Re: How to generate textures from frame buffer?

New Message Reply Date view Thread view Subject view Author view

Anita Kishore (kishore++at++triavest.com)
Fri, 20 Jun 1997 09:52:53 -0700


On Jun 19, 6:18pm, Amaury Aubel wrote:
> Subject: How to generate textures from frame buffer?
> Hi Performers,
>
>
> I have a pfBillboard made up of a few planes. I map onto those planes
> transparent textures, which I update from time to time.
> What I'd like to do is generate the textures from the frame buffer.
> Unfortunately there's no example source code on the subject to hand.
>

Here is a sample code that I wrote sometime back. This makes a texture out of
the frame buffer and maps it onto a square geometry. This is for RE2, pf 2.0.1,
Irix 5.3, IrisGL.

-anita

kishore++at++triavest.com

--------------------------------------------------------------------------------
/* File name : fbTex.c */
--------------------------------------------------------------------------------

#include <stdio.h>
#include <stdlib.h>

#include <Performer/pf.h>
#include <Performer/pr.h>
#include <Performer/pfutil.h>
#include <gl.h>

#define WIN_X 720
#define WIN_Y 486

void *arena;
pfTexture **tex;
pfPipe *p;
pfGeoState *gst;

static float idmat[4][4] = {
    1.0, 0.0, 0.0, 0.0,
    0.0, 1.0, 0.0, 0.0,
    0.0, 0.0, 1.0, 0.0,
    0.0, 0.0, 0.0, 1.0
};

pfGroup *MkScene();
pfGeoSet *MakeTexCube(void);
void channelDraw(pfChannel *chan, void *data);
void setTexParameters();
static int loadTextureMatrixCB(pfGeoState *gs, void *userData);
static int loadIDMatrixCB(pfGeoState *gs, void *userData);

int main(int argc, char *argv[])
{

        pfChannel *chan;
        pfScene *scene;
        pfGroup *root, *pass1;
        pfCoord view;
        pfDCS *dcs;
        pfPipeWindow *pw;
        int arg, texFrame = 0;
        int i=0;
        float j = 0.0, step = 1.0;

        pfInit();
        arena = pfGetSharedArena();
        tex = (pfTexture **) pfMalloc(sizeof(pfTexture *), arena);

        //pfMultiprocess ( PFMP_FORK_DRAW | PFMP_FORK_CULL );
        pfMultiprocess ( PFMP_DEFAULT );
        pfConfig();
        pfuInitUtil();

        *tex = pfNewTex(arena);
        /* set some basic formats for doing dynamic textures */
        pfTexFormat(*tex, PFTEX_SUBLOAD_FORMAT, 1);
        pfTexFilter(*tex, PFTEX_MINFILTER, PFTEX_BILINEAR);
        // load a default texture
        //pfLoadTexFile(*tex, "/disk5/people/ian/candle/zoom/candle0000.rgb");

        scene = pfNewScene();
        dcs = pfNewDCS();
        if ((root = MkScene()) == NULL)
        {
              printf("Unable to create scene data base....\n");
              pfExit();
              exit(-1);
        }
        pfAddChild(scene, dcs);
        pfAddChild(dcs, root);

        setTexParameters();

        p = pfGetPipe(0);

        pw = pfNewPWin(p);
        pfPWinType(pw, PFWIN_TYPE_X);
        pfPWinName(pw, "Movie");
        pfPWinOriginSize(pw, 100, 100, WIN_X, WIN_Y);
        pfOpenPWin(pw);

        chan = pfNewChan(p);
        pfChanScene(chan, scene);
        pfChanNearFar(chan, 1.0f, 10000.0f);
        pfChanFOV(chan, 10.0f, -1.0f);

        pfSetVec3(view.hpr, 0, 0, 0);
        pfSetVec3(view.xyz, 0, -50, 0);
        pfChanView(chan, view.xyz, view.hpr);

        pfChanTravFunc(chan, PFTRAV_DRAW, channelDraw );

        while (1)
        {
                pfSync();
                pfFrame();

                /* translate the geo back and forth */
                if (j >= 5.0)
                    step = -0.04;
                if (j <= 0.0)
                    step = 0.04;
                pfDCSTrans(dcs, j, 0, 0);
                j = j + step;

                pfDrawChanStats(chan);

        }
        pfuExitUtil();
        pfExit();
        exit(0);
}

void channelDraw(pfChannel *chan, void *data)
{
        pfLoadTex(*tex);

        pfClearChan(chan);
        pfDraw();

}

void setTexParameters()
{
    pfMatrix *tmat;
    float s_scale, t_scale;
    float texWidth = 1024.0f, texHeight = 1024.0f;

    tmat = (pfMatrix*) pfCalloc(sizeof(pfMatrix),
                                 1, pfGetSharedArena());
    pfMakeIdentMat(*tmat);
    s_scale = (float)WIN_X/texWidth;
    t_scale = (float)WIN_Y/texHeight;
    (*tmat)[0][0] = s_scale;
    (*tmat)[1][1] = -t_scale; /* invert in y because of video origin */
    (*tmat)[3][1] = t_scale; /* this is really a translate */

    pfGStateFuncs(gst, loadTextureMatrixCB, loadIDMatrixCB, tmat);
    pfTexImage(*tex, NULL, 3, texWidth, texHeight, 1);
    pfTexFormat(*tex, PFTEX_INTERNAL_FORMAT, PFTEX_RGB_5);
    pfTexLoadMode(*tex, PFTEX_LOAD_SOURCE, PFTEX_SOURCE_FRAMEBUFFER);
    pfTexLoadSize(*tex, WIN_X, WIN_Y);

}

static int
loadTextureMatrixCB(pfGeoState *gs, void *userData)
{
    pfMatrix *tmat = (pfMatrix *)(userData);
    mmode(MTEXTURE);
    pfLoadMatrix(*tmat);
    mmode(MVIEWING);
    return 0;
}

static int
loadIDMatrixCB(pfGeoState *gs, void *userData)
{
    mmode(MTEXTURE);
    pfLoadMatrix(idmat);
    mmode(MVIEWING);
    return 0;
}

pfGroup *MkScene()
{

        pfGroup *group;
        pfGeode *cube;
        pfGeoSet *coloredCube;

        group = pfNewGroup();
        cube = pfNewGeode();
        coloredCube = MakeTexCube();
        pfAddGSet(cube, coloredCube);

        pfAddChild(group,cube);
        return group;

}

#define CUBE_SIZE 1.0f

pfGeoSet *MakeTexCube(void)
{

    pfGeoSet *gset;
    pfTexEnv *tenv;

    static pfVec3 verts[] ={{-2.0f, 0, -1.0f},
                                    { 0.0f, 0, -1.0f},
                                    { 0.0f, 0, 1.0f},
                                    {-2.0f, 0, 1.0f}};

    static ushort vindex[] ={0, 1, 2, 3}; /* front */

    static pfVec3 norms[] ={{ 0.0f, -1.0f, 0.0f}};

    static ushort nindex[] ={0};

    static pfVec2 tcoords[] ={{0.0f, 0.0f},
                                      {1.0f, 0.0f},
                                      {1.0f, 1.0f},
                                      {0.0f, 1.0f}};

    static ushort tindex[] ={0, 1, 2, 3};

    gset = pfNewGSet(arena);

    pfGSetAttr(gset, PFGS_COORD3, PFGS_PER_VERTEX, verts, vindex);
    pfGSetAttr(gset, PFGS_NORMAL3, PFGS_PER_PRIM, norms, nindex);
    pfGSetAttr(gset, PFGS_TEXCOORD2, PFGS_PER_VERTEX, tcoords, tindex);
    pfGSetPrimType(gset, PFGS_QUADS);
    pfGSetNumPrims(gset, 1);

    gst = pfNewGState(arena);
    pfGStateMode(gst, PFSTATE_ENTEXTURE, 1);
    pfGSetGState(gset, gst);

    //*tex = pfNewTex(arena);
    //pfLoadTexFile(*tex,
"/disk4/people/kishore/performer/data/smallGlobeDesat.rgb");

    pfGStateAttr(gst, PFSTATE_TEXTURE, *tex);
    tenv = pfNewTEnv(arena);
    pfTEnvMode(tenv, PFTE_DECAL);
    pfGStateAttr(gst, PFSTATE_TEXENV, tenv);

    return gset;

}

--------------------------------------------------------------------------------
                        makefile
--------------------------------------------------------------------------------

#--
#-- definitions
#--

#-- force Make to use a known shell
SHELL = /bin/sh

#-- provide a list of alternate locations for file searches
UNIQUE = .

#-- alternate locatins for included files
INCLUDE = \
        -I${UNIQUE} \
        -I/usr/include/Performer

#-- some libraries lack .so versions; so use optimized .a's instead

#SRCLIBOPT= _ogl
SRCLIBOPT= _igl

LIBGL1 = -lgl
#LIBGL1 = -lGL

PERFORMER = \
        -L/usr/src/Performer/lib \
        -lpfdu${SRCLIBOPT} \
        -lpfutil${SRCLIBOPT} \
        -lpf${SRCLIBOPT}

#-- IRIX 4.x uses shared gl {gl_s} library {System-V Make lacks #if tests}
LIBGL2 = ${LIBGL1:.4=_s}
LIBGL = ${LIBGL2:.5=}

# .ptu (Performer Terrain Utility)
# This loader requires linking with the ImageVision Libraries(IL)!
# Shoud you want to use the Performer Terrain Utility loader (.ptu)
# then install the image library and un-comment the following two
# definitions of LIBIL and LIBCIL.
#LIBIL = -lil
#LIBCIL = -lcil

SYSTEM = \
        -lInventor \
        -lmpc \
        -limage \
        -lfm \
        ${LIBGL} \
        -lX11 \
        -lm \
        -lfpe \
        ${LIBIL} \
        ${LIBCIL} \
        -lC

LIBRARIES = \
        ${PERFORMER} ${SYSTEM}

#-- select c-compiler options
CFLAGS = -xansi -g -D__STDC__ ${INCLUDE} ${COPT} -Xcpluscomm \
                 -DPF_C_API=1 -DPF_CPLUSPLUS_API=0 \
                 -DIRISGL \
                 -DPF_MAJOR_VERSION=2

#-DIRISGL

#-- base name of program
TARGET = fbTex

#-- dummy assignment in case pmake is used
EXT=
LIBOPT=
MAJOR=

#-- object files from which target built {some are in the common directory}
OBJECTS = \
        fbTex.o

${TARGET}: ${OBJECTS}
        ${CC} ${CFLAGS} -o $++at++ ${OBJECTS} ${LIBRARIES}

#-- objects are built from either unique or common files
fbTex.o: ${UNIQUE}/fbTex.c
        ${CC} ${CFLAGS} -c $?
--------------------------------------------------------------------------------

-- 
Anita Kishore
=======================================================================
List Archives, FAQ, FTP:  http://www.sgi.com/Technology/Performer/
            Submissions:  info-performer++at++sgi.com
        Admin. requests:  info-performer-request++at++sgi.com

New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:55:29 PDT

This message has been cleansed for anti-spam protection. Replace '++at++' in any mail addresses with the '@' symbol.