Hi,
I'm working on a node visitor to run around a scenegraph detecting
statesets with attached glsl program attributes, and in the presence
of a non "fixed function" program (#shaders > 0), insert some new
"helper" shaders to allow complete linking.
All the nodes/drawables in my test graph that have a glsl program
attribute have either 0 shaders (fixed function), or 2 (main() vert/
frag, which make reference to the "helper shaders" I'm attaching).
When my test graph does not contain any particle systems, all behaves
as expected. Non fixed function programs are located and "helper
shaders" attached. Everything links and my scene renders as expected.
However. When I add a particle system with a program attached to the
stateset on its drawable, enclosing group or just about anywhere else
around it. Strange things start to happen. Program attributes on
other parts of the graph which previously had two shaders attached,
now appear is if they have no shaders attached and are incorrectly
picked up by my visitor as being fixed function.
My test scenegraph is constructed as a procedurally generated tree of
groups/transformnodes with .osg files as the "leaves". Most of
the .osg files themselves are a hierarchical structure of groups/
transform nodes containing drawables and particle systems. The .osg
files clearly state which "objects" have fixed function program
objects and which contain actual shader code. But somewhere along the
line select shader objects seem to be going missing.
Extract from one of the .osg files ("5x5 wooden.osg") tacked on to
the tree, this file does not contain any particle systems:
...
MatrixTransform {
StateSet {
Program{
DataVariance STATIC
name "5x5 wooden.osg program"
num_shaders 2
...
Output of my visitor when no particle systems are added to the graph:
# 5x5 wooden.osg program is NOT FIXED function, added helpers.
With a particle system added, elsewhere in the graph (not a child of
5x5 wooden.osg):
# 5x5 wooden.osg program IS FIXED function, skipping.
Not all "objects" lose their shaders like this. Only select ones for
some mysterious reason. It's always the same ones, but there's no
obvious pattern or similar trait they possess to link them.
This is probably a difficult one to speculate on without the source,
I can post some snippets and things if they might be helpful, but
there's really nothing much fancy about the code at all. I'm not
using the standard osg visitor pattern, opting instead for my own
class not derived from osg::NodeVisitor, but I can't see how that
would cause problems like this.
Here's the source to the visitor incase it helps any.
---------------------------
class UpdateShadersVisitor : public osg::Referenced
{
public:
UpdateShadersVisitor(void);
void update(MPRenderState *STATE, osg::Node *NODE);
private:
MPRenderState *_tempstate;
void apply(osg::Node *NODE);
void apply(osg::Drawable *DRAWABLE);
};
---------------------------
MPRenderSuperpass::UpdateShadersVisitor::UpdateShadersVisitor(void)
{
_tempstate = NULL;
}
void MPRenderSuperpass::UpdateShadersVisitor::update(MPRenderState
*STATE, osg::Node *NODE)
{
_tempstate = STATE;
if(_tempstate != NULL) apply(NODE);
_tempstate = NULL;
}
void MPRenderSuperpass::UpdateShadersVisitor::apply(osg::Node* NODE)
{
if(NODE != NULL)
{
if(NODE->getStateSet() != NULL)
{
osg::Program *program = dynamic_cast<osg::Program*>(NODE-
>getStateSet()->getAttribute(osg::StateAttribute::PROGRAM));
if(program != NULL)
{
cout << program->getName();
if(program->isFixedFunction() == false)
{
program->addShader(_tempstate->scenehdrtonemapshader());
program->addShader(_tempstate->scenebloomtonemapshader());
program->addShader(_tempstate->scenepfdofencodeshader());
cout << " is NOT FIXED function, added
helpers.";
}
else cout << " IS FIXED function, skipping.";
cout << "\n";
}
}
osg::Group *group = dynamic_cast<osg::Group*>(NODE);
if(group != NULL)
{
long i = 0;
while(i < group->getNumChildren())
{
apply(group->getChild(i));
i++;
}
}
osg::Geode *geode = dynamic_cast<osg::Geode*>(NODE);
if(geode != NULL)
{
long i = 0;
while(i < geode->getNumDrawables())
{
apply(geode->getDrawable(i));
i++;
}
}
}
}
void MPRenderSuperpass::UpdateShadersVisitor::apply(osg::Drawable
*DRAWABLE)
{
if(DRAWABLE != NULL)
{
if(DRAWABLE->getStateSet() != NULL)
{
osg::Program *program = dynamic_cast<osg::Program*>(DRAWABLE-
>getStateSet()->getAttribute(osg::StateAttribute::PROGRAM));
if(program != NULL)
{
cout << program->getName();
if(program->isFixedFunction() == false)
{
program->addShader(_tempstate->scenehdrtonemapshader());
program->addShader(_tempstate->scenebloomtonemapshader());
program->addShader(_tempstate->scenepfdofencodeshader());
cout << " is NOT FIXED function, added
helpers.";
}
else cout << " IS FIXED function, skipping.";
cout << "\n";
}
}
}
}
Sorry for the long email, thanks in advance for any time given.
Alan.
_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/