diff --git a/include/osgUtil/RenderBin b/include/osgUtil/RenderBin index f19961c7e..22b16cfc2 100644 --- a/include/osgUtil/RenderBin +++ b/include/osgUtil/RenderBin @@ -73,6 +73,9 @@ class OSGUTIL_EXPORT RenderBin : public osg::Object virtual void reset(); + void setStateGraph(StateGraph* sg) { _rootStateGraph = sg; } + StateGraph* getStateGraph() { return _rootStateGraph.get(); } + void setStateSet(osg::StateSet* stateset) { _stateset = stateset; } osg::StateSet* getStateSet() { return _stateset.get(); } const osg::StateSet* getStateSet() const { return _stateset.get(); } @@ -157,6 +160,8 @@ class OSGUTIL_EXPORT RenderBin : public osg::Object virtual ~RenderBin(); + osg::ref_ptr _rootStateGraph; + int _binNum; RenderBin* _parent; RenderStage* _stage; diff --git a/src/osgUtil/CullVisitor.cpp b/src/osgUtil/CullVisitor.cpp index b49951b1c..34bfa25c6 100644 --- a/src/osgUtil/CullVisitor.cpp +++ b/src/osgUtil/CullVisitor.cpp @@ -1569,13 +1569,41 @@ void CullVisitor::apply(osg::Camera& camera) } else { + // cache the StateGraph and replace with a clone of the exisitng parental chain. + osg::ref_ptr previous_rootStateGraph = _rootStateGraph; + StateGraph* previous_currentStateGraph = _currentStateGraph; + + { + // replicate the StageGraph parental chain so that state graph and render leaves all are kept local the the Camera's RenderStage. + typedef std::vector< osg::ref_ptr > StageGraphStack; + StageGraphStack stateGraphParentalChain; + StateGraph* sg = _currentStateGraph; + while(sg) + { + stateGraphParentalChain.push_back(sg); + sg = sg->_parent; + } + + StageGraphStack::reverse_iterator ritr = stateGraphParentalChain.rbegin(); + + if (ritr!=stateGraphParentalChain.rend()) + { + const osg::StateSet* ss = (*ritr++)->getStateSet(); + _rootStateGraph = ss ? new StateGraph(0, ss) : new StateGraph(); + _currentStateGraph = _rootStateGraph.get(); + + while(ritr != stateGraphParentalChain.rend()) + { + _currentStateGraph = _currentStateGraph->find_or_insert((*ritr++)->getStateSet()); + } + } + } + // set up lighting. // currently ignore lights in the scene graph itself.. // will do later. osgUtil::RenderStage* previous_stage = getCurrentRenderBin()->getStage(); -// unsigned int contextID = getState() ? getState()->getContextID() : 0; - // use render to texture stage. // create the render to texture stage. osg::ref_ptr rsCache = dynamic_cast(camera.getRenderingCache()); @@ -1621,6 +1649,9 @@ void CullVisitor::apply(osg::Camera& camera) rtts->reset(); } + // assign the state grph to the RenderStage to ensure it remains in memory for the draw traversal. + rtts->setStateGraph(_rootStateGraph); + // set up clear masks/values rtts->setClearDepth(camera.getClearDepth()); rtts->setClearAccum(camera.getClearAccum()); @@ -1669,6 +1700,11 @@ void CullVisitor::apply(osg::Camera& camera) } + // restored cache of the StateGraph + _rootStateGraph = previous_rootStateGraph; + _currentStateGraph = previous_currentStateGraph; + + // and the render to texture stage to the current stages // dependency list. switch(camera.getRenderOrder())