Fixed bug associated with complex RenderBin setup.
This commit is contained in:
parent
68a6882d04
commit
9db23e0b22
@ -125,6 +125,12 @@ class OSG_EXPORT State : public Referenced
|
||||
* Note, to return OpenGL to default state, one should do any state.popAllStatSets(); state.apply().*/
|
||||
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.*/
|
||||
unsigned int getStateSetStackSize() { return _stateStateStack.size(); }
|
||||
|
||||
|
@ -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:
|
||||
|
||||
/// disallow copy construction.
|
||||
|
@ -178,6 +178,7 @@ void State::setInitialViewMatrix(const osg::RefMatrix* matrix)
|
||||
|
||||
void State::pushStateSet(const StateSet* dstate)
|
||||
{
|
||||
|
||||
_stateStateStack.push_back(dstate);
|
||||
if (dstate)
|
||||
{
|
||||
@ -203,10 +204,14 @@ void State::pushStateSet(const StateSet* dstate)
|
||||
|
||||
pushUniformList(_uniformMap,dstate->getUniformList());
|
||||
}
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"State::pushStateSet()"<<_stateStateStack.size()<<std::endl;
|
||||
}
|
||||
|
||||
void State::popAllStateSets()
|
||||
{
|
||||
// osg::notify(osg::NOTICE)<<"State::popAllStateSets()"<<_stateStateStack.size()<<std::endl;
|
||||
|
||||
while (!_stateStateStack.empty()) popStateSet();
|
||||
|
||||
applyProjectionMatrix(0);
|
||||
@ -217,8 +222,11 @@ void State::popAllStateSets()
|
||||
|
||||
void State::popStateSet()
|
||||
{
|
||||
// osg::notify(osg::NOTICE)<<"State::popStateSet()"<<_stateStateStack.size()<<std::endl;
|
||||
|
||||
if (_stateStateStack.empty()) return;
|
||||
|
||||
|
||||
const StateSet* dstate = _stateStateStack.back();
|
||||
|
||||
if (dstate)
|
||||
@ -251,6 +259,58 @@ void State::popStateSet()
|
||||
_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
|
||||
{
|
||||
// empty the stateset first.
|
||||
|
@ -370,12 +370,31 @@ void RenderBin::draw(osg::RenderInfo& renderInfo,RenderLeaf*& previous)
|
||||
else drawImplementation(renderInfo,previous);
|
||||
}
|
||||
|
||||
#define NEW_STATECODE
|
||||
//#define OLD_STATECODE
|
||||
|
||||
void RenderBin::drawImplementation(osg::RenderInfo& renderInfo,RenderLeaf*& previous)
|
||||
{
|
||||
osg::State& state = *renderInfo.getState();
|
||||
|
||||
// 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();
|
||||
|
||||
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.
|
||||
state.pushStateSet(_stateset.get());
|
||||
state.apply();
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// draw first set of draw bins.
|
||||
RenderBinList::iterator rbitr;
|
||||
@ -457,12 +479,25 @@ void RenderBin::drawImplementation(osg::RenderInfo& renderInfo,RenderLeaf*& prev
|
||||
rbitr->second->draw(renderInfo,previous);
|
||||
}
|
||||
|
||||
#ifndef OLD_STATECODE
|
||||
#ifdef NEW_STATECODE
|
||||
|
||||
if (_stateset.valid())
|
||||
{
|
||||
state.removeStateSet(insertStateSetPosition);
|
||||
state.apply();
|
||||
}
|
||||
|
||||
#else
|
||||
if (stateSetStackSize!=state.getStateSetStackSize())
|
||||
{
|
||||
state.popStateSetStackToSize(stateSetStackSize);
|
||||
}
|
||||
|
||||
previous = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"end RenderBin::drawImplementation "<<className()<<std::endl;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user