#include #include #include #include #include #include #include #include #include #include static void createScene(pfChannel *chan,int argc,char **argv); static pfGeode * createMesh(void); static pfGeoSet * createGeoSet(pfVec3 *verts,pfVec3 *norms,pfVec4 *colors,int xres,int yres); static int changeGeometry(pfTraverser *trav,void *); int main(int argc,char **argv) { pfInit(); pfCAVEConfig(&argc,argv,NULL); pfConfig(); pfCAVEInitChannels(); if (CAVEConfig->Simulator) pfCAVEMasterChan()->getFStats()->setClass( PFSTATS_ALL^PFSTATSHW_ENGFXPIPE_FILL, PFSTATS_ON); else pfCAVEMasterChan()->getFStats()->setClass(PFSTATS_ALL, PFSTATS_OFF); createScene(pfCAVEMasterChan(),argc,argv); while (!CAVEgetbutton(CAVE_ESCKEY)) { pfSync(); pfCAVEPreFrame(); pfFrame(); pfCAVEPostFrame(); } pfCAVEHalt(); pfExit(); return 0; } static void createScene(pfChannel *chan,int ,char **) { pfScene *scene; pfGeoState *gstate; pfLightSource *light; scene = new pfScene; gstate = new pfGeoState; gstate->setMode(PFSTATE_ENLIGHTING, PF_ON); gstate->setMode(PFSTATE_CULLFACE, PFCF_OFF); scene->setGState(gstate); light = new pfLightSource; light->setColor(PFLT_DIFFUSE, 1.0, 1.0, 1.0); light->setAmbient(0.0, 0.0, 0.0); scene->addChild(light); scene->addChild(createMesh()); chan->setScene(scene); } static pfGeode * createMesh(void) { int xres=32, yres=32, x, y, index; pfGeoSet *gset; pfGeode *geode; pfVec3 *verts, *norms; pfVec4 *colors; verts = (pfVec3 *) pfMalloc(xres * yres * sizeof(pfVec3), pfGetSharedArena()); norms = (pfVec3 *) pfMalloc(xres * yres * sizeof(pfVec3), pfGetSharedArena()); colors = (pfVec4 *) pfMalloc(xres * yres * sizeof(pfVec4), pfGetSharedArena()); for (y = 0, index = 0; y < yres; y++) for (x = 0; x < xres; x++, index++) { verts[index].set(x - xres/2.0f + 0.5f, y - yres/2.0f + 0.5f, 0); norms[index].set(0,0,1); pfuRandomColor(colors[index], 0.3, 0.6); } gset = createGeoSet(verts,norms,colors,xres,yres); geode = new pfGeode; geode->addGSet(gset); geode->setTravFuncs(PFTRAV_APP, changeGeometry, NULL); return geode; } static pfGeoSet * createGeoSet(pfVec3 *verts,pfVec3 *norms,pfVec4 *colors,int xres,int yres) { pfGeoSet *gset; int *lengths, x,y,index; ushort *ilist; gset = new pfGeoSet; gset->setPrimType(PFGS_TRISTRIPS); gset->setNumPrims(yres-1); lengths = (int *) pfMalloc((yres-1)*sizeof(int),pfGetSharedArena()); for (y = 0; y < yres-1; y++) lengths[y] = xres * 2; gset->setPrimLengths(lengths); ilist = (ushort *) pfMalloc((2 * xres) * (yres - 1) * sizeof(ushort), pfGetSharedArena()); for (y = 0, index = 0; y < yres-1; y++) for (x = 0; x < xres; x++) { ilist[index++] = x + y * xres; ilist[index++] = x + y * xres + xres; } gset->setAttr(PFGS_COORD3, PFGS_PER_VERTEX, verts, ilist); gset->setAttr(PFGS_NORMAL3, PFGS_PER_VERTEX, norms, ilist); gset->setAttr(PFGS_COLOR4, PFGS_PER_VERTEX, colors, ilist); gset->setGState(new pfGeoState); return gset; } static int changeGeometry(pfTraverser *trav,void *) { pfGeode *geode = (pfGeode *) trav->getNode(); pfGeoSet *gset = geode->getGSet(0); pfVec3 *verts, *norms; ushort *ilist; int numVerts, i; float sinX,cosX,sinY,cosY, phase=pfGetTime()*90; gset->getAttrLists(PFGS_COORD3, (void **) &verts, &ilist); gset->getAttrLists(PFGS_NORMAL3, (void **) &norms, &ilist); numVerts = pfGetSize(verts) / sizeof(pfVec3); for (i=0; i < numVerts; i++) { pfSinCos(verts[i][0]*30 + phase, &sinX, &cosX); pfSinCos(verts[i][1]*30 + phase, &sinY, &cosY); verts[i][2] = sinX * sinY; norms[i][0] = cosX; norms[i][1] = cosY; norms[i][2] = 1; norms[i].normalize(); } return PFTRAV_CONT; }