From a4c8804b1b5419cc220008213d21c9af83921232 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 18 May 2018 10:00:10 +0100 Subject: [PATCH] Introduced a local StateGraph hierarchy into CullVisitor::apply(osg::Camera&) and RenderBin to fixed RTT Camera bug where multiple RTT Camera end up with the rendering back end results assigned to them which occured when RTT Camera's share the same StateSet or null StateSet. --- include/osgUtil/RenderBin | 5 +++++ src/osgUtil/CullVisitor.cpp | 40 +++++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) 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())