Implemented StateGraph reuse in in scene graph Canera's RenderStage.

This commit is contained in:
Robert Osfield 2018-05-23 14:30:31 +01:00
parent e5ff90e455
commit 6eb6634997
2 changed files with 46 additions and 35 deletions

View File

@ -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()<<std::endl;
++_currentReuseRenderLeafIndex;
}
@ -478,15 +478,15 @@ inline RenderLeaf* CullVisitor::createOrReuseRenderLeaf(osg::Drawable* drawable,
return renderleaf;
}
// Otherwise need to create new renderleaf.
RenderLeaf* renderleaf = new RenderLeaf(drawable,projection,matrix,depth,_traversalOrderNumber++);
_reuseRenderLeafList.push_back(renderleaf);
++_currentReuseRenderLeafIndex;
return renderleaf;
}
}
#endif

View File

@ -1569,36 +1569,6 @@ void CullVisitor::apply(osg::Camera& camera)
}
else
{
// cache the StateGraph and replace with a clone of the existing parental chain.
osg::ref_ptr<StateGraph> 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<StateGraph> > 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,48 @@ 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.get());
// cache the StateGraph and replace with a clone of the existing parental chain.
osg::ref_ptr<StateGraph> 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<StateGraph> > 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 +1711,7 @@ void CullVisitor::apply(osg::Camera& camera)
// restore cache of the StateGraph
_rootStateGraph->prune();
_rootStateGraph = previous_rootStateGraph;
_currentStateGraph = previous_currentStateGraph;