2001-09-20 05:19:47 +08:00
|
|
|
#include <osg/State>
|
|
|
|
#include <osg/Notify>
|
|
|
|
|
2001-10-04 05:44:07 +08:00
|
|
|
#include <osg/GLU>
|
2001-09-20 05:19:47 +08:00
|
|
|
|
|
|
|
using namespace osg;
|
|
|
|
|
|
|
|
State::State()
|
|
|
|
{
|
|
|
|
_contextID = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
State::~State()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void State::reset()
|
|
|
|
{
|
2001-10-15 22:07:54 +08:00
|
|
|
/*
|
|
|
|
for(ModeMap::iterator mitr=_modeMap.begin();
|
|
|
|
mitr!=_modeMap.end();
|
|
|
|
++mitr)
|
|
|
|
{
|
|
|
|
ModeStack& ms = mitr->second;
|
|
|
|
ms.valueVec.clear();
|
|
|
|
ms.last_applied_value = !ms.global_default_value;
|
|
|
|
ms.changed = true;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
2001-09-20 05:19:47 +08:00
|
|
|
_modeMap.clear();
|
2001-10-15 22:07:54 +08:00
|
|
|
_modeMap[GL_DEPTH_TEST].global_default_value = true;
|
|
|
|
|
|
|
|
// go through all active StateAttribute's, applying where appropriate.
|
|
|
|
for(AttributeMap::iterator aitr=_attributeMap.begin();
|
|
|
|
aitr!=_attributeMap.end();
|
|
|
|
++aitr)
|
|
|
|
{
|
|
|
|
AttributeStack& as = aitr->second;
|
|
|
|
as.attributeVec.clear();
|
|
|
|
as.last_applied_attribute = NULL;
|
|
|
|
as.changed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// _attributeMap.clear();
|
|
|
|
|
2001-09-20 05:19:47 +08:00
|
|
|
_drawStateStack.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void State::pushStateSet(const StateSet* dstate)
|
|
|
|
{
|
|
|
|
_drawStateStack.push_back(dstate);
|
|
|
|
if (dstate)
|
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
// iterator through all OpenGL modes in incomming StateSet
|
|
|
|
// for each GLMode entry push it to the back of the appropriate
|
|
|
|
// mode stack, taking into consideration current override status.
|
|
|
|
const StateSet::ModeList& ds_modeList = dstate->getModeList();
|
|
|
|
for(StateSet::ModeList::const_iterator mitr=ds_modeList.begin();
|
|
|
|
mitr!=ds_modeList.end();
|
|
|
|
++mitr)
|
|
|
|
{
|
|
|
|
// get the mode stack for incomming GLmode {mitr->first}.
|
|
|
|
ModeStack& ms = _modeMap[mitr->first];
|
|
|
|
if (ms.valueVec.empty())
|
|
|
|
{
|
|
|
|
// first pair so simply push incomming pair to back.
|
|
|
|
ms.valueVec.push_back(mitr->second);
|
|
|
|
}
|
|
|
|
else if (ms.valueVec.back() & StateAttribute::OVERRIDE) // check the existing override flag
|
|
|
|
{
|
|
|
|
// push existing back since override keeps the previoius value.
|
|
|
|
ms.valueVec.push_back(ms.valueVec.back());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// no override on so simply push incomming pair to back.
|
|
|
|
ms.valueVec.push_back(mitr->second);
|
|
|
|
}
|
|
|
|
ms.changed = true;
|
|
|
|
}
|
|
|
|
|
2001-09-20 05:19:47 +08:00
|
|
|
// iterator through all StateAttribute's in incomming StateSet
|
|
|
|
// for each Type entry push it to the back of the appropriate
|
|
|
|
// attribute stack, taking into consideration current override status.
|
|
|
|
const StateSet::AttributeList& ds_attributeList = dstate->getAttributeList();
|
|
|
|
for(StateSet::AttributeList::const_iterator aitr=ds_attributeList.begin();
|
|
|
|
aitr!=ds_attributeList.end();
|
|
|
|
++aitr)
|
|
|
|
{
|
|
|
|
// get the attribute stack for incomming type {aitr->first}.
|
|
|
|
AttributeStack& as = _attributeMap[aitr->first];
|
|
|
|
if (as.attributeVec.empty())
|
|
|
|
{
|
|
|
|
// first pair so simply push incomming pair to back.
|
|
|
|
as.attributeVec.push_back(
|
|
|
|
AttributePair(aitr->second.first.get(),aitr->second.second));
|
|
|
|
}
|
|
|
|
else if (as.attributeVec.back().second & StateAttribute::OVERRIDE) // check the existing override flag
|
|
|
|
{
|
|
|
|
// push existing back since override keeps the previoius value.
|
|
|
|
as.attributeVec.push_back(as.attributeVec.back());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// no override on so simply push incomming pair to back.
|
|
|
|
as.attributeVec.push_back(
|
|
|
|
AttributePair(aitr->second.first.get(),aitr->second.second));
|
|
|
|
}
|
|
|
|
as.changed = true;
|
|
|
|
}
|
|
|
|
|
2002-01-17 05:23:29 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void State::popStateSet()
|
|
|
|
{
|
|
|
|
if (_drawStateStack.empty()) return;
|
|
|
|
|
|
|
|
const StateSet* dstate = _drawStateStack.back().get();
|
|
|
|
|
|
|
|
if (dstate)
|
|
|
|
{
|
2001-09-20 05:19:47 +08:00
|
|
|
|
2002-01-17 05:23:29 +08:00
|
|
|
// iterator through all OpenGL modes in incomming StateSet
|
|
|
|
// for each GLMode entry pop_back of the appropriate
|
|
|
|
// mode stack.
|
|
|
|
const StateSet::ModeList& ds_modeList = dstate->getModeList();
|
|
|
|
for(StateSet::ModeList::const_iterator mitr=ds_modeList.begin();
|
|
|
|
mitr!=ds_modeList.end();
|
|
|
|
++mitr)
|
|
|
|
{
|
|
|
|
// get the mode stack for incomming GLmode {mitr->first}.
|
|
|
|
ModeStack& ms = _modeMap[mitr->first];
|
|
|
|
if (!ms.valueVec.empty())
|
|
|
|
{
|
|
|
|
ms.valueVec.pop_back();
|
|
|
|
}
|
|
|
|
ms.changed = true;
|
|
|
|
}
|
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
// iterator through all StateAttribute's in incomming StateSet
|
|
|
|
// for each Type entry pop_back of the appropriate
|
|
|
|
// attribute stack.
|
|
|
|
const StateSet::AttributeList& ds_attributeList = dstate->getAttributeList();
|
|
|
|
for(StateSet::AttributeList::const_iterator aitr=ds_attributeList.begin();
|
|
|
|
aitr!=ds_attributeList.end();
|
|
|
|
++aitr)
|
|
|
|
{
|
|
|
|
// get the attribute stack for incomming type {aitr->first}.
|
|
|
|
AttributeStack& as = _attributeMap[aitr->first];
|
|
|
|
if (!as.attributeVec.empty())
|
|
|
|
{
|
|
|
|
as.attributeVec.pop_back();
|
|
|
|
}
|
|
|
|
as.changed = true;
|
|
|
|
}
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// remove the top draw state from the stack.
|
|
|
|
_drawStateStack.pop_back();
|
|
|
|
}
|
|
|
|
|
2001-10-23 06:02:47 +08:00
|
|
|
void State::captureCurrentState(StateSet& stateset) const
|
|
|
|
{
|
|
|
|
// empty the stateset first.
|
|
|
|
stateset.setAllToInherit();
|
|
|
|
|
|
|
|
for(ModeMap::const_iterator mitr=_modeMap.begin();
|
|
|
|
mitr!=_modeMap.end();
|
|
|
|
++mitr)
|
|
|
|
{
|
|
|
|
// note GLMode = mitr->first
|
|
|
|
const ModeStack& ms = mitr->second;
|
|
|
|
if (!ms.valueVec.empty())
|
|
|
|
{
|
|
|
|
stateset.setMode(mitr->first,ms.valueVec.back());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
for(AttributeMap::const_iterator aitr=_attributeMap.begin();
|
|
|
|
aitr!=_attributeMap.end();
|
|
|
|
++aitr)
|
|
|
|
{
|
|
|
|
const AttributeStack& as = aitr->second;
|
|
|
|
if (!as.attributeVec.empty())
|
|
|
|
{
|
|
|
|
stateset.setAttribute(const_cast<StateAttribute*>(as.attributeVec.back().first));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-10-23 06:02:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-09-20 05:19:47 +08:00
|
|
|
void State::apply(const StateSet* dstate)
|
|
|
|
{
|
|
|
|
// equivilant to:
|
|
|
|
//pushStateSet(dstate);
|
|
|
|
//apply();
|
|
|
|
//popStateSet();
|
|
|
|
|
|
|
|
if (dstate)
|
|
|
|
{
|
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
// then handle mode changes.
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
const StateSet::ModeList& ds_modeList = dstate->getModeList();
|
2001-09-20 05:19:47 +08:00
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
StateSet::ModeList::const_iterator ds_mitr = ds_modeList.begin();
|
|
|
|
ModeMap::iterator this_mitr=_modeMap.begin();
|
2001-09-20 05:19:47 +08:00
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
while (this_mitr!=_modeMap.end() && ds_mitr!=ds_modeList.end())
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
if (this_mitr->first<ds_mitr->first)
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
// note GLMode = this_mitr->first
|
|
|
|
ModeStack& ms = this_mitr->second;
|
|
|
|
if (ms.changed)
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
ms.changed = false;
|
|
|
|
if (!ms.valueVec.empty())
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
bool new_value = ms.valueVec.back() & StateAttribute::ON;
|
|
|
|
apply_mode(this_mitr->first,new_value,ms);
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
// assume default of disabled.
|
|
|
|
apply_mode(this_mitr->first,ms.global_default_value,ms);
|
|
|
|
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
2002-01-23 20:04:53 +08:00
|
|
|
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
++this_mitr;
|
2001-09-20 05:19:47 +08:00
|
|
|
|
|
|
|
}
|
2002-01-23 20:04:53 +08:00
|
|
|
else if (ds_mitr->first<this_mitr->first)
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
// ds_mitr->first is a new mode, therefore
|
|
|
|
// need to insert a new mode entry for ds_mistr->first.
|
|
|
|
ModeStack& ms = _modeMap[ds_mitr->first];
|
2001-09-20 05:19:47 +08:00
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
bool new_value = ds_mitr->second & StateAttribute::ON;
|
|
|
|
apply_mode(ds_mitr->first,new_value,ms);
|
2001-09-20 05:19:47 +08:00
|
|
|
|
|
|
|
// will need to disable this mode on next apply so set it to changed.
|
2002-01-23 20:04:53 +08:00
|
|
|
ms.changed = true;
|
2001-09-20 05:19:47 +08:00
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
++ds_mitr;
|
2001-09-20 05:19:47 +08:00
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// this_mitr & ds_mitr refer to the same mode, check the overide
|
|
|
|
// if any otherwise just apply the incomming mode.
|
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
ModeStack& ms = this_mitr->second;
|
2001-09-20 05:19:47 +08:00
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
if (!ms.valueVec.empty() && ms.valueVec.back() & StateAttribute::OVERRIDE)
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
// override is on, there just treat as a normal apply on modes.
|
2001-09-20 05:19:47 +08:00
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
if (ms.changed)
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
ms.changed = false;
|
|
|
|
bool new_value = ms.valueVec.back() & StateAttribute::ON;
|
|
|
|
apply_mode(this_mitr->first,new_value,ms);
|
|
|
|
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// no override on or no previous entry, therefore consider incomming mode.
|
2002-01-23 20:04:53 +08:00
|
|
|
bool new_value = ds_mitr->second & StateAttribute::ON;
|
|
|
|
if (apply_mode(ds_mitr->first,new_value,ms))
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
ms.changed = true;
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
++this_mitr;
|
|
|
|
++ds_mitr;
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// iterator over the remaining state modes to apply any previous changes.
|
|
|
|
for(;
|
2002-01-23 20:04:53 +08:00
|
|
|
this_mitr!=_modeMap.end();
|
|
|
|
++this_mitr)
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
// note GLMode = this_mitr->first
|
|
|
|
ModeStack& ms = this_mitr->second;
|
|
|
|
if (ms.changed)
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
ms.changed = false;
|
|
|
|
if (!ms.valueVec.empty())
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
bool new_value = ms.valueVec.back() & StateAttribute::ON;
|
|
|
|
apply_mode(this_mitr->first,new_value,ms);
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
// assume default of disabled.
|
|
|
|
apply_mode(this_mitr->first,ms.global_default_value,ms);
|
|
|
|
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
2002-01-23 20:04:53 +08:00
|
|
|
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// iterator over the remaining incomming modes to apply any new mode.
|
|
|
|
for(;
|
2002-01-23 20:04:53 +08:00
|
|
|
ds_mitr!=ds_modeList.end();
|
|
|
|
++ds_mitr)
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
ModeStack& ms = _modeMap[ds_mitr->first];
|
2001-09-20 05:19:47 +08:00
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
bool new_value = ds_mitr->second & StateAttribute::ON;
|
|
|
|
apply_mode(ds_mitr->first,new_value,ms);
|
2001-09-20 05:19:47 +08:00
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
// will need to disable this mode on next apply so set it to changed.
|
|
|
|
ms.changed = true;
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
// first handle attribute changes
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
const StateSet::AttributeList& ds_attributeList = dstate->getAttributeList();
|
|
|
|
StateSet::AttributeList::const_iterator ds_aitr=ds_attributeList.begin();
|
2001-09-20 05:19:47 +08:00
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
AttributeMap::iterator this_aitr=_attributeMap.begin();
|
2001-09-20 05:19:47 +08:00
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
while (this_aitr!=_attributeMap.end() && ds_aitr!=ds_attributeList.end())
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
if (this_aitr->first<ds_aitr->first)
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
// note attribute type = this_aitr->first
|
|
|
|
AttributeStack& as = this_aitr->second;
|
|
|
|
if (as.changed)
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
as.changed = false;
|
|
|
|
if (!as.attributeVec.empty())
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
const StateAttribute* new_attr = as.attributeVec.back().first;
|
|
|
|
apply_attribute(new_attr,as);
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
apply_global_default_attribute(as);
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
++this_aitr;
|
2001-09-20 05:19:47 +08:00
|
|
|
|
|
|
|
}
|
2002-01-23 20:04:53 +08:00
|
|
|
else if (ds_aitr->first<this_aitr->first)
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
// ds_mitr->first is a new attribute, therefore
|
|
|
|
// need to insert a new attribute entry for ds_aistr->first.
|
|
|
|
AttributeStack& as = _attributeMap[ds_aitr->first];
|
2001-09-20 05:19:47 +08:00
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
const StateAttribute* new_attr = ds_aitr->second.first.get();
|
|
|
|
apply_attribute(new_attr,as);
|
2001-09-20 05:19:47 +08:00
|
|
|
|
|
|
|
// will need to disable this mode on next apply so set it to changed.
|
2002-01-23 20:04:53 +08:00
|
|
|
as.changed = true;
|
2001-09-20 05:19:47 +08:00
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
++ds_aitr;
|
2001-09-20 05:19:47 +08:00
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// this_mitr & ds_mitr refer to the same mode, check the overide
|
|
|
|
// if any otherwise just apply the incomming mode.
|
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
AttributeStack& as = this_aitr->second;
|
2001-09-20 05:19:47 +08:00
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
if (!as.attributeVec.empty() && as.attributeVec.back().second)
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
// override is os, there just treat as a normal apply on modes.
|
2001-09-20 05:19:47 +08:00
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
if (as.changed)
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
as.changed = false;
|
|
|
|
const StateAttribute* new_attr = as.attributeVec.back().first;
|
|
|
|
apply_attribute(new_attr,as);
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// no override on or no previous entry, therefore consider incomming mode.
|
2002-01-23 20:04:53 +08:00
|
|
|
const StateAttribute* new_attr = ds_aitr->second.first.get();
|
|
|
|
if (apply_attribute(new_attr,as))
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
as.changed = true;
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
++this_aitr;
|
|
|
|
++ds_aitr;
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// iterator over the remaining state modes to apply any previous changes.
|
|
|
|
for(;
|
2002-01-23 20:04:53 +08:00
|
|
|
this_aitr!=_attributeMap.end();
|
|
|
|
++this_aitr)
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
// note attribute type = this_aitr->first
|
|
|
|
AttributeStack& as = this_aitr->second;
|
|
|
|
if (as.changed)
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
as.changed = false;
|
|
|
|
if (!as.attributeVec.empty())
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
const StateAttribute* new_attr = as.attributeVec.back().first;
|
|
|
|
apply_attribute(new_attr,as);
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
apply_global_default_attribute(as);
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// iterator over the remaining incomming modes to apply any new mode.
|
|
|
|
for(;
|
2002-01-23 20:04:53 +08:00
|
|
|
ds_aitr!=ds_attributeList.end();
|
|
|
|
++ds_aitr)
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
2002-01-23 20:04:53 +08:00
|
|
|
// ds_mitr->first is a new attribute, therefore
|
|
|
|
// need to insert a new attribute entry for ds_aistr->first.
|
|
|
|
AttributeStack& as = _attributeMap[ds_aitr->first];
|
2001-09-20 05:19:47 +08:00
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
const StateAttribute* new_attr = ds_aitr->second.first.get();
|
|
|
|
apply_attribute(new_attr,as);
|
2001-09-20 05:19:47 +08:00
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
// will need to update this attribute on next apply so set it to changed.
|
|
|
|
as.changed = true;
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-01-17 05:23:29 +08:00
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// no incomming stateset, so simply apply state.
|
|
|
|
apply();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void State::apply()
|
|
|
|
{
|
|
|
|
|
|
|
|
// go through all active OpenGL modes, enabling/disable where
|
|
|
|
// appropriate.
|
|
|
|
for(ModeMap::iterator mitr=_modeMap.begin();
|
|
|
|
mitr!=_modeMap.end();
|
|
|
|
++mitr)
|
|
|
|
{
|
|
|
|
// note GLMode = mitr->first
|
|
|
|
ModeStack& ms = mitr->second;
|
|
|
|
if (ms.changed)
|
|
|
|
{
|
|
|
|
ms.changed = false;
|
|
|
|
if (!ms.valueVec.empty())
|
|
|
|
{
|
|
|
|
bool new_value = ms.valueVec.back() & StateAttribute::ON;
|
|
|
|
apply_mode(mitr->first,new_value,ms);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// assume default of disabled.
|
2001-10-15 22:07:54 +08:00
|
|
|
apply_mode(mitr->first,ms.global_default_value,ms);
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-01-23 20:04:53 +08:00
|
|
|
|
|
|
|
// go through all active StateAttribute's, applying where appropriate.
|
|
|
|
for(AttributeMap::iterator aitr=_attributeMap.begin();
|
|
|
|
aitr!=_attributeMap.end();
|
|
|
|
++aitr)
|
|
|
|
{
|
|
|
|
AttributeStack& as = aitr->second;
|
|
|
|
if (as.changed)
|
|
|
|
{
|
|
|
|
as.changed = false;
|
|
|
|
if (!as.attributeVec.empty())
|
|
|
|
{
|
|
|
|
const StateAttribute* new_attr = as.attributeVec.back().first;
|
|
|
|
apply_attribute(new_attr,as);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
apply_global_default_attribute(as);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2001-09-20 05:19:47 +08:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/** mode has been set externally, update state to reflect this setting.*/
|
|
|
|
void State::have_applied(const StateAttribute::GLMode mode,const StateAttribute::GLModeValue value)
|
|
|
|
{
|
|
|
|
ModeStack& ms = _modeMap[mode];
|
|
|
|
|
|
|
|
ms.last_applied_value = value & StateAttribute::ON;
|
|
|
|
|
|
|
|
// will need to disable this mode on next apply so set it to changed.
|
|
|
|
ms.changed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** attribute has been applied externally, update state to reflect this setting.*/
|
|
|
|
void State::have_applied(const StateAttribute* attribute)
|
|
|
|
{
|
|
|
|
if (attribute)
|
|
|
|
{
|
|
|
|
AttributeStack& as = _attributeMap[attribute->getType()];
|
|
|
|
|
|
|
|
as.last_applied_attribute = attribute;
|
|
|
|
|
|
|
|
// will need to update this attribute on next apply so set it to changed.
|
|
|
|
as.changed = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|