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.

This commit is contained in:
Robert Osfield 2018-05-18 10:00:10 +01:00
parent 41f7efbab6
commit a4c8804b1b
2 changed files with 43 additions and 2 deletions

View File

@ -73,6 +73,9 @@ class OSGUTIL_EXPORT RenderBin : public osg::Object
virtual void reset(); virtual void reset();
void setStateGraph(StateGraph* sg) { _rootStateGraph = sg; }
StateGraph* getStateGraph() { return _rootStateGraph.get(); }
void setStateSet(osg::StateSet* stateset) { _stateset = stateset; } void setStateSet(osg::StateSet* stateset) { _stateset = stateset; }
osg::StateSet* getStateSet() { return _stateset.get(); } osg::StateSet* getStateSet() { return _stateset.get(); }
const osg::StateSet* getStateSet() const { return _stateset.get(); } const osg::StateSet* getStateSet() const { return _stateset.get(); }
@ -157,6 +160,8 @@ class OSGUTIL_EXPORT RenderBin : public osg::Object
virtual ~RenderBin(); virtual ~RenderBin();
osg::ref_ptr<StateGraph> _rootStateGraph;
int _binNum; int _binNum;
RenderBin* _parent; RenderBin* _parent;
RenderStage* _stage; RenderStage* _stage;

View File

@ -1569,13 +1569,41 @@ void CullVisitor::apply(osg::Camera& camera)
} }
else else
{ {
// cache the StateGraph and replace with a clone of the exisitng 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 all are kept local the 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. // set up lighting.
// currently ignore lights in the scene graph itself.. // currently ignore lights in the scene graph itself..
// will do later. // will do later.
osgUtil::RenderStage* previous_stage = getCurrentRenderBin()->getStage(); osgUtil::RenderStage* previous_stage = getCurrentRenderBin()->getStage();
// unsigned int contextID = getState() ? getState()->getContextID() : 0;
// use render to texture stage. // use render to texture stage.
// create the render to texture stage. // create the render to texture stage.
osg::ref_ptr<osgUtil::RenderStageCache> rsCache = dynamic_cast<osgUtil::RenderStageCache*>(camera.getRenderingCache()); osg::ref_ptr<osgUtil::RenderStageCache> rsCache = dynamic_cast<osgUtil::RenderStageCache*>(camera.getRenderingCache());
@ -1621,6 +1649,9 @@ void CullVisitor::apply(osg::Camera& camera)
rtts->reset(); 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 // set up clear masks/values
rtts->setClearDepth(camera.getClearDepth()); rtts->setClearDepth(camera.getClearDepth());
rtts->setClearAccum(camera.getClearAccum()); 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 // and the render to texture stage to the current stages
// dependency list. // dependency list.
switch(camera.getRenderOrder()) switch(camera.getRenderOrder())