[Plib-users] modifying materials of loaded models on the fly
Brought to you by:
sjbaker
From: Jakob G. <pi...@st...> - 2006-02-11 11:14:11
|
Hi. I'm trying to change the material properties of AC3D models after I load them. (think of a bottle model which is then used to render bottles with different surface properties). I can, sort of, achieve this following Steve Bakers earlier suggestion of locating the ssgSimpleState objects in the loaded model and then modifying them. However, it only works if I update and replace ALL of them. I was hoping I could just do myLeaf->setState(NULL) on all but the first one, and that the state set when starting the rendering would then "carry through" throughout the render of the whole object. Instead, this leaves the rest of the object uncoloured/white. There is one optimization that seems to work though - I can pick up the first ssgSimpleState, and then replace all the subsequent ssgstates with it. From this I at least get, that I only have to modify attributes of one ssgState. So my question: Am I just misunderstanding how SSG works - does each and every ssgLeaf need its own separate ssgState? I would have thought that 'last used state' would carry through for ssgLeafs with NULL ssgState? I include part of the code here, to illustrate what I'm doing. class MyTraverser : public TraverserBase { public: ssgState* firstState; private: int leafType; virtual bool visit(ssgEntity* pEnt) { if (!pEnt->isAKindOf(leafType)) { return true; // search on } ssgLeaf* pLeaf = static_cast<ssgLeaf*>(pEnt); ssgState* leafState = pLeaf->getState(); if (leafState != NULL) { if (firstState == NULL) { firstState = leafState; } else { //pLeaf->setState(NULL); //pLeaf->setState(new ssgSimpleState); pLeaf->setState(firstState); } /* ssgSimpleState* thestate = static_cast<ssgSimpleState*>(leafState); thestate->set(GL_COLOR_MATERIAL, false); thestate->setMaterial(GL_DIFFUSE, 0.99, 0.1, 0.1, 1.0); thestate->setMaterial(GL_AMBIENT, 0.6, 0.2, 0.4, 1.0); thestate->setMaterial(GL_SPECULAR,0.4, 0.6, 0.2, 1.0); */ } return true; } public: MyTraverser() { leafType = ssgTypeLeaf(); firstState = NULL; } }; This I then call like this: ... MyTraverser trav; trav.findLeafs(my_ssgScene); if (trav.firstState) { ssgSimpleState* thestate = static_cast<ssgSimpleState*>(trav.firstState); thestate->set(GL_COLOR_MATERIAL, false); // nothing worked without this... thestate->setMaterial(GL_DIFFUSE, 0.99, 0.1, 0.1, 1.0); thestate->setMaterial(GL_AMBIENT, 0.6, 0.2, 0.4, 1.0); thestate->setMaterial(GL_SPECULAR,0.4, 0.6, 0.2, 1.0); } ssgFlatten(themodel); ssgStripify(tra); I hope some more experienced users can clarify this. Cheers and thanks in advance, Jakob Gaardsted. |