/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace osg; // local class to help porting from OSG0.8.x to 0.9.x class TextureGLModeSet { public: TextureGLModeSet() { _textureModeSet.insert(GL_TEXTURE_1D); _textureModeSet.insert(GL_TEXTURE_2D); _textureModeSet.insert(GL_TEXTURE_3D); _textureModeSet.insert(GL_TEXTURE_CUBE_MAP); _textureModeSet.insert(GL_TEXTURE_RECTANGLE_NV); _textureModeSet.insert(GL_TEXTURE_GEN_Q); _textureModeSet.insert(GL_TEXTURE_GEN_R); _textureModeSet.insert(GL_TEXTURE_GEN_S); _textureModeSet.insert(GL_TEXTURE_GEN_T); } bool isTextureMode(StateAttribute::GLMode mode) const { return _textureModeSet.find(mode)!=_textureModeSet.end(); } protected: std::set _textureModeSet; }; TextureGLModeSet s_textureGLModeSet; StateSet::StateSet() { setDataVariance(osg::StateAttribute::STATIC); _renderingHint = DEFAULT_BIN; setRenderBinToInherit(); } StateSet::StateSet(const StateSet& rhs,const CopyOp& copyop):Object(rhs,copyop) { _modeList = rhs._modeList; for(AttributeList::const_iterator itr=rhs._attributeList.begin(); itr!=rhs._attributeList.end(); ++itr) { const StateAttribute::TypeMemberPair& typemember = itr->first; const RefAttributePair& rap = itr->second; StateAttribute* attr = copyop(rap.first.get()); if (attr) _attributeList[typemember]=RefAttributePair(attr,rap.second); } // copy texture related modes. _textureModeList = rhs._textureModeList; // set up the size of the texture attribute list. _textureAttributeList.resize(rhs._textureAttributeList.size()); // copy the contents across. for(unsigned int i=0;ifirst; const RefAttributePair& rap = itr->second; StateAttribute* attr = copyop(rap.first.get()); if (attr) lhs_attributeList[typemember]=RefAttributePair(attr,rap.second); } } #if 0 //[ TODO // copy uniform values for(UniformList::const_iterator rhs_uitr = rhs._uniformList.begin(); rhs_uitr != rhs._uniformList.end(); ++rhs_uitr) { const std::string& name = rhs_uitr->first; const RefUniformPair& rup = rhs_uitr->second; Uniform* uni = copyop(rup.first.get()); if( uni ) _uniformList[name] = RefUniformPair(uni, rup.second); } Program* prog = copyop( rhs._program ); if( prog ) _program = prog; #endif //] _renderingHint = rhs._renderingHint; _binMode = rhs._binMode; _binNum = rhs._binNum; _binName = rhs._binName; } StateSet::~StateSet() { // note, all attached state attributes will be automatically // unreferenced by ref_ptr<> and therefore there is no need to // delete the memory manually. } int StateSet::compare(const StateSet& rhs,bool compareAttributeContents) const { if (_textureAttributeList.size()rhs._textureAttributeList.size()) return 1; for(unsigned int ai=0;ai<_textureAttributeList.size();++ai) { const AttributeList& rhs_attributeList = _textureAttributeList[ai]; const AttributeList& lhs_attributeList = rhs._textureAttributeList[ai]; if (compareAttributeContents) { // now check to see how the attributes compare. AttributeList::const_iterator lhs_attr_itr = lhs_attributeList.begin(); AttributeList::const_iterator rhs_attr_itr = rhs_attributeList.begin(); while (lhs_attr_itr!=lhs_attributeList.end() && rhs_attr_itr!=rhs_attributeList.end()) { if (lhs_attr_itr->firstfirst) return -1; else if (rhs_attr_itr->firstfirst) return 1; if (*(lhs_attr_itr->second.first)<*(rhs_attr_itr->second.first)) return -1; else if (*(rhs_attr_itr->second.first)<*(lhs_attr_itr->second.first)) return 1; if (lhs_attr_itr->second.secondsecond.second) return -1; else if (rhs_attr_itr->second.secondsecond.second) return 1; ++lhs_attr_itr; ++rhs_attr_itr; } if (lhs_attr_itr==lhs_attributeList.end()) { if (rhs_attr_itr!=rhs_attributeList.end()) return -1; } else if (rhs_attr_itr == rhs_attributeList.end()) return 1; } else // just compare pointers. { // now check to see how the attributes compare. AttributeList::const_iterator lhs_attr_itr = lhs_attributeList.begin(); AttributeList::const_iterator rhs_attr_itr = rhs_attributeList.begin(); while (lhs_attr_itr!=lhs_attributeList.end() && rhs_attr_itr!=rhs_attributeList.end()) { if (lhs_attr_itr->firstfirst) return -1; else if (rhs_attr_itr->firstfirst) return 1; if (lhs_attr_itr->second.firstsecond.first) return -1; else if (rhs_attr_itr->second.firstsecond.first) return 1; if (lhs_attr_itr->second.secondsecond.second) return -1; else if (rhs_attr_itr->second.secondsecond.second) return 1; ++lhs_attr_itr; ++rhs_attr_itr; } if (lhs_attr_itr==lhs_attributeList.end()) { if (rhs_attr_itr!=rhs_attributeList.end()) return -1; } else if (rhs_attr_itr == rhs_attributeList.end()) return 1; } } // now check the rest of the non texture attributes if (compareAttributeContents) { // now check to see how the attributes compare. AttributeList::const_iterator lhs_attr_itr = _attributeList.begin(); AttributeList::const_iterator rhs_attr_itr = rhs._attributeList.begin(); while (lhs_attr_itr!=_attributeList.end() && rhs_attr_itr!=rhs._attributeList.end()) { if (lhs_attr_itr->firstfirst) return -1; else if (rhs_attr_itr->firstfirst) return 1; if (*(lhs_attr_itr->second.first)<*(rhs_attr_itr->second.first)) return -1; else if (*(rhs_attr_itr->second.first)<*(lhs_attr_itr->second.first)) return 1; if (lhs_attr_itr->second.secondsecond.second) return -1; else if (rhs_attr_itr->second.secondsecond.second) return 1; ++lhs_attr_itr; ++rhs_attr_itr; } if (lhs_attr_itr==_attributeList.end()) { if (rhs_attr_itr!=rhs._attributeList.end()) return -1; } else if (rhs_attr_itr == rhs._attributeList.end()) return 1; } else // just compare pointers. { // now check to see how the attributes compare. AttributeList::const_iterator lhs_attr_itr = _attributeList.begin(); AttributeList::const_iterator rhs_attr_itr = rhs._attributeList.begin(); while (lhs_attr_itr!=_attributeList.end() && rhs_attr_itr!=rhs._attributeList.end()) { if (lhs_attr_itr->firstfirst) return -1; else if (rhs_attr_itr->firstfirst) return 1; if (lhs_attr_itr->second.firstsecond.first) return -1; else if (rhs_attr_itr->second.firstsecond.first) return 1; if (lhs_attr_itr->second.secondsecond.second) return -1; else if (rhs_attr_itr->second.secondsecond.second) return 1; ++lhs_attr_itr; ++rhs_attr_itr; } if (lhs_attr_itr==_attributeList.end()) { if (rhs_attr_itr!=rhs._attributeList.end()) return -1; } else if (rhs_attr_itr == rhs._attributeList.end()) return 1; } // we've got here so attributes must be equal... if (_textureModeList.size()rhs._textureModeList.size()) return 1; // check to see how the modes compare. // first check the rest of the texture modes for(unsigned int ti=0;ti<_textureModeList.size();++ti) { const ModeList& lhs_modeList = _textureModeList[ti]; const ModeList& rhs_modeList = rhs._textureModeList[ti]; ModeList::const_iterator lhs_mode_itr = lhs_modeList.begin(); ModeList::const_iterator rhs_mode_itr = rhs_modeList.begin(); while (lhs_mode_itr!=lhs_modeList.end() && rhs_mode_itr!=rhs_modeList.end()) { if (lhs_mode_itr->firstfirst) return -1; else if (rhs_mode_itr->firstfirst) return 1; if (lhs_mode_itr->secondsecond) return -1; else if (rhs_mode_itr->secondsecond) return 1; ++lhs_mode_itr; ++rhs_mode_itr; } if (lhs_mode_itr==lhs_modeList.end()) { if (rhs_mode_itr!=rhs_modeList.end()) return -1; } else if (rhs_mode_itr == rhs_modeList.end()) return 1; } // check non texture modes. ModeList::const_iterator lhs_mode_itr = _modeList.begin(); ModeList::const_iterator rhs_mode_itr = rhs._modeList.begin(); while (lhs_mode_itr!=_modeList.end() && rhs_mode_itr!=rhs._modeList.end()) { if (lhs_mode_itr->firstfirst) return -1; else if (rhs_mode_itr->firstfirst) return 1; if (lhs_mode_itr->secondsecond) return -1; else if (rhs_mode_itr->secondsecond) return 1; ++lhs_mode_itr; ++rhs_mode_itr; } if (lhs_mode_itr==_modeList.end()) { if (rhs_mode_itr!=rhs._modeList.end()) return -1; } else if (rhs_mode_itr == rhs._modeList.end()) return 1; // check uniforms. UniformList::const_iterator lhs_uniform_itr = _uniformList.begin(); UniformList::const_iterator rhs_uniform_itr = rhs._uniformList.begin(); while (lhs_uniform_itr!=_uniformList.end() && rhs_uniform_itr!=rhs._uniformList.end()) { if (lhs_uniform_itr->firstfirst) return -1; else if (rhs_uniform_itr->firstfirst) return 1; if (lhs_uniform_itr->secondsecond) return -1; else if (rhs_uniform_itr->secondsecond) return 1; ++lhs_uniform_itr; ++rhs_uniform_itr; } if (lhs_uniform_itr==_uniformList.end()) { if (rhs_uniform_itr!=rhs._uniformList.end()) return -1; } else if (rhs_uniform_itr == rhs._uniformList.end()) return 1; if (_program.valid()) { if (rhs._program.valid()) { int result = _program->compare(*rhs._program); if (result!=0) return result; } else return 1; } else if (rhs._program.valid()) return -1; return 0; } int StateSet::compareModes(const ModeList& lhs,const ModeList& rhs) { ModeList::const_iterator lhs_mode_itr = lhs.begin(); ModeList::const_iterator rhs_mode_itr = rhs.begin(); while (lhs_mode_itr!=lhs.end() && rhs_mode_itr!=rhs.end()) { if (lhs_mode_itr->firstfirst) return -1; else if (rhs_mode_itr->firstfirst) return 1; if (lhs_mode_itr->secondsecond) return -1; else if (rhs_mode_itr->secondsecond) return 1; ++lhs_mode_itr; ++rhs_mode_itr; } if (lhs_mode_itr==lhs.end()) { if (rhs_mode_itr!=rhs.end()) return -1; } else if (rhs_mode_itr == rhs.end()) return 1; return 0; } int StateSet::compareAttributePtrs(const AttributeList& lhs,const AttributeList& rhs) { AttributeList::const_iterator lhs_attr_itr = lhs.begin(); AttributeList::const_iterator rhs_attr_itr = rhs.begin(); while (lhs_attr_itr!=lhs.end() && rhs_attr_itr!=rhs.end()) { if (lhs_attr_itr->firstfirst) return -1; else if (rhs_attr_itr->firstfirst) return 1; if (lhs_attr_itr->second.firstsecond.first) return -1; else if (rhs_attr_itr->second.firstsecond.first) return 1; if (lhs_attr_itr->second.secondsecond.second) return -1; else if (rhs_attr_itr->second.secondsecond.second) return 1; ++lhs_attr_itr; ++rhs_attr_itr; } if (lhs_attr_itr==lhs.end()) { if (rhs_attr_itr!=rhs.end()) return -1; } else if (rhs_attr_itr == rhs.end()) return 1; return 0; } int StateSet::compareAttributeContents(const AttributeList& lhs,const AttributeList& rhs) { AttributeList::const_iterator lhs_attr_itr = lhs.begin(); AttributeList::const_iterator rhs_attr_itr = rhs.begin(); while (lhs_attr_itr!=lhs.end() && rhs_attr_itr!=rhs.end()) { if (lhs_attr_itr->firstfirst) return -1; else if (rhs_attr_itr->firstfirst) return 1; if (*(lhs_attr_itr->second.first)<*(rhs_attr_itr->second.first)) return -1; else if (*(rhs_attr_itr->second.first)<*(lhs_attr_itr->second.first)) return 1; if (lhs_attr_itr->second.secondsecond.second) return -1; else if (rhs_attr_itr->second.secondsecond.second) return 1; ++lhs_attr_itr; ++rhs_attr_itr; } if (lhs_attr_itr==lhs.end()) { if (rhs_attr_itr!=rhs.end()) return -1; } else if (rhs_attr_itr == rhs.end()) return 1; return 0; } void StateSet::setGlobalDefaults() { _renderingHint = DEFAULT_BIN; setRenderBinToInherit(); setMode(GL_DEPTH_TEST,StateAttribute::ON); setAttributeAndModes(new AlphaFunc,StateAttribute::OFF); setAttributeAndModes(new BlendFunc,StateAttribute::OFF); Material *material = new Material; material->setColorMode(Material::AMBIENT_AND_DIFFUSE); setAttributeAndModes(material,StateAttribute::ON); } void StateSet::clear() { _renderingHint = DEFAULT_BIN; setRenderBinToInherit(); _modeList.clear(); _attributeList.clear(); _textureModeList.clear(); _textureAttributeList.clear(); _uniformList.clear(); _program = 0; } void StateSet::merge(const StateSet& rhs) { // merge the modes of rhs into this, // this overrides rhs if OVERRIDE defined in this. for(ModeList::const_iterator rhs_mitr = rhs._modeList.begin(); rhs_mitr != rhs._modeList.end(); ++rhs_mitr) { ModeList::iterator lhs_mitr = _modeList.find(rhs_mitr->first); if (lhs_mitr!=_modeList.end()) { if (!(lhs_mitr->second & StateAttribute::OVERRIDE)) { // override isn't on in rhs, so overrite it with incomming // value. lhs_mitr->second = rhs_mitr->second; } } else { // entry doesn't exist so insert it. _modeList.insert(*rhs_mitr); } } // merge the attributes of rhs into this, // this overrides rhs if OVERRIDE defined in this. for(AttributeList::const_iterator rhs_aitr = rhs._attributeList.begin(); rhs_aitr != rhs._attributeList.end(); ++rhs_aitr) { AttributeList::iterator lhs_aitr = _attributeList.find(rhs_aitr->first); if (lhs_aitr!=_attributeList.end()) { if (!(lhs_aitr->second.second & StateAttribute::OVERRIDE)) { // override isn't on in rhs, so overrite it with incomming // value. lhs_aitr->second = rhs_aitr->second; } } else { // entry doesn't exist so insert it. _attributeList.insert(*rhs_aitr); } } if (_textureModeList.size()first); if (lhs_mitr!=lhs_modeList.end()) { if (!(lhs_mitr->second & StateAttribute::OVERRIDE)) { // override isn't on in rhs, so overrite it with incomming // value. lhs_mitr->second = rhs_mitr->second; } } else { // entry doesn't exist so insert it. lhs_modeList.insert(*rhs_mitr); } } } if (_textureAttributeList.size()first); if (lhs_aitr!=lhs_attributeList.end()) { if (!(lhs_aitr->second.second & StateAttribute::OVERRIDE)) { // override isn't on in rhs, so overrite it with incomming // value. lhs_aitr->second = rhs_aitr->second; } } else { // entry doesn't exist so insert it. lhs_attributeList.insert(*rhs_aitr); } } } // merge the uniforms of rhs into this, // this overrides rhs if OVERRIDE defined in this. for(UniformList::const_iterator rhs_uitr = rhs._uniformList.begin(); rhs_uitr != rhs._uniformList.end(); ++rhs_uitr) { UniformList::iterator lhs_uitr = _uniformList.find(rhs_uitr->first); if (lhs_uitr!=_uniformList.end()) { if (!(lhs_uitr->second.second & StateAttribute::OVERRIDE)) { // override isn't on in rhs, so overrite it with incomming // value. lhs_uitr->second = rhs_uitr->second; } } else { // entry doesn't exist so insert it. _uniformList.insert(*rhs_uitr); } } // need to merge rendering hints // but will need to think how best to do this first // RO, Nov. 2001. } void StateSet::setMode(StateAttribute::GLMode mode, StateAttribute::GLModeValue value) { if (!s_textureGLModeSet.isTextureMode(mode)) { setMode(_modeList,mode,value); } else { notify(NOTICE)<<"Warning: texture mode '"<isTextureAttribute()) { setAttribute(_attributeList,attribute,value); } else { notify(NOTICE)<<"Warning: texture attribute '"<className()<<"'passed to setAttribute(attr,value), "<isTextureAttribute()) { if (value&StateAttribute::INHERIT) { removeAttribute(attribute->getType()); } else { setAttribute(_attributeList,attribute,value); setAssociatedModes(attribute,value); } } else { notify(NOTICE)<<"Warning: texture attribute '"<className()<<"' passed to setAttributeAndModes(attr,value), "<second.first.get(),StateAttribute::INHERIT); _attributeList.erase(itr); } } void StateSet::removeAttribute(StateAttribute* attribute) { if (!attribute) return; AttributeList::iterator itr = _attributeList.find(attribute->getTypeMemberPair()); if (itr!=_attributeList.end()) { if (itr->second.first != attribute) return; setAssociatedModes(itr->second.first.get(),StateAttribute::INHERIT); _attributeList.erase(itr); } } StateAttribute* StateSet::getAttribute(StateAttribute::Type type, unsigned int member) { return getAttribute(_attributeList,type,member); } const StateAttribute* StateSet::getAttribute(StateAttribute::Type type, unsigned int member) const { return getAttribute(_attributeList,type,member); } const StateSet::RefAttributePair* StateSet::getAttributePair(StateAttribute::Type type, unsigned int member) const { return getAttributePair(_attributeList,type,member); } void StateSet::addUniform(Uniform* uniform, StateAttribute::OverrideValue value) { if (uniform) { RefUniformPair& up = _uniformList[uniform->getName()]; up.first = uniform; up.second = value; } } void StateSet::removeUniform(const std::string& name) { UniformList::iterator itr = _uniformList.find(name); if (itr!=_uniformList.end()) { _uniformList.erase(itr); } } void StateSet::removeUniform(Uniform* uniform) { if (!uniform) return; UniformList::iterator itr = _uniformList.find(uniform->getName()); if (itr!=_uniformList.end()) { if (itr->second.first != uniform) return; _uniformList.erase(itr); } } Uniform* StateSet::getUniform(const std::string& name) { UniformList::iterator itr = _uniformList.find(name); if (itr!=_uniformList.end()) return itr->second.first.get(); else return 0; } const Uniform* StateSet::getUniform(const std::string& name) const { UniformList::const_iterator itr = _uniformList.find(name); if (itr!=_uniformList.end()) return itr->second.first.get(); else return 0; } const StateSet::RefUniformPair* StateSet::getUniformPair(const std::string& name) const { UniformList::const_iterator itr = _uniformList.find(name); if (itr!=_uniformList.end()) return &(itr->second); else return 0; } void StateSet::setTextureMode(unsigned int unit,StateAttribute::GLMode mode, StateAttribute::GLModeValue value) { if (s_textureGLModeSet.isTextureMode(mode)) { setMode(getOrCreateTextureModeList(unit),mode,value); } else { notify(NOTICE)<<"Warning: non-texture mode '"<=_textureModeList.size()) return; setModeToInherit(_textureModeList[unit],mode); } else { notify(NOTICE)<<"Warning: non-texture mode '"<=_textureModeList.size()) return StateAttribute::INHERIT; return getMode(_textureModeList[unit],mode); } else { notify(NOTICE)<<"Warning: non-texture mode '"<isTextureAttribute()) { setAttribute(getOrCreateTextureAttributeList(unit),attribute,value); } else { notify(NOTICE)<<"Warning: texture attribute '"<className()<<"' passed to setTextureAttribute(unit,attr,value), "<isTextureAttribute()) { if (value&StateAttribute::INHERIT) { removeTextureAttribute(unit,attribute->getType()); } else { setAttribute(getOrCreateTextureAttributeList(unit),attribute,value); setAssociatedTextureModes(unit,attribute,value); } } else { notify(NOTICE)<<"Warning: non texture attribute '"<className()<<"' passed to setTextureAttributeAndModes(unit,attr,value), "<=_textureAttributeList.size()) return; AttributeList& attributeList = _textureAttributeList[unit]; AttributeList::iterator itr = attributeList.find(StateAttribute::TypeMemberPair(type,0)); if (itr!=attributeList.end()) { if (unit<_textureModeList.size()) { setAssociatedTextureModes(unit,itr->second.first.get(),StateAttribute::INHERIT); } attributeList.erase(itr); } } void StateSet::removeTextureAttribute(unsigned int unit, StateAttribute* attribute) { if (!attribute) return; if (unit>=_textureAttributeList.size()) return; AttributeList& attributeList = _textureAttributeList[unit]; AttributeList::iterator itr = attributeList.find(attribute->getTypeMemberPair()); if (itr!=attributeList.end()) { if (itr->second.first != attribute) return; setAssociatedTextureModes(unit,itr->second.first.get(),StateAttribute::INHERIT); attributeList.erase(itr); } } StateAttribute* StateSet::getTextureAttribute(unsigned int unit,StateAttribute::Type type) { if (unit>=_textureAttributeList.size()) return 0; return getAttribute(_textureAttributeList[unit],type,0); } const StateAttribute* StateSet::getTextureAttribute(unsigned int unit,StateAttribute::Type type) const { if (unit>=_textureAttributeList.size()) return 0; return getAttribute(_textureAttributeList[unit],type,0); } const StateSet::RefAttributePair* StateSet::getTextureAttributePair(unsigned int unit,StateAttribute::Type type) const { if (unit>=_textureAttributeList.size()) return 0; return getAttributePair(_textureAttributeList[unit],type,0); } void StateSet::compileGLObjects(State& state) const { for(AttributeList::const_iterator itr = _attributeList.begin(); itr!=_attributeList.end(); ++itr) { itr->second.first->compileGLObjects(state); } for(TextureAttributeList::const_iterator taitr=_textureAttributeList.begin(); taitr!=_textureAttributeList.end(); ++taitr) { for(AttributeList::const_iterator itr = taitr->begin(); itr!=taitr->end(); ++itr) { itr->second.first->compileGLObjects(state); } } } void StateSet::releaseGLObjects(State* state) const { for(AttributeList::const_iterator itr = _attributeList.begin(); itr!=_attributeList.end(); ++itr) { itr->second.first->releaseGLObjects(state); } for(TextureAttributeList::const_iterator taitr=_textureAttributeList.begin(); taitr!=_textureAttributeList.end(); ++taitr) { for(AttributeList::const_iterator itr = taitr->begin(); itr!=taitr->end(); ++itr) { itr->second.first->releaseGLObjects(state); } } } void StateSet::setRenderingHint(int hint) { _renderingHint = hint; // temporary hack to get new render bins working. switch(_renderingHint) { case(TRANSPARENT_BIN): { _binMode = USE_RENDERBIN_DETAILS; _binNum = 10; _binName = "DepthSortedBin"; break; } case(OPAQUE_BIN): { _binMode = USE_RENDERBIN_DETAILS; _binNum = 0; _binName = "RenderBin"; break; } default: // DEFAULT_BIN { setRenderBinToInherit(); break; } } } void StateSet::setRenderBinDetails(int binNum,const std::string& binName,RenderBinMode mode) { _binMode = mode; _binNum = binNum; _binName = binName; } void StateSet::setRenderBinToInherit() { _binMode = INHERIT_RENDERBIN_DETAILS; _binNum = 0; _binName = ""; } void StateSet::setMode(ModeList& modeList,StateAttribute::GLMode mode, StateAttribute::GLModeValue value) { if ((value&StateAttribute::INHERIT)) setModeToInherit(modeList,mode); else modeList[mode] = value; } void StateSet::setModeToInherit(ModeList& modeList,StateAttribute::GLMode mode) { ModeList::iterator itr = modeList.find(mode); if (itr!=modeList.end()) { modeList.erase(itr); } } StateAttribute::GLModeValue StateSet::getMode(const ModeList& modeList,StateAttribute::GLMode mode) const { ModeList::const_iterator itr = modeList.find(mode); if (itr!=modeList.end()) { return itr->second; } else return StateAttribute::INHERIT; } class SetAssociateModesHelper : public StateAttribute::ModeUsage { public: SetAssociateModesHelper(StateSet* stateset, StateAttribute::GLModeValue value,unsigned int unit=0): _stateset(stateset), _value(value), _unit(unit) {} virtual ~SetAssociateModesHelper() {} virtual void usesMode(StateAttribute::GLMode mode) { _stateset->setMode(mode,_value); } virtual void usesTextureMode(StateAttribute::GLMode mode) { _stateset->setTextureMode(_unit,mode,_value); } StateSet* _stateset; StateAttribute::GLModeValue _value; unsigned int _unit; }; void StateSet::setAssociatedModes(const StateAttribute* attribute, StateAttribute::GLModeValue value) { SetAssociateModesHelper helper(this,value); attribute->getModeUsage(helper); } void StateSet::setAssociatedTextureModes(unsigned int unit,const StateAttribute* attribute, StateAttribute::GLModeValue value) { SetAssociateModesHelper helper(this,value,unit); attribute->getModeUsage(helper); } void StateSet::setAttribute(AttributeList& attributeList,StateAttribute *attribute, const StateAttribute::OverrideValue value) { if (attribute) { attributeList[attribute->getTypeMemberPair()] = RefAttributePair(attribute,value&(StateAttribute::OVERRIDE|StateAttribute::PROTECTED)); } } StateAttribute* StateSet::getAttribute(AttributeList& attributeList,StateAttribute::Type type, unsigned int member) { AttributeList::iterator itr = attributeList.find(StateAttribute::TypeMemberPair(type,member)); if (itr!=attributeList.end()) { return itr->second.first.get(); } else return NULL; } const StateAttribute* StateSet::getAttribute(const AttributeList& attributeList,StateAttribute::Type type, unsigned int member) const { AttributeList::const_iterator itr = attributeList.find(StateAttribute::TypeMemberPair(type,member)); if (itr!=attributeList.end()) { return itr->second.first.get(); } else return NULL; } const StateSet::RefAttributePair* StateSet::getAttributePair(const AttributeList& attributeList,StateAttribute::Type type, unsigned int member) const { AttributeList::const_iterator itr = attributeList.find(StateAttribute::TypeMemberPair(type,member)); if (itr!=attributeList.end()) { return &(itr->second); } else return NULL; }