Fixed bug associated with complex RenderBin setup.
This commit is contained in:
parent
68a6882d04
commit
9db23e0b22
@ -120,10 +120,16 @@ class OSG_EXPORT State : public Referenced
|
|||||||
|
|
||||||
/** Pop stateset off state stack.*/
|
/** Pop stateset off state stack.*/
|
||||||
void popStateSet();
|
void popStateSet();
|
||||||
|
|
||||||
/** pop all statesets off state stack, ensuring it is empty ready for the next frame.
|
/** pop all statesets off state stack, ensuring it is empty ready for the next frame.
|
||||||
* Note, to return OpenGL to default state, one should do any state.popAllStatSets(); state.apply().*/
|
* Note, to return OpenGL to default state, one should do any state.popAllStatSets(); state.apply().*/
|
||||||
void popAllStateSets();
|
void popAllStateSets();
|
||||||
|
|
||||||
|
/** Insert stateset onto state stack.*/
|
||||||
|
void insertStateSet(unsigned int pos,const StateSet* dstate);
|
||||||
|
|
||||||
|
/** Pop stateset off state stack.*/
|
||||||
|
void removeStateSet(unsigned int pos);
|
||||||
|
|
||||||
/** Get the number of StateSet's on the StateSet stack.*/
|
/** Get the number of StateSet's on the StateSet stack.*/
|
||||||
unsigned int getStateSetStackSize() { return _stateStateStack.size(); }
|
unsigned int getStateSetStackSize() { return _stateStateStack.size(); }
|
||||||
|
@ -46,7 +46,7 @@ class OSGUTIL_EXPORT StateGraph : public osg::Referenced
|
|||||||
typedef std::map< const osg::StateSet*, osg::ref_ptr<StateGraph> > ChildList;
|
typedef std::map< const osg::StateSet*, osg::ref_ptr<StateGraph> > ChildList;
|
||||||
typedef std::vector< osg::ref_ptr<RenderLeaf> > LeafList;
|
typedef std::vector< osg::ref_ptr<RenderLeaf> > LeafList;
|
||||||
|
|
||||||
StateGraph* _parent;
|
StateGraph* _parent;
|
||||||
const osg::StateSet* _stateset;
|
const osg::StateSet* _stateset;
|
||||||
|
|
||||||
int _depth;
|
int _depth;
|
||||||
@ -279,6 +279,19 @@ class OSGUTIL_EXPORT StateGraph : public osg::Referenced
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static int numToPop(osg::State& state,StateGraph* sg_curr)
|
||||||
|
{
|
||||||
|
int numToPop = 0;
|
||||||
|
// need to pop back all statesets and matrices.
|
||||||
|
while (sg_curr)
|
||||||
|
{
|
||||||
|
if (sg_curr->_stateset) ++numToPop;
|
||||||
|
sg_curr = sg_curr->_parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return numToPop;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/// disallow copy construction.
|
/// disallow copy construction.
|
||||||
|
@ -178,6 +178,7 @@ void State::setInitialViewMatrix(const osg::RefMatrix* matrix)
|
|||||||
|
|
||||||
void State::pushStateSet(const StateSet* dstate)
|
void State::pushStateSet(const StateSet* dstate)
|
||||||
{
|
{
|
||||||
|
|
||||||
_stateStateStack.push_back(dstate);
|
_stateStateStack.push_back(dstate);
|
||||||
if (dstate)
|
if (dstate)
|
||||||
{
|
{
|
||||||
@ -203,10 +204,14 @@ void State::pushStateSet(const StateSet* dstate)
|
|||||||
|
|
||||||
pushUniformList(_uniformMap,dstate->getUniformList());
|
pushUniformList(_uniformMap,dstate->getUniformList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// osg::notify(osg::NOTICE)<<"State::pushStateSet()"<<_stateStateStack.size()<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void State::popAllStateSets()
|
void State::popAllStateSets()
|
||||||
{
|
{
|
||||||
|
// osg::notify(osg::NOTICE)<<"State::popAllStateSets()"<<_stateStateStack.size()<<std::endl;
|
||||||
|
|
||||||
while (!_stateStateStack.empty()) popStateSet();
|
while (!_stateStateStack.empty()) popStateSet();
|
||||||
|
|
||||||
applyProjectionMatrix(0);
|
applyProjectionMatrix(0);
|
||||||
@ -217,8 +222,11 @@ void State::popAllStateSets()
|
|||||||
|
|
||||||
void State::popStateSet()
|
void State::popStateSet()
|
||||||
{
|
{
|
||||||
|
// osg::notify(osg::NOTICE)<<"State::popStateSet()"<<_stateStateStack.size()<<std::endl;
|
||||||
|
|
||||||
if (_stateStateStack.empty()) return;
|
if (_stateStateStack.empty()) return;
|
||||||
|
|
||||||
|
|
||||||
const StateSet* dstate = _stateStateStack.back();
|
const StateSet* dstate = _stateStateStack.back();
|
||||||
|
|
||||||
if (dstate)
|
if (dstate)
|
||||||
@ -251,6 +259,58 @@ void State::popStateSet()
|
|||||||
_stateStateStack.pop_back();
|
_stateStateStack.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void State::insertStateSet(unsigned int pos,const StateSet* dstate)
|
||||||
|
{
|
||||||
|
StateSetStack tempStack;
|
||||||
|
|
||||||
|
// first pop the StateSet above the position we need to insert at
|
||||||
|
while (_stateStateStack.size()>pos)
|
||||||
|
{
|
||||||
|
tempStack.push_back(_stateStateStack.back());
|
||||||
|
popStateSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
// push our new stateset
|
||||||
|
pushStateSet(dstate);
|
||||||
|
|
||||||
|
// push back the original ones
|
||||||
|
for(StateSetStack::reverse_iterator itr = tempStack.rbegin();
|
||||||
|
itr != tempStack.rend();
|
||||||
|
++itr)
|
||||||
|
{
|
||||||
|
pushStateSet(*itr);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void State::removeStateSet(unsigned int pos)
|
||||||
|
{
|
||||||
|
if (pos >= _stateStateStack.size())
|
||||||
|
{
|
||||||
|
osg::notify(osg::NOTICE)<<"Warning: State::removeStateSet("<<pos<<") out of range"<<std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// record the StateSet above the one we intend to remove
|
||||||
|
StateSetStack tempStack;
|
||||||
|
while (_stateStateStack.size()-1>pos)
|
||||||
|
{
|
||||||
|
tempStack.push_back(_stateStateStack.back());
|
||||||
|
popStateSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove the intended StateSet as well
|
||||||
|
popStateSet();
|
||||||
|
|
||||||
|
// push back the original ones that were above the remove StateSet
|
||||||
|
for(StateSetStack::reverse_iterator itr = tempStack.rbegin();
|
||||||
|
itr != tempStack.rend();
|
||||||
|
++itr)
|
||||||
|
{
|
||||||
|
pushStateSet(*itr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void State::captureCurrentState(StateSet& stateset) const
|
void State::captureCurrentState(StateSet& stateset) const
|
||||||
{
|
{
|
||||||
// empty the stateset first.
|
// empty the stateset first.
|
||||||
|
@ -370,12 +370,31 @@ void RenderBin::draw(osg::RenderInfo& renderInfo,RenderLeaf*& previous)
|
|||||||
else drawImplementation(renderInfo,previous);
|
else drawImplementation(renderInfo,previous);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define NEW_STATECODE
|
||||||
|
//#define OLD_STATECODE
|
||||||
|
|
||||||
void RenderBin::drawImplementation(osg::RenderInfo& renderInfo,RenderLeaf*& previous)
|
void RenderBin::drawImplementation(osg::RenderInfo& renderInfo,RenderLeaf*& previous)
|
||||||
{
|
{
|
||||||
osg::State& state = *renderInfo.getState();
|
osg::State& state = *renderInfo.getState();
|
||||||
|
|
||||||
// osg::notify(osg::NOTICE)<<"begin RenderBin::drawImplementation "<<className()<<" sortMode "<<getSortMode()<<std::endl;
|
// osg::notify(osg::NOTICE)<<"begin RenderBin::drawImplementation "<<className()<<" sortMode "<<getSortMode()<<std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef OLD_STATECODE
|
||||||
|
|
||||||
|
#ifdef NEW_STATECODE
|
||||||
|
|
||||||
|
unsigned int numToPop = (previous ? StateGraph::numToPop(state, previous->_parent) : 0);
|
||||||
|
if (numToPop>1) --numToPop;
|
||||||
|
unsigned int insertStateSetPosition = state.getStateSetStackSize() - numToPop;
|
||||||
|
|
||||||
|
if (_stateset.valid())
|
||||||
|
{
|
||||||
|
state.insertStateSet(insertStateSetPosition, _stateset.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
unsigned int stateSetStackSize = state.getStateSetStackSize();
|
unsigned int stateSetStackSize = state.getStateSetStackSize();
|
||||||
|
|
||||||
previous = 0;
|
previous = 0;
|
||||||
@ -386,8 +405,11 @@ void RenderBin::drawImplementation(osg::RenderInfo& renderInfo,RenderLeaf*& prev
|
|||||||
|
|
||||||
// now its safe to push RenderBin's StateSet as we now know its the root.
|
// now its safe to push RenderBin's StateSet as we now know its the root.
|
||||||
state.pushStateSet(_stateset.get());
|
state.pushStateSet(_stateset.get());
|
||||||
|
state.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// draw first set of draw bins.
|
// draw first set of draw bins.
|
||||||
RenderBinList::iterator rbitr;
|
RenderBinList::iterator rbitr;
|
||||||
@ -457,12 +479,25 @@ void RenderBin::drawImplementation(osg::RenderInfo& renderInfo,RenderLeaf*& prev
|
|||||||
rbitr->second->draw(renderInfo,previous);
|
rbitr->second->draw(renderInfo,previous);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef OLD_STATECODE
|
||||||
|
#ifdef NEW_STATECODE
|
||||||
|
|
||||||
|
if (_stateset.valid())
|
||||||
|
{
|
||||||
|
state.removeStateSet(insertStateSetPosition);
|
||||||
|
state.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
if (stateSetStackSize!=state.getStateSetStackSize())
|
if (stateSetStackSize!=state.getStateSetStackSize())
|
||||||
{
|
{
|
||||||
state.popStateSetStackToSize(stateSetStackSize);
|
state.popStateSetStackToSize(stateSetStackSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
previous = 0;
|
previous = 0;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// osg::notify(osg::NOTICE)<<"end RenderBin::drawImplementation "<<className()<<std::endl;
|
// osg::notify(osg::NOTICE)<<"end RenderBin::drawImplementation "<<className()<<std::endl;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user