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/

Reply via email to