Dick Rous (dick++at++puth.demeern.sgi.com)
Thu, 1 Aug 1996 11:37:11 -0600
Attached find the prog and the makefile for r/t (Sirius)video.
I modified an early 2.0 example from Vince Uttley and recently "ported" it to
2.1 / OpenGL.
Let me know if this helps (also when it doesn't...)
Regards,
-- ------------------------------------------------------------ Dick Rous email....: dick++at++demeern.sgi.com Systems Engineer voicemail: 5-8160 Graphics Technology phone....: (31) 30-6696868Silicon Graphics BV phone....: (31) 30-6696777 Veldzigt 2 fax......: (31) 30-6696799 3454 PW De Meern The Netherlands ------------------------------------------------------------
#!smake -J 1 #-------------------------------------------------------------------# #-- Makefile for Performer/src/pguide/libpr directory --# #-------------------------------------------------------------------# #-- RCS version information --# #-- $Revision: 1.55 $ --# #-- $Date: 1996/04/09 05:32:15 $ --# #-------------------------------------------------------------------#
#-------------------------------------------------------------------# #-- The default make target makes the IRISGL Dynamic Shared Object.-# #-- The targets are: --# #-- build debugging versions: igldbg (or ogldbg) --# #-- build optimized versions: iglopt (or oglopt) --# #-- build dynamic shared object versions: igldso ogldso --# #-- build debugging dynamic shared object versions: --# #-- iglddso oglddso --# #-- remove all unneeded files after a build: clean --# #-- remove all machine generated files: clobber --# #-- --# #-- --# #-------------------------------------------------------------------#
#-- #-- definitions #--
#if !defined(PFSTYLE) PFSTYLE = 32 #endif #if $(PFSTYLE) == "64" OBJECT_STYLE = 64 LIBBITSUF=64 PFRELEASE=N64 #endif #if $(PFSTYLE) == "N32" OBJECT_STYLE = N32_M3 LIBBITSUF=32 PFRELEASE=N32 #endif #if $(PFSTYLE) == "32" OBJECT_STYLE = 32 LIBBITSUF= PFRELEASE=O32 #endif
include $(ROOT)/usr/include/make/commondefs
PFROOT ?= $(ROOT)
DSOLINKS = \ -L$(PFROOT)/usr/lib$(LIBBITSUF) \ -L$(PFROOT)/usr/lib$(LIBBITSUF)/libpfdb \ -L$(PFROOT)/lib$(LIBBITSUF)
DDSOLINKS = \ -L$(PFROOT)/usr/lib$(LIBBITSUF)/Performer/Debug \ -L$(PFROOT)/usr/lib$(LIBBITSUF)/Performer/Debug/libpfdb \ -L$(PFROOT)/lib$(LIBBITSUF)
DBGLINKS = \ -L$(PFROOT)/usr/lib$(LIBBITSUF)/Performer/DebugStatic \ -L$(PFROOT)/usr/lib$(LIBBITSUF)/Performer/DebugStatic/libpfdb \ -L$(PFROOT)/lib$(LIBBITSUF)
OPTLINKS = \ -L$(PFROOT)/usr/lib$(LIBBITSUF)/Performer/Static \ -L$(PFROOT)/usr/lib$(LIBBITSUF)/Performer/Static/libpfdb \ -L$(PFROOT)/lib$(LIBBITSUF)
IGLLIB = -ignore_unresolved -lpf_igl -lpfdu_igl -lpfui -lpfutil_igl OGLLIB = -ignore_unresolved -lpf_ogl -lpfdu_ogl -lpfui -lpfutil_ogl
LIBIGL = -ignore_unresolved -lgl -lvl LIBOGL = -ignore_unresolved -lGLU -lGL -lXext -lvl
#if $(RELEASE) < 6.2 IRIXREL=-DIRIX5 #else IRIXREL=-DIRIX6 LIBIGL += -lXsgivc LIBOGL += -lXsgivc #endif
SYSTEM_IRISGL = \ -lmpc \ -limage \ -lfm \ ${LIBIGL} \ -lXirisw \ -lXm \ -lXt \ -lfpe \ -lXmu \ -lX11 \ -lm \ -lmalloc \ -lC
SYSTEM_OPENGL = \ -lmpc \ -limage \ -lGLw \ ${LIBOGL} \ -lfpe \ -lXm \ -lXt \ -lXmu \ -lX11 \ -lm \ -lmalloc \ -lC
#if $(PFSTYLE) == "64" SYSTEM_OPENGL = \ -limage \ ${LIBOGL} \ -lXmu \ -lX11 \ -lm \ -lC #endif
#if $(PFSTYLE) == "N32" SYSTEM_IRISGL = \ -limage \ ${LIBIGL} \ -lXmu \ -lX11 \ -lm \ -lfm \ -lC
SYSTEM_OPENGL = \ -limage \ ${LIBOGL} \ -lXmu \ -lX11 \ -lm \ -lC #endif
#-- targets are the executables TARGETS = \ videoAndStaticTex movietex2.1
OBJECTS = \ $(TARGETS:=.o)
#-- #-- #-- generic targets #--
#-- make optimized dso version of program by default default: ogldso
#-- synonym targets debug: ogldbg
optimize: oglopt
#-- make all versions of program all: ogldbg oglopt ogldso oglddso
#if $(PFSTYLE) == "64" #-- make optimized dso version of program by default default: ogldso
#-- synonym targets debug: ogldbg
optimize: oglopt
#-- make all versions of program all: ogldbg oglopt ogldso oglddso #endif
igldso: $(TARGETS:=.igldso) iglopt: $(TARGETS:=.iglopt) igldbg: $(TARGETS:=.igldbg) iglddso: $(TARGETS:=.iglddso)
ogldso: $(TARGETS:=.ogldso) oglopt: $(TARGETS:=.oglopt) ogldbg: $(TARGETS:=.ogldbg) oglddso: $(TARGETS:=.oglddso)
#-- clean up directories {remove junk} clean: if test -d DBG.$(PFRELEASE).IRISGL; then cd DBG.$(PFRELEASE).IRISGL ; rm -f ${OBJECTS} core ; cd .. ; fi if test -d DBG.$(PFRELEASE).OPENGL; then cd DBG.$(PFRELEASE).OPENGL ; rm -f ${OBJECTS} core ; cd .. ; fi if test -d OPT.$(PFRELEASE).IRISGL; then cd OPT.$(PFRELEASE).IRISGL ; rm -f ${OBJECTS} core ; cd .. ; fi if test -d OPT.$(PFRELEASE).OPENGL; then cd OPT.$(PFRELEASE).OPENGL ; rm -f ${OBJECTS} core ; cd .. ; fi
#-- remove all machine-built files clobber: clean if test -d OPT.$(PFRELEASE).IRISGL ; then rm -rf OPT.$(PFRELEASE).IRISGL ; fi if test -d OPT.$(PFRELEASE).OPENGL ; then rm -rf OPT.$(PFRELEASE).OPENGL ; fi if test -d DBG.$(PFRELEASE).IRISGL ; then rm -rf DBG.$(PFRELEASE).IRISGL ; fi if test -d DBG.$(PFRELEASE).OPENGL ; then rm -rf DBG.$(PFRELEASE).OPENGL ; fi rm -f ${TARGETS}
#-- #-- library targets #--
$(TARGETS): $(++at++:=.igldso)
$(TARGETS:=.igldbg): .MAKE ++at++echo "\nmaking IrisGL DBG version of $++at++" ++at++if test ! -d DBG.$(PFRELEASE).IRISGL ; then mkdir -p DBG.$(PFRELEASE).IRISGL ; fi ++at++ rm -f $(++at++:S/.igldbg//) ++at++cd DBG.$(PFRELEASE).IRISGL ; \ ${MAKE} -f ../Makefile OPTIMIZER=-g LCDEFS=-DIRISGL LCXXDEFS=-DIRISGL \ LIBRARIES='$(IGLLIB) ${SYSTEM_IRISGL}' \ $(++at++:S/igl//)cmd ; ++at++echo "making symbolic links to DBG versions" ln -s DBG.$(PFRELEASE).IRISGL/$(++at++:S/igl//)cmd $(++at++:S/.igldbg//) ;
$(TARGETS:=.iglopt): .MAKE ++at++echo "\nmaking IrisGL OPT version of $++at++" ++at++if test ! -d OPT.$(PFRELEASE).IRISGL ; then mkdir -p OPT.$(PFRELEASE).IRISGL ; fi ++at++ rm -f $(++at++:S/.iglopt//) ++at++cd OPT.$(PFRELEASE).IRISGL ; \ ${MAKE} -f ../Makefile OPTIMIZER="-O -Olimit 2000" LCDEFS=-DIRISGL LCXXDEFS=-DIRISGL \ LIBRARIES='$(IGLLIB) ${SYSTEM_IRISGL}' \ $(++at++:S/igl//)cmd ; cd .. ++at++echo "making symbolic links to OPT versions" ln -s OPT.$(PFRELEASE).IRISGL/$(++at++:S/igl//)cmd $(++at++:S/.iglopt//) ;
$(TARGETS:=.igldso): .MAKE ++at++echo "\nmaking IrisGL DSO version of $++at++" ++at++if test ! -d OPT.$(PFRELEASE).IRISGL ; then mkdir -p OPT.$(PFRELEASE).IRISGL ; fi ++at++ rm -f $(++at++:S/.igldso//) ++at++cd OPT.$(PFRELEASE).IRISGL ; \ ${MAKE} -f ../Makefile OPTIMIZER="-O -Olimit 2000" LCDEFS=-DIRISGL LCXXDEFS=-DIRISGL \ LIBRARIES='$(IGLLIB) ${SYSTEM_IRISGL}' \ $(++at++:S/igl//)cmd ; cd .. ++at++echo "making symbolic links to DSO versions" ln -s OPT.$(PFRELEASE).IRISGL/$(++at++:S/igl//)cmd $(++at++:S/.igldso//) ;
$(TARGETS:=.iglddso): .MAKE ++at++echo "\nmaking IrisGL DDSO version of $++at++" ++at++if test ! -d DBG.$(PFRELEASE).IRISGL ; then mkdir -p DBG.$(PFRELEASE).IRISGL ; fi ++at++ rm -f $(++at++:S/.iglddso//) ++at++cd DBG.$(PFRELEASE).IRISGL ; \ ${MAKE} -f ../Makefile OPTIMIZER=-g LCDEFS=-DIRISGL LCXXDEFS=-DIRISGL \ LIBRARIES='$(IGLLIB) ${SYSTEM_IRISGL}' \ $(++at++:S/igl//)cmd ; cd .. ++at++echo "making symbolic links to DDSO versions" ln -s DBG.$(PFRELEASE).IRISGL/$(++at++:S/igl//)cmd $(++at++:S/.iglddso//) ;
$(TARGETS:=.ogldbg): .MAKE ++at++echo "\nmaking OpenGL DBG version of $++at++" ++at++if test ! -d DBG.$(PFRELEASE).OPENGL ; then mkdir -p DBG.$(PFRELEASE).OPENGL ; fi ++at++ rm -f $(++at++:S/.ogldbg//) ++at++cd DBG.$(PFRELEASE).OPENGL ; \ ${MAKE} -f ../Makefile OPTIMIZER="-g " \ LIBRARIES='$(OGLLIB) ${SYSTEM_OPENGL}' \ $(++at++:S/ogl//)cmd ; cd .. ++at++echo "making symbolic links to DBG versions" ln -s DBG.$(PFRELEASE).OPENGL/$(++at++:S/ogl//)cmd $(++at++:S/.ogldbg//) ;
$(TARGETS:=.oglopt): .MAKE ++at++echo "\nmaking OpenGL OPT version of $++at++" ++at++if test ! -d OPT.$(PFRELEASE).OPENGL ; then mkdir -p OPT.$(PFRELEASE).OPENGL ; fi ++at++ rm -f $(++at++:S/.oglopt//) ++at++cd OPT.$(PFRELEASE).OPENGL ; \ ${MAKE} -f ../Makefile OPTIMIZER="-O -Olimit 2000" \ LIBRARIES='$(OGLLIB) ${SYSTEM_OPENGL}' \ $(++at++:S/ogl//)cmd ; cd .. ++at++echo "making symbolic links to OPT versions" ln -s OPT.$(PFRELEASE).OPENGL/$(++at++:S/ogl//)cmd $(++at++:S/.oglopt//) ;
$(TARGETS:=.ogldso): .MAKE ++at++echo "\nmaking OpenGL DSO version of $++at++" ++at++if test ! -d OPT.$(PFRELEASE).OPENGL ; then mkdir -p OPT.$(PFRELEASE).OPENGL ; fi ++at++ rm -f $(++at++:S/.ogldso//) ++at++cd OPT.$(PFRELEASE).OPENGL ; \ ${MAKE} -f ../Makefile OPTIMIZER="-O -Olimit 2000" \ LIBRARIES='$(OGLLIB) ${SYSTEM_OPENGL}' \ $(++at++:S/ogl//)cmd ; cd .. ++at++echo "making symbolic links to DSO versions" ln -s OPT.$(PFRELEASE).OPENGL/$(++at++:S/ogl//)cmd $(++at++:S/.ogldso//);
$(TARGETS:=.oglddso): .MAKE ++at++echo "\nmaking OpenGL DDSO version of $++at++" ++at++if test ! -d DBG.$(PFRELEASE).OPENGL ; then mkdir -p DBG.$(PFRELEASE).OPENGL ; fi ++at++ rm -f $(++at++:S/.oglddso//) ++at++cd DBG.$(PFRELEASE).OPENGL ; \ ${MAKE} -f ../Makefile OPTIMIZER="-g " \ LIBRARIES='$(OGLLIB) ${SYSTEM_OPENGL}' \ $(++at++:S/ogl//)cmd ; cd .. ++at++echo "making symbolic links to DDSO versions" ln -s DBG.$(PFRELEASE).OPENGL/$(++at++:S/ogl//)cmd $(++at++:S/.oglddso//);
dso: ogldso ddso: oglddso dbg: ogldbg opt: oglopt
#-- #-- internal targets #--
.SUFFIXES: .dbgcmd .optcmd .dsocmd .ddsocmd
.o.dbgcmd: ${CC} ${CFLAGS} -o $++at++ $< $(DBGLINKS) -all ${LIBRARIES}
.o.optcmd: ${CC} ${CFLAGS} -o $++at++ $< $(OPTLINKS) -all ${LIBRARIES}
.o.dsocmd: ${CC} ${CFLAGS} -o $++at++ $< $(DSOLINKS) -all ${LIBRARIES}
.o.ddsocmd: ${CC} ${CFLAGS} -o $++at++ $< $(DDSOLINKS) -all ${LIBRARIES}
#-- #-- internal targets #--
#-- look for sources in this dir when recursing .PATH: ..
# #-- special rules for using pixie with profile #
# create a pixie version of profile profile.pixie: $(TOOLROOT)/usr/bin/pixie profile
#-- runs prof -pixie on the using the data file produced by #-- running profile.pixie profit: prof -procedures -i -l -pixie -quit 1% \ profile profile.Addrs profile.Counts
#-- a speciall c++ version that will de-mangle c++ names #-- requires /usr/lib/c++/c++filt profit_c++: prof -procedures -i -l -pixie -quit 1% \ profile profile.Addrs profile.Counts | $(TOOLROOT)/usr/lib/c++/c++filt
/*** general includes ***/ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <math.h> #include <getopt.h> #include <signal.h> /* for sigset for forked X event handler process */ #include <fcntl.h> #include <sys/syssgi.h> #include <sys/stat.h>
/*** X Window includes ***/ #include <X11/X.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/keysym.h>
/*** VL includes ***/ #include <GL/gl.h> #include <vl/vl.h> #include <vl/dev_sirius.h>
/*** Performer includes ***/ #include <Performer/pf.h>
#define SIRIUS_SCANLINE_SIZE 768 /* must be 32 bit word */
/* position of panels */ #define OBJECT_FAR (6.0f) #define OBJECT_NEAR (0.0f) #define OBJECT_INC (0.025f)
/* * structure that resides in shared memory so that the forked * application, cull, draw, and X processes can access it. */ typedef struct { /* Video */ int vlTexWidth, vlTexHeight, subTexLoadYsize; int vlInSrc, vlDevice; VLControlValue vlSize, vlTiming, vlTexPack; VLControlValue vlFormat; VLControlValue vlCaptureType; VLServer vlServer; VLPath vlPath; VLNode vlSrc, vlDrn; int TexFormat; int TexComp;
/* Window */ pfPipeWindow *pw; pfWindow *w; GLXVideoSourceSGIX videosource; int EndXfer; int exitFlag; int inWindow, reset; int winSizeX, winSizeY; int mouseButtons;
/* basic run-time controls */ int drawStats;
/* background pixel copies */ int bytesPerPixel; int origin; float zoomXfactor, zoomYfactor;
/* for memory textures only */ int texFrame; int listLength; int runMovie; int spin; pfMatrix textureMatrix;
/* data for scene */ int panelBackward; int panelForward; pfCoord view, viewOrig; float viewPosition; pfVec2 StaticTextureCoords[4]; pfVec2 VideoTextureCoords[4]; pfVec3 VertexCoords[4]; pfVec4 Colour[1]; pfGeoState *movieState; pfGeoState *videoState; pfTexture *movieTex; /* this is the static texture */ pfTexture *videoTex; /* this is the texture that gets sirius input */ pfScene *scene; pfDCS *sceneDCS; float initAngle; float Angle; } SharedData;
static SharedData *Shared;
/* for static texture image */ /* static char StaticTexName[] = "wood.rgb"; */ static char StaticTexName[] = "re_coke.rgb";
/* general startup controls */ static int LockMode = False; /*** default locking degrades performance! ***/ static int DrawStats = False; static float InitAngle = 0.0f;
/*** DRAW process global variables ***/ static int RealityEngine = False; static int InfiniteReality = False; static int Interlacing = False; static int DoFields = True;
/*** Function Prototypes ***/ static void initShared (void); static int videoInit (void); static void videoExit (void); static void setVideoTextureParameters (pfGeoState *gstate); static int loadVideoTextureMatrixCB (pfGeoState *gs, void *userData); static int loadStaticTextureMatrixCB (pfGeoState *gs, void *userData);
/* Performer utility functions */ static void makeScene (void); static void cullChannel (pfChannel *chan, void *data); static void drawChannel (pfChannel *chan, void *data); static void openPipeWin (pfPipeWindow *pw); static void doXInput (void); static void getXInput (Display *dsp);
int main (int argc, char **argv) { pfChannel *chan; pfScene *scene; pfPipe *p; float ypos; Display *Dsp; Window xwin; void *arena = NULL;
#ifdef PAL /*** Set vof to 50Hz genlocked PAL field mode ***/ system ("/usr/gfx/setmon -n 1280x1024_50f"); #endif
/*** Initialise Performer ***/ pfInit (); /*** Enable printing of debug messages ***/ pfNotifyLevel (PFNFY_DEBUG);
/* Append to PFPATH standard data dirs */ pfFilePath (".:/usr/share/Performer/data:/usr/demos/data/textures"); /*** Allocate shared memory before fork()'ing parallel processes ***/ arena = pfGetSharedArena (); /*** Initialise shared variables ***/ initShared ();
/*** Request seperate CULL and DRAW processes and fork them off ***/ pfMultiprocess (PFMP_APP_CULLoDRAW); pfConfig ();
/*** Request a framerate locked to 50 Hz ***/ pfFrameRate (50.0f); pfPhase (PFPHASE_LOCK);
if (LockMode) { pfuPrioritizeProcs (True); pfuLockDownProc (3); }
/*** Create Video Texture ***/ Shared->videoTex = pfNewTex (arena);
/* set some basic formats for doing dynamic textures */ pfTexFormat (Shared->videoTex, PFTEX_SUBLOAD_FORMAT, PF_ON); pfTexFilter (Shared->videoTex, PFTEX_MINFILTER, PFTEX_BILINEAR);
/*** Create Static Texture ***/ Shared->movieTex = pfNewTex (arena);
pfNotify (PFNFY_INFO, PFNFY_PRINT, "Loading texture %s as static texture\n", StaticTexName); if (!pfLoadTexFile (Shared->movieTex, StaticTexName)) pfNotify (PFNFY_INFO, PFNFY_PRINT, "%s not loaded...\n", StaticTexName);
/*** Create Scene ***/ makeScene ();
/*** Configure Window ***/ p = pfGetPipe (0); Shared->pw = pfNewPWin (p); pfPWinOriginSize (Shared->pw, 0, 0, 768, 576); pfPWinName (Shared->pw, "NOB Interactive"); pfPWinType (Shared->pw, PFWIN_TYPE_X); pfPWinConfigFunc (Shared->pw, openPipeWin); pfConfigPWin (Shared->pw);
chan = pfNewChan (p); pfAddChan (Shared->pw, chan); pfChanScene (chan, Shared->scene); pfChanTravFunc (chan, PFTRAV_CULL, cullChannel); pfChanTravFunc (chan, PFTRAV_DRAW, drawChannel);
/* initialize the window size parameters before the Draw process is called * the first time. */ pfGetPWinSize(pfGetChanPWin(chan), &Shared->winSizeX, &Shared->winSizeY); pfNotify (PFNFY_INFO, PFNFY_PRINT, "Window size: %d x %d\n", Shared->winSizeX, Shared->winSizeY);
PFSET_VEC3 (Shared->view.xyz, 0.0f, Shared->viewPosition, 0.0f); PFSET_VEC3 (Shared->view.hpr, 0.0f, 0.0f, 0.0f); pfChanView (chan, Shared->view.xyz, Shared->view.hpr); /* vertical FOV is matched to window aspect ratio */ pfChanFOV (chan, 45.0f, -1.0f); pfChanNearFar (chan, 1.0f, 100.0f);
/* create forked XInput handling process * since the Shared pointer has already been initialized, that structure * will be visible to the XInput process. Nothing else created in the * application after this fork whose handles are not put in shared memory * (such as the database and channels) will be visible to the * XInput process. */ { pid_t fpid = 0;
if ((fpid = fork ()) < 0) pfNotify (PFNFY_FATAL, PFNFY_SYSERR, "Fork of XInput process failed."); else if (fpid) /*** True if in parent process ***/ pfNotify (PFNFY_NOTICE, PFNFY_PRINT, "XInput running in forked process %d", fpid); else if (fpid == 0) /*** True if in child process ***/ doXInput (); }
/* setup transformation parameters */ if (Shared->panelForward) ypos = OBJECT_NEAR; else if (Shared->panelBackward) ypos = OBJECT_FAR;
pfDCSRot (Shared->sceneDCS, Shared->initAngle, 0.0f, 0.0f);
/* Main Loop */ pfNotify (PFNFY_NOTICE, PFNFY_PRINT, "Entering Main Loop..."); while (!Shared->exitFlag) { static int a = 0; pfSync(); if (Shared->panelForward && (ypos > OBJECT_NEAR)) ypos -= OBJECT_INC; else if (Shared->panelBackward && (ypos < OBJECT_FAR)) ypos += OBJECT_INC;
if (Shared->spin) a = (a += 5) % 3600;
pfDCSRot (Shared->sceneDCS, Shared->Angle + (float)a / 10.0f, 0.0f, 0.0f); pfDCSTrans (Shared->sceneDCS, 0.0f, ypos, 0.0f); pfChanView (chan, Shared->view.xyz, Shared->view.hpr);
pfFrame (); } if (LockMode) pfuFreeCPUs ();
/*** Set vof back to 60Hz ***/ system ("/usr/gfx/setmon -n 1280x1024_60"); return 0; }
static void initShared (void) { void *arena = NULL;
arena = pfGetSharedArena ();
/*** Use pfCalloc() so it is all zero-ed. ***/ Shared = (SharedData *)pfCalloc (1, sizeof (SharedData), arena);
/*** Initialise shared variables ***/ Shared->vlInSrc = VL_ANY; Shared->vlDevice = VL_ANY; Shared->TexFormat = PFTEX_RGB_5; /* PFTEX_RGBA_4, PFTEX_RGBA_8 */ Shared->TexComp = 3; /* 4, 4 */ Shared->drawStats = DrawStats; Shared->runMovie = 1; Shared->spin = 0; Shared->texFrame = -1; /* points to base texture */ Shared->viewPosition = -2.36f; Shared->panelForward = 1; Shared->panelBackward = 0; Shared->initAngle = InitAngle;
PFSET_VEC2 (Shared->VideoTextureCoords[0], 0.0f, 0.0f); PFSET_VEC2 (Shared->VideoTextureCoords[1], 1.0f, 0.0f); PFSET_VEC2 (Shared->VideoTextureCoords[2], 1.0f, 1.0f); PFSET_VEC2 (Shared->VideoTextureCoords[3], 0.0f, 1.0f);
PFSET_VEC2 (Shared->StaticTextureCoords[0], 0.50f, 0.00f); PFSET_VEC2 (Shared->StaticTextureCoords[1], 0.80f, 0.90f); PFSET_VEC2 (Shared->StaticTextureCoords[2], 0.45f, 1.00f); PFSET_VEC2 (Shared->StaticTextureCoords[3], 0.15f, 0.10f);
PFSET_VEC3 (Shared->VertexCoords[0], -1.25f, 0.0f, -1.0f); PFSET_VEC3 (Shared->VertexCoords[1], 1.25f, 0.0f, -1.0f); PFSET_VEC3 (Shared->VertexCoords[2], 1.25f, 0.0f, 1.0f); PFSET_VEC3 (Shared->VertexCoords[3], -1.25f, 0.0f, 1.0f);
PFSET_VEC4 (Shared->Colour[0], 1.0f, 1.0f, 1.0f, 1.0f); }
/* Creation of scene geometry - done in application process. * Data is put in shared memory to be read by the draw process. */ static void makeScene (void) { int i; pfGeode *geode; pfGeoSet *geom; pfMatrix LeftMat, RightMat;
void *arena = pfGetSharedArena ();
pfVec3 *LeftScreen = (pfVec3 *)pfMalloc (sizeof (pfVec3) * 4, arena); pfVec3 *RightScreen = (pfVec3 *)pfMalloc (sizeof (pfVec3) * 4, arena); /*** Create the root of the scene-graph ***/ Shared->scene = pfNewScene (); Shared->sceneDCS = pfNewDCS (); pfAddChild (Shared->scene, Shared->sceneDCS); /*** Create the two distinct geo-states ***/ Shared->videoState = pfNewGState (arena); Shared->movieState = pfNewGState (arena);
pfGStateMode (Shared->videoState, PFSTATE_CULLFACE, PFCF_OFF); pfGStateAttr (Shared->videoState, PFSTATE_TEXENV, pfNewTEnv (arena)); pfGStateAttr (Shared->videoState, PFSTATE_TEXTURE, Shared->videoTex); pfGStateMode (Shared->movieState, PFSTATE_CULLFACE, PFCF_OFF); pfGStateAttr (Shared->movieState, PFSTATE_TEXENV, pfNewTEnv (arena)); pfGStateAttr (Shared->movieState, PFSTATE_TEXTURE, Shared->movieTex);
pfMakeTransMat (LeftMat, -1.25f, 0.0f, 0.0f); pfMakeTransMat (RightMat, 1.25f, 0.0f, 0.0f); pfPostRotMat (LeftMat, LeftMat, 45.0f, 0.0f, 0.0f, 1.0f); pfPostRotMat (RightMat, RightMat, -45.0f, 0.0f, 0.0f, 1.0f); pfPostTransMat (LeftMat, LeftMat, -1.25f, 0.0f, 0.0f); pfPostTransMat (RightMat, RightMat, 1.25f, 0.0f, 0.0f);
for (i = 0; i < 4; i++) { pfXformPt3 (LeftScreen[i], Shared->VertexCoords[i], LeftMat); pfXformPt3 (RightScreen[i], Shared->VertexCoords[i], RightMat); } /*** Do the right thing for each panel ***/ /*** When the centre node is created first, the video-texture is ok ***/ /* create the center panel geostate */ geom = pfNewGSet (arena); pfGSetGState (geom, Shared->videoState); pfGSetAttr (geom, PFGS_COLOR4, PFGS_OVERALL, Shared->Colour, NULL); pfGSetAttr (geom, PFGS_TEXCOORD2, PFGS_PER_VERTEX, Shared->VideoTextureCoords, NULL); pfGSetAttr (geom, PFGS_COORD3, PFGS_PER_VERTEX, Shared->VertexCoords, NULL); pfGSetPrimType (geom, PFGS_QUADS); pfGSetNumPrims (geom, 1); /* create the center panel geometry node */ geode = pfNewGeode (); pfAddGSet (geode, geom); pfAddChild (Shared->sceneDCS, geode); /* create the left panel geostate */ geom = pfNewGSet (arena); pfGSetGState (geom, Shared->movieState); pfGSetAttr (geom, PFGS_COLOR4, PFGS_OVERALL, Shared->Colour, NULL); pfGSetAttr (geom, PFGS_TEXCOORD2, PFGS_PER_VERTEX, Shared->StaticTextureCoords, NULL); pfGSetAttr (geom, PFGS_COORD3, PFGS_PER_VERTEX, LeftScreen, NULL); pfGSetPrimType (geom, PFGS_QUADS); pfGSetNumPrims (geom, 1); /* create the left panel geometry node */ geode = pfNewGeode (); pfAddGSet (geode, geom); pfAddChild (Shared->sceneDCS, geode);
/* create the right panel geostate */ geom = pfNewGSet (arena); pfGSetGState (geom, Shared->movieState); pfGSetAttr (geom, PFGS_COLOR4, PFGS_OVERALL, Shared->Colour, NULL); pfGSetAttr (geom, PFGS_TEXCOORD2, PFGS_PER_VERTEX, Shared->VideoTextureCoords, NULL); pfGSetAttr (geom, PFGS_COORD3, PFGS_PER_VERTEX, RightScreen, NULL); pfGSetPrimType (geom, PFGS_QUADS); pfGSetNumPrims (geom, 1); /* create the right panel geometry node */ geode = pfNewGeode (); pfAddGSet (geode, geom); pfAddChild (Shared->sceneDCS, geode); }
/* Video initialization - goes in application process */ static int videoInit (void) { VLNode dev;
/* open the server */ if (!(Shared->vlServer = vlOpenVideo (""))) { vlPerror ("vlOpenVideo"); fprintf (stderr, "couldn't open video server!\n"); return (1); }
/* Get the Video source */ Shared->vlSrc = vlGetNode (Shared->vlServer, VL_SRC, VL_VIDEO, Shared->vlInSrc);
/* Get the Texture drain */ Shared->vlDrn = vlGetNode (Shared->vlServer, VL_DRN, VL_TEXTURE, 0);
/* Create path */ Shared->vlPath = vlCreatePath (Shared->vlServer, Shared->vlDevice, Shared->vlSrc, Shared->vlDrn); if (Shared->vlPath < 0) { vlPerror ("vlCreatePath"); return -1; }
/* setup path */ if (vlSetupPaths (Shared->vlServer, (VLPathList)&Shared->vlPath, 1, VL_SHARE, VL_SHARE) < 0) { vlPerror ("vlSetupPaths"); return -1; }
/* select the appropriate events */ if (vlSelectEvents (Shared->vlServer, Shared->vlPath, VLStreamPreemptedMask | VLControlChangedMask ) < 0) { vlPerror ("Select Events"); return -1; } if (DoFields) Shared->vlCaptureType.intVal = VL_CAPTURE_NONINTERLEAVED; else Shared->vlCaptureType.intVal = VL_CAPTURE_INTERLEAVED;
vlSetControl (Shared->vlServer, Shared->vlPath, Shared->vlDrn, VL_CAP_TYPE, &Shared->vlCaptureType); switch (Shared->TexFormat) { case PFTEX_RGBA_4: Shared->TexComp = 4; Shared->vlTexPack.intVal = SIR_TEX_PACK_RGBA_4; break; case PFTEX_RGB_5: Shared->TexComp = 3; Shared->vlTexPack.intVal = SIR_TEX_PACK_RGB_5; break; case PFTEX_RGBA_8: Shared->TexComp = 4; Shared->vlTexPack.intVal = SIR_TEX_PACK_RGBA_8; break; default: Shared->TexComp = 3; Shared->vlTexPack.intVal = SIR_TEX_PACK_RGB_5; Shared->TexFormat = PFTEX_RGB_5; break; } /* Set the Texture packing mode */ vlSetControl (Shared->vlServer, Shared->vlPath, Shared->vlDrn, VL_PACKING, &Shared->vlTexPack);
/* Get the timing from input source */ vlGetControl (Shared->vlServer, Shared->vlPath, Shared->vlSrc, VL_TIMING, &Shared->vlTiming);
/* Set texture drain's timing to input source */ vlSetControl (Shared->vlServer, Shared->vlPath, Shared->vlDrn, VL_TIMING, &Shared->vlTiming);
/* Get corresponding size */ vlGetControl (Shared->vlServer, Shared->vlPath, Shared->vlSrc, VL_SIZE, &Shared->vlSize);
return 0; }
static void videoExit (void) { vlEndTransfer (Shared->vlServer, Shared->vlPath); vlDestroyPath (Shared->vlServer, Shared->vlPath); vlCloseVideo (Shared->vlServer); }
static void setVideoTextureParameters (pfGeoState *gstate) { pfTexture *tex; pfMatrix *tmat; float s_scale, t_scale; tex = pfGetGStateAttr (gstate, PFSTATE_TEXTURE); if ((Shared->vlTiming.intVal == VL_TIMING_525_SQ_PIX) || (Shared->vlTiming.intVal == VL_TIMING_525_CCIR601)) { Shared->vlTexWidth = 1024; Shared->vlTexHeight = 512; } else { Shared->vlTexWidth = 1024; Shared->vlTexHeight = 1024; }
/*** createTextureMatrix (); ***/ tmat = (pfMatrix*)pfCalloc (sizeof (pfMatrix), 1, pfGetSharedArena ()); pfMakeIdentMat (*tmat); s_scale = (float)Shared->vlSize.xyVal.x / (float)Shared->vlTexWidth; t_scale = (float)Shared->vlSize.xyVal.y / (float)Shared->vlTexHeight;
(*tmat)[0][0] = s_scale; (*tmat)[1][1] = -t_scale; (*tmat)[3][1] = t_scale;
/* gset callbacks to manage texture matrix - put matrix in userData */ pfGStateFuncs (gstate, loadVideoTextureMatrixCB, loadStaticTextureMatrixCB, tmat);
pfNotify (PFNFY_INFO, PFNFY_PRINT, "Shared->vlSize.xyVal.x: %d\n", Shared->vlSize.xyVal.x); pfNotify (PFNFY_INFO, PFNFY_PRINT, "Shared->vlSize.xyVal.y: %d\n", Shared->vlSize.xyVal.y);
Shared->subTexLoadYsize = Shared->vlSize.xyVal.y;
/* if transfering fields then reduce image height by .5 */ if (DoFields) { Shared->vlTexHeight >>= 1; Shared->subTexLoadYsize >>= 1; }
pfNotify (PFNFY_INFO, PFNFY_PRINT, "subTexLoadYsize: %d\n", Shared->subTexLoadYsize);
/* define the video texture */ pfTexImage (tex, NULL, Shared->TexComp, Shared->vlTexWidth, Shared->vlTexHeight, 1);
if (RealityEngine) pfTexLoadSize (tex, SIRIUS_SCANLINE_SIZE, Shared->subTexLoadYsize); else if (InfiniteReality) pfTexLoadSize (tex, Shared->vlSize.xyVal.x, Shared->subTexLoadYsize);
/* specify the texture format, this is the default */ pfTexFormat (tex, PFTEX_INTERNAL_FORMAT, Shared->TexFormat);
/* specify a video texture */ pfTexLoadMode (tex, PFTEX_LOAD_SOURCE, PFTEX_SOURCE_VIDEO); }
/* * OpenPipeWin() -- create a win: setup the GL and IRIS Performer. * This procedure is executed in the DRAW process * (when there is a separate draw process). */ static int loadVideoTextureMatrixCB (pfGeoState *gs, void *userData) { glMatrixMode (GL_TEXTURE); glLoadIdentity (); glLoadMatrixf ((GLfloat *)userData); glMatrixMode (GL_MODELVIEW); return 0; }
static int loadStaticTextureMatrixCB (pfGeoState *gs, void *userData) { glMatrixMode (GL_TEXTURE); glLoadIdentity (); glMatrixMode (GL_MODELVIEW); return 0; }
static void openPipeWin (pfPipeWindow *pw) { Display *Dsp; Window xwin; const GLubyte *Str;
pfNotify (PFNFY_INFO, PFNFY_PRINT, "Opening Pipe-window..."); pfOpenPWin (pw); Dsp = pfGetCurWSConnection (); xwin = pfGetPWinWSWindow (pw); XMapWindow (Dsp, xwin); XSync (Dsp, False); /* Identify the graphics hardware. Note: RealityEngine can load either */ /* fields or frames into texture, but cannot interlace. InfiniteReality */ /* cannot load frames, but can interlace. */ Str = glGetString (GL_RENDERER); pfNotify (PFNFY_INFO, PFNFY_PRINT, "OpenGL Render Engine is: <type>/<pixd>/<nrm>/<texsz>/<nge>: %s", Str);
if (!strncmp (Str, "RE", 2)) { InfiniteReality = False; RealityEngine = True; Interlacing = False; DoFields = True; } else if (!strncmp (Str, "IR", 2)) { InfiniteReality = True; RealityEngine = False; Interlacing = True; DoFields = True; } else pfNotify (PFNFY_FATAL, PFNFY_RESOURCE, "Graphics Engine must be RealityEngine or InfiniteReality.");
/*** If possible, enable Interlace Extension ***/ if (Interlacing) glEnable (GL_INTERLACE_SGIX); if (!glIsEnabled (GL_INTERLACE_SGIX)) { pfNotify (PFNFY_WARN, PFNFY_RESOURCE, "Cannot enable interlace extension"); Interlacing = False; }
/*** initialise Sirius Video ***/ if (videoInit () < 0) pfNotify (PFNFY_FATAL, PFNFY_RESOURCE, "Error in initializing VL and Sirius.");
/* video starts running HERE */ vlBeginTransfer (Shared->vlServer, Shared->vlPath, 0, NULL); Shared->EndXfer = False; pfNotify (PFNFY_INFO, PFNFY_PRINT, "Video initialisation completed, xfer started");
Shared->videosource = glXCreateGLXVideoSourceSGIX (Dsp, 0 /* screen */, Shared->vlServer, Shared->vlPath, VL_TEXTURE, Shared->vlDrn); if (Shared->videosource == None) { fprintf (stderr, "Cannot create video source\n"); exit (EXIT_FAILURE); }
pfNotify (PFNFY_INFO, PFNFY_PRINT, "setVideoTextureParameters()...."); setVideoTextureParameters (Shared->videoState);
/* Set up global state */ /* if lighting initialization need (or other draw stuff) put here */ pfApplyTEnv (pfNewTEnv (pfGetSharedArena ()));
pfEnable (PFEN_TEXTURE);
pfNotify (PFNFY_INFO, PFNFY_PRINT, "Texture initialisation completed..."); if (LockMode) { pfuLockDownDraw(pfGetPWinPipe(pw)); } }
static void cullChannel (pfChannel *channel, void *data) { static int First = 1; if (First) { First = 0; #ifdef DEBUG_SCENE pfPrint (Shared->sceneDCS, PFTRAV_SELF | PFTRAV_DESCEND, PFPRINT_VB_ON, NULL); #endif } pfCull (); }
static void drawChannel (pfChannel *channel, void *data) { static Display *Dsp; static pfVec4 clr = {0.75f, 0.0f, 0.0f, 1.0f}; static int FirstFrame = 1; static int FrameCount = 0; static int Offset = 0; pfClear (PFCL_COLOR | PFCL_DEPTH, clr);
if (FirstFrame) { FirstFrame = 0; Dsp = pfGetCurWSConnection (); clr[0] = 0.0f; clr[2] = 0.5f; pfNotify (PFNFY_INFO, PFNFY_PRINT, "drawChannel() called..."); } else { if (!glXMakeCurrentReadSGI (Dsp, pfGetPWinWSDrawable (Shared->pw), Shared->videosource, pfGetPWinGLCxt (Shared->pw))) pfNotify (PFNFY_FATAL, PFNFY_RESOURCE, "glXMakeCurrentReadSGI failed"); if (Interlacing) Offset = (FrameCount++ % 2) ? 1 : 0; pfTexLoadOrigin (Shared->videoTex, PFTEX_ORIGIN_DEST, 0, Offset); pfLoadTex (Shared->videoTex);
pfDraw (); /* draw Performer throughput statistics */ if (Shared->drawStats) pfDrawChanStats (channel); } /* read window origin and size (it may have changed) */ pfGetPWinSize (pfGetChanPWin (channel), &Shared->winSizeX, &Shared->winSizeY);
if (Shared->EndXfer) { videoExit (); Shared->exitFlag = True; } }
/* * doXInput() runs an asychronous forked X event handling process. * Shared memory structures can be read from this process but NO * Performer calls that set any structures should be issued by * routines in this process. */ void doXInput (void) { /* windows from draw should now exist so can attach X input handling * to the X window */ Display *dsp = pfGetCurWSConnection (); Window w; prctl (PR_TERMCHILD); /* Exit when parent does */ sigset (SIGHUP, SIG_DFL); /* Exit when sent SIGHUP by TERMCHILD */ /* wait for Pipe Window to exist in Performer shared memory */ while (!(w = pfGetPWinWSWindow (Shared->pw))) {}; XSelectInput (dsp, w, PointerMotionMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask); XMapWindow (dsp, w); XSync (dsp, False); XFlush (dsp); pfNotify (PFNFY_INFO, PFNFY_PRINT, "doXInput: Entering event loop..."); while (True) getXInput (dsp); }
static void getXInput (Display *dsp) { static int x = 0, y = 0; while (XPending (dsp)) { XEvent event; XNextEvent (dsp, &event);
switch (event.type) { case ConfigureNotify: break;
case FocusIn: Shared->inWindow = True; break;
case FocusOut: Shared->inWindow = False; break;
case MotionNotify: { XMotionEvent *motion_event = (XMotionEvent *)&event; x = motion_event->x; y = Shared->winSizeY - motion_event->y; } break;
case ButtonPress: { XButtonEvent *button_event = (XButtonEvent *)&event; x = event.xbutton.x; y = Shared->winSizeY - event.xbutton.y; Shared->inWindow = True; switch (button_event->button) { case Button1: Shared->mouseButtons |= Button1Mask; break;
case Button2: Shared->mouseButtons |= Button2Mask; break;
case Button3: Shared->mouseButtons |= Button3Mask; break; } } break;
case ButtonRelease: { XButtonEvent *button_event = (XButtonEvent *)&event; switch (button_event->button) { case Button1: Shared->mouseButtons &= ~Button1Mask; break;
case Button2: Shared->mouseButtons &= ~Button2Mask; break;
case Button3: Shared->mouseButtons &= ~Button3Mask; break; } } break;
case KeyPress: { char buf[100]; int rv; KeySym ks;
rv = XLookupString (&event.xkey, buf, sizeof(buf), &ks, 0); switch (ks) { case XK_Escape: Shared->EndXfer = True; pfNotify (PFNFY_NOTICE, PFNFY_PRINT, "Ending Video Xfer..."); break;
case XK_space: Shared->reset = True; pfNotify (PFNFY_NOTICE, PFNFY_PRINT, "Reset"); break;
case XK_b: Shared->panelBackward = True; Shared->panelForward = False; break;
case XK_f: Shared->panelBackward = False; Shared->panelForward = True; break;
case XK_g: Shared->drawStats = !Shared->drawStats; break;
case XK_r: Shared->runMovie = !Shared->runMovie; break;
case XK_s: Shared->spin = !Shared->spin; break; default: break; } } break;
default: break; } } Shared->Angle = ((float)(x - Shared->winSizeX / 2) * 360.0f) / (float)Shared->winSizeX; }
======================================================================= List Archives, FAQ, FTP: http://www.sgi.com/Technology/Performer/ Submissions: info-performer++at++sgi.com Admin. requests: info-performer-request++at++sgi.com
This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:53:18 PDT