MaterialPtr PerformerLoader::traverseGState(NodePtr node, pfGeoState *gstate) { FDEBUG(("PerformerLoader::traverseGState: traversing %p\n", gstate)); if(_materials.find(gstate) != _materials.end()) { FDEBUG(("PfL:traverseGState: found in matmap.\n")); return _materials[gstate]; } ChunkMaterialPtr mat = ChunkMaterial::create(); beginEditCP(mat); uint64_t inherit; inherit = gstate->getInherit(); static int pcolormode[] = { PFMTL_CMODE_AMBIENT_AND_DIFFUSE, PFMTL_CMODE_AMBIENT, PFMTL_CMODE_DIFFUSE, PFMTL_CMODE_EMISSION, PFMTL_CMODE_SPECULAR, PFMTL_CMODE_OFF, -1 }; static int ocolormode[] = { GL_AMBIENT_AND_DIFFUSE, GL_AMBIENT, GL_DIFFUSE, GL_EMISSION, GL_SPECULAR, GL_NONE }; pair<void *, void*> key; if((inherit & (PFSTATE_FRONTMTL | PFSTATE_BACKMTL)) != (PFSTATE_FRONTMTL | PFSTATE_BACKMTL) ) { MaterialChunkPtr matc; key.first = NULL; if (!(inherit & PFSTATE_FRONTMTL)) key.first = gstate->getAttr(PFSTATE_FRONTMTL); key.second = NULL; if (!(inherit & PFSTATE_BACKMTL)) key.second = gstate->getAttr(PFSTATE_BACKMTL); if(_chunks.find(key) != _chunks.end()) { matc = MaterialChunkPtr::dcast(_chunks[key]); } else { matc = MaterialChunk::create(); beginEditCP(matc); if (!(inherit & PFSTATE_FRONTMTL)) { pfMaterial *mat = (pfMaterial*)gstate->getAttr(PFSTATE_FRONTMTL); float r,g,b,a; a = mat->getAlpha(); mat->getColor(PFMTL_AMBIENT, &r, &g, &b); matc->setAmbient(Color4f(r,g,b,0)); mat->getColor(PFMTL_DIFFUSE, &r, &g, &b); matc->setDiffuse(Color4f(r,g,b,a)); mat->getColor(PFMTL_SPECULAR, &r, &g, &b); matc->setSpecular(Color4f(r,g,b,0)); mat->getColor(PFMTL_EMISSION, &r, &g, &b); matc->setEmission(Color4f(r,g,b,0)); matc->setShininess(mat->getShininess()); int cm = mat->getColorMode(PFMTL_FRONT); UInt32 om = GL_NONE; for (UInt16 i = 0; pcolormode[i] != -1; ++i) if(pcolormode[i] == cm) om = ocolormode[i]; matc->setColorMaterial(om); } if (!(inherit & PFSTATE_BACKMTL)) { pfMaterial *mat = (pfMaterial*)gstate->getAttr(PFSTATE_BACKMTL); matc->setBackMaterial(true); float r,g,b,a; a = mat->getAlpha(); mat->getColor(PFMTL_AMBIENT, &r, &g, &b); matc->setBackAmbient(Color4f(r,g,b,0)); mat->getColor(PFMTL_DIFFUSE, &r, &g, &b); matc->setBackDiffuse(Color4f(r,g,b,a)); mat->getColor(PFMTL_SPECULAR, &r, &g, &b); matc->setBackSpecular(Color4f(r,g,b,0)); mat->getColor(PFMTL_EMISSION, &r, &g, &b); matc->setBackEmission(Color4f(r,g,b,0)); matc->setBackShininess(mat->getShininess()); int cm = mat->getColorMode(PFMTL_FRONT); UInt32 om = GL_NONE; for (UInt16 i = 0; pcolormode[i] != -1; ++i) if(pcolormode[i] == cm) om = ocolormode[i]; matc->setBackColorMaterial(om); } endEditCP(matc); } mat->addChunk(matc); } if((inherit & (PFSTATE_TEXTURE | PFSTATE_TEXENV)) != (PFSTATE_TEXTURE | PFSTATE_TEXENV) ) { TextureChunkPtr texc; for(int t = 0; t < PF_MAX_TEXTURES; ++t) { if(gstate->getMultiAttr(PFSTATE_TEXTURE, t) == NULL) continue; key.first = NULL; if (!(inherit & PFSTATE_TEXTURE) && gstate->getMultiAttr(PFSTATE_TEXTURE, t)) key.first = gstate->getMultiAttr(PFSTATE_TEXTURE, t); key.second = NULL; if (!(inherit & PFSTATE_TEXENV) && gstate->getMultiAttr(PFSTATE_TEXENV, t)) key.second = gstate->getMultiAttr(PFSTATE_TEXENV, t); if(_chunks.find(key) != _chunks.end()) { texc = TextureChunkPtr::dcast(_chunks[key]); } else { texc = TextureChunk::create(); beginEditCP(texc); if (!(inherit & PFSTATE_TEXTURE)) { pfTexture *tex = (pfTexture*)gstate->getMultiAttr(PFSTATE_TEXTURE, t); unsigned int* pdata; int pf, w, h, d, type, comp, sides; UInt32 intformat = 0, extformat = 0; tex->getImage(&pdata, &comp, &w, &h, &d); sides = tex->getFormat(PFTEX_CUBE_MAP) ? 6 : 1; pf = tex->getFormat(PFTEX_IMAGE_FORMAT); if(pf == 0x7fff) { switch(comp) { case 1: pf = Image::OSG_L_PF; break; case 2: pf = Image::OSG_LA_PF; break; case 3: pf = Image::OSG_RGB_PF; break; case 4: pf = Image::OSG_RGBA_PF; break; } } switch(tex->getFormat(PFTEX_EXTERNAL_FORMAT)) { case PFTEX_PACK_8: type = Image::OSG_UINT8_IMAGEDATA; break; case PFTEX_PACK_16: type = Image::OSG_UINT16_IMAGEDATA; break; default: type = Image::OSG_UINT8_IMAGEDATA; FWARNING(("PerformerLoader::traverseGState: " "Unknown tex format %d!\n", tex->getFormat(PFTEX_EXTERNAL_FORMAT))); extformat = tex->getFormat(PFTEX_EXTERNAL_FORMAT); break; } intformat = tex->getFormat(PFTEX_INTERNAL_FORMAT); ImagePtr img = Image::create(); beginEditCP(img); img->set(pf, w, h, d, 1, 1, 0, NULL, type, 1, sides); if(sides == 1) { memcpy(img->getData(), pdata, img->getSize()); } else { FWARNING(("PerformerLoader::traverseGState: " "CubeTex not impl yet!\n")); } endEditCP(img); texc->setImage(img); texc->setInternalFormat(intformat); texc->setWrapS(tex->getRepeat(PFTEX_WRAP_S)); texc->setWrapT(tex->getRepeat(PFTEX_WRAP_T)); texc->setWrapR(tex->getRepeat(PFTEX_WRAP_R)); static int ptexfilter[] = { PFTEX_POINT, PFTEX_LINEAR, PFTEX_BILINEAR, PFTEX_TRILINEAR, PFTEX_QUADLINEAR, PFTEX_MIPMAP_POINT, PFTEX_MIPMAP_LINEAR, PFTEX_MIPMAP_BILINEAR, PFTEX_MIPMAP_TRILINEAR, PFTEX_MIPMAP_QUADLINEAR, -1 }; static int otexfilter[] = { GL_NEAREST, GL_LINEAR, GL_LINEAR, GL_LINEAR, GL_LINEAR, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_LINEAR }; int ptf = tex->getFilter(PFTEX_MINFILTER); UInt32 otf = GL_NONE; for (UInt16 i = 0; ptexfilter[i] != -1; ++i) if(ptexfilter[i] == ptf) otf = otexfilter[i]; texc->setMinFilter(otf); ptf = tex->getFilter(PFTEX_MAGFILTER); otf = GL_NONE; for (UInt16 i = 0; ptexfilter[i] != -1; ++i) if(ptexfilter[i] == ptf) otf = otexfilter[i]; texc->setMagFilter(otf); } if (!(inherit & PFSTATE_TEXENV)) { pfTexEnv *te = (pfTexEnv*)gstate->getMultiAttr(PFSTATE_TEXENV, t); if(te != NULL) { texc->setEnvMode(te->getMode()); float r,g,b,a; te->getBlendColor(&r,&g,&b,&a); texc->setEnvColor(Color4f(r,g,b,a)); } } endEditCP(texc); } mat->addChunk(texc); } // for t } /* Unhandled: lightmodel, lights, fog, texgen, texlod, vtxprog, fragprog, gprogparms, colortable, highlight, lpointstate, shadprog */ endEditCP(mat); _materials[gstate] = mat; return mat; }
int main( int argc, char *argv[] ) { osgInit(argc, argv); glutInit(&argc, argv); glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); glutCreateWindow("OpenSG"); glutKeyboardFunc(key); // glutReshapeFunc(resize); glutDisplayFunc(display); // glutMouseFunc(mouse); // glutMotionFunc(motion); glutIdleFunc(display); pImage = Image::create(); // create the dummy structures // the window is needed for the chunks that access GLObjects win = GLUTWindow::create(); win->frameInit(); // test for preliminary calls not messing up GLexts win->init(); dact = DrawAction::create(); dact->setWindow(get_pointer(win)); win->init(); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective( 60, 1, 0.1, 10 ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); gluLookAt( 3, 3, 3, 0, 0, 0, 0, 1, 0 ); glEnable( GL_DEPTH_TEST ); glEnable( GL_LIGHTING ); glEnable( GL_LIGHT0 ); glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); dlid = glGenLists( 1 ); glNewList( dlid, GL_COMPILE ); glutSolidSphere( .8, 8, 8 ); glEndList(); dlid2 = glGenLists( 1 ); glNewList( dlid2, GL_COMPILE ); glBegin( GL_POLYGON ); glNormal3f( 0, 1, 0 ); glColor3f( 1, 1, 1 ); glTexCoord2f( 0, 0 ); glVertex3f( -1.5, -1, -1.5 ); glTexCoord2f( 2, 0 ); glVertex3f( 1.5, -1, -1.5 ); glTexCoord2f( 2, 2 ); glVertex3f( 1.5, -1, 1.5 ); glTexCoord2f( 0, 2 ); glVertex3f( -1.5, -1, 1.5 ); glEnd(); glEndList(); Matrix m; tchunk1 = TransformChunk::create(); m.setTranslate( 0, 1, 0 ); tchunk1->setMatrix( m ); tchunk2 = TransformChunk::create(); tchunk2->setMatrix( Matrix::identity() ); mchunk1 = MaterialChunk::create(); mchunk1->setDiffuse( Color4f( 1,0,0,0 ) ); mchunk1->setAmbient( Color4f( 1,0,0,0 ) ); mchunk1->setShininess( 20 ); mchunk2 = MaterialChunk::create(); mchunk2->setDiffuse( Color4f( 0,1,0,0 ) ); mchunk2->setAmbient( Color4f( 0,1,0,0 ) ); mchunk2->setShininess( 50 ); // Texture chunk // UChar8 imgdata[] = // { 255,0,0,0, 0,255,0,0, 0,0,255,255, 255,255,255,255 }; UChar8 imgdata[] = { 255,0,0, 255,0,0, 255,0,255, 255,0,0, 255,0,0, 255,0,255, 255,255,0, 255,255,0, 255,255,255, 255,255,0, 255,255,0, 255,255,255, }; // UChar8 limgdata[] = // { 0, 128, 64, 255 }; pImage->set( Image::OSG_RGB_PF, 2, 2, 1, 1, 1, 0, imgdata ); if ( argc > 1 ) pImage->read( argv[1] ); xchunk1 = TextureChunk::create(); beginEditCP(xchunk1); xchunk1->setImage( pImage ); // NOTE: the image is NOT copied, the variable // needs to be kept around as long as the // texture is used xchunk1->setMinFilter( GL_LINEAR ); xchunk1->setMagFilter( GL_NEAREST ); xchunk1->setWrapS( GL_REPEAT ); xchunk1->setWrapT( GL_REPEAT ); xchunk1->setEnvMode( GL_REPLACE ); xchunk1->setEnvColor( Color4f(.5,.5,.5,0) ); xchunk1->setScale( false ); // xchunk1->setShaderOperation(GL_PASS_THROUGH_NV); endEditCP(xchunk1); xchunk1->imageContentChanged(); beginEditCP(xchunk1); xchunk1->setImage( pImage ); endEditCP(xchunk1); // blend chunk blchunk = BlendChunk::create(); #ifdef GL_EXT_blend_color blchunk->setSrcFactor( GL_CONSTANT_ALPHA ); blchunk->setDestFactor( GL_ONE_MINUS_CONSTANT_ALPHA ); #endif blchunk->setColor( Color4f( .5,.5,.5,0.1 ) ); blchunk->setEquation(GL_FUNC_SUBTRACT); std::cout << "BlendChunk is trans:" << blchunk->isTransparent() << std::endl; // texture transform chunk txchunk = TextureTransformChunk::create(); beginEditCP(txchunk); txchunk->setMatrix( Matrix(4,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1) ); endEditCP(txchunk); // polygon chunk pchunk1 = PolygonChunk::create(); { UInt32 stipple[32] = { 0xffff0000, 0x0000ffff, 0xffff0000, 0x0000ffff, 0xffff0000, 0x0000ffff, 0xffff0000, 0x0000ffff, 0xffff0000, 0x0000ffff, 0xffff0000, 0x0000ffff, 0xffff0000, 0x0000ffff, 0xffff0000, 0x0000ffff, 0xffff0000, 0x0000ffff, 0xffff0000, 0x0000ffff, 0xffff0000, 0x0000ffff, 0xffff0000, 0x0000ffff, 0xffff0000, 0x0000ffff, 0xffff0000, 0x0000ffff, 0xffff0000, 0x0000ffff, 0xffff0000, 0x0000ffff }; pchunk1->editMFStipple()->clear(); for ( int i = 0; i < 32; i++ ) pchunk1->editMFStipple()->push_back( stipple[i] ); } pchunk1->setFrontMode(GL_LINE); pchunk1->setBackMode(GL_FILL); pchunk2 = PolygonChunk::create(); { UInt32 stipple[32] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }; pchunk2->editMFStipple()->clear(); for ( int i = 0; i < 32; i++ ) pchunk2->editMFStipple()->push_back( stipple[i] ); } lichunk1 = LineChunk::create(); lichunk1->setSmooth(true); lichunk1->setStipplePattern(0xf0f0); lichunk2 = LineChunk::create(); lichunk2->setStippleRepeat(5); lichunk2->setStipplePattern(0xaaaa); glutMainLoop(); return 0; }