From 189e4e3a6445de5a1e0c39c6c06c3a164b9e5a08 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 23 May 2018 14:30:31 +0100 Subject: [PATCH] Implemented StateGraph reuse in in scene graph Canera's RenderStage. --- include/osgUtil/CullVisitor | 6 +-- src/osgUtil/CullVisitor.cpp | 76 +++++++++++++++++++++---------------- 2 files changed, 47 insertions(+), 35 deletions(-) diff --git a/include/osgUtil/CullVisitor b/include/osgUtil/CullVisitor index 659f0dea6..93d7b8e11 100644 --- a/include/osgUtil/CullVisitor +++ b/include/osgUtil/CullVisitor @@ -466,7 +466,7 @@ inline RenderLeaf* CullVisitor::createOrReuseRenderLeaf(osg::Drawable* drawable, while (_currentReuseRenderLeafIndex<_reuseRenderLeafList.size() && _reuseRenderLeafList[_currentReuseRenderLeafIndex]->referenceCount()>1) { - osg::notify(osg::NOTICE)<<"Warning:createOrReuseRenderLeaf() skipping multiply referenced entry."<< std::endl; + osg::notify(osg::INFO)<<"CullVisitor:createOrReuseRenderLeaf() skipping multiply referenced entry. _reuseRenderLeafList.size()="<< _reuseRenderLeafList.size()<<" _reuseRenderLeafList["<<_currentReuseRenderLeafIndex<<"]->referenceCount()="<<_reuseRenderLeafList[_currentReuseRenderLeafIndex]->referenceCount()< previous_rootStateGraph = _rootStateGraph; - StateGraph* previous_currentStateGraph = _currentStateGraph; - - { - // replicate the StageGraph parental chain so that state graph and render leaves are kept local to 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. @@ -1649,8 +1619,49 @@ void CullVisitor::apply(osg::Camera& camera) rtts->reset(); } - // assign the state graph to the RenderStage to ensure it remains in memory for the draw traversal. - rtts->setStateGraph(_rootStateGraph); + // cache the StateGraph and replace with a clone of the existing parental chain. + osg::ref_ptr previous_rootStateGraph = _rootStateGraph; + StateGraph* previous_currentStateGraph = _currentStateGraph; + + // replicate the StageGraph parental chain so that state graph and render leaves are kept local to 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; + } + + _rootStateGraph = rtts->getStateGraph(); + if (_rootStateGraph) + { + _rootStateGraph->clean(); + } + else + { + _rootStateGraph = new StateGraph; + + // assign the state graph to the RenderStage to ensure it remains in memory for the draw traversal. + rtts->setStateGraph(_rootStateGraph.get()); + } + _currentStateGraph = _rootStateGraph.get(); + + StageGraphStack::reverse_iterator ritr = stateGraphParentalChain.rbegin(); + + if (ritr!=stateGraphParentalChain.rend()) + { + const osg::StateSet* ss = (*ritr++)->getStateSet(); + _rootStateGraph->setStateSet(ss); + + while(ritr != stateGraphParentalChain.rend()) + { + _currentStateGraph = _currentStateGraph->find_or_insert((*ritr++)->getStateSet()); + } + } + } + // set up clear masks/values rtts->setClearDepth(camera.getClearDepth()); @@ -1701,6 +1712,7 @@ void CullVisitor::apply(osg::Camera& camera) // restore cache of the StateGraph + _rootStateGraph->prune(); _rootStateGraph = previous_rootStateGraph; _currentStateGraph = previous_currentStateGraph;