OpenSceneGraph/src/osg/StateSet.cpp
Robert Osfield 7883574d28 From Mike Weiblen,
"updates for GLSL core integration:
Code compiles and runs on win32.
Basic functionality of Program and Shader in place.
Program derived from StateAttribute.
Uniform value propagation is not yet functional (in development)
Includes some patches by Nathan Cournia.
includes example testcase to demo use of new classes."
2005-03-24 09:37:45 +00:00

1103 lines
37 KiB
C++

/* -*-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 <stdio.h>
#include <osg/StateSet>
#include <osg/State>
#include <osg/Notify>
#include <osg/AlphaFunc>
#include <osg/Material>
#include <osg/CullFace>
#include <osg/FrontFace>
#include <osg/PolygonMode>
#include <osg/BlendFunc>
#include <osg/Depth>
#include <osg/TextureCubeMap>
#include <osg/TextureRectangle>
#include <set>
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<StateAttribute::GLMode> _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;i<rhs._textureAttributeList.size();++i)
{
AttributeList& lhs_attributeList = _textureAttributeList[i];
const AttributeList& rhs_attributeList = rhs._textureAttributeList[i];
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) 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;
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->first<rhs_attr_itr->first) return -1;
else if (rhs_attr_itr->first<lhs_attr_itr->first) 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.second<rhs_attr_itr->second.second) return -1;
else if (rhs_attr_itr->second.second<lhs_attr_itr->second.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->first<rhs_attr_itr->first) return -1;
else if (rhs_attr_itr->first<lhs_attr_itr->first) 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.second<rhs_attr_itr->second.second) return -1;
else if (rhs_attr_itr->second.second<lhs_attr_itr->second.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->first<rhs_attr_itr->first) return -1;
else if (rhs_attr_itr->first<lhs_attr_itr->first) 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.second<rhs_attr_itr->second.second) return -1;
else if (rhs_attr_itr->second.second<lhs_attr_itr->second.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->first<rhs_attr_itr->first) return -1;
else if (rhs_attr_itr->first<lhs_attr_itr->first) 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.second<rhs_attr_itr->second.second) return -1;
else if (rhs_attr_itr->second.second<lhs_attr_itr->second.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;
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->first<rhs_mode_itr->first) return -1;
else if (rhs_mode_itr->first<lhs_mode_itr->first) return 1;
if (lhs_mode_itr->second<rhs_mode_itr->second) return -1;
else if (rhs_mode_itr->second<lhs_mode_itr->second) 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->first<rhs_mode_itr->first) return -1;
else if (rhs_mode_itr->first<lhs_mode_itr->first) return 1;
if (lhs_mode_itr->second<rhs_mode_itr->second) return -1;
else if (rhs_mode_itr->second<lhs_mode_itr->second) 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->first<rhs_uniform_itr->first) return -1;
else if (rhs_uniform_itr->first<lhs_uniform_itr->first) return 1;
if (lhs_uniform_itr->second<rhs_uniform_itr->second) return -1;
else if (rhs_uniform_itr->second<lhs_uniform_itr->second) 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->first<rhs_mode_itr->first) return -1;
else if (rhs_mode_itr->first<lhs_mode_itr->first) return 1;
if (lhs_mode_itr->second<rhs_mode_itr->second) return -1;
else if (rhs_mode_itr->second<lhs_mode_itr->second) 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->first<rhs_attr_itr->first) return -1;
else if (rhs_attr_itr->first<lhs_attr_itr->first) 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.second<rhs_attr_itr->second.second) return -1;
else if (rhs_attr_itr->second.second<lhs_attr_itr->second.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->first<rhs_attr_itr->first) return -1;
else if (rhs_attr_itr->first<lhs_attr_itr->first) 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.second<rhs_attr_itr->second.second) return -1;
else if (rhs_attr_itr->second.second<lhs_attr_itr->second.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()<rhs._textureModeList.size()) _textureModeList.resize(rhs._textureModeList.size());
for(unsigned int mi=0;mi<rhs._textureModeList.size();++mi)
{
ModeList& lhs_modeList = _textureModeList[mi];
const ModeList& rhs_modeList = rhs._textureModeList[mi];
// 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 = lhs_modeList.find(rhs_mitr->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()<rhs._textureAttributeList.size()) _textureAttributeList.resize(rhs._textureAttributeList.size());
for(unsigned int ai=0;ai<rhs._textureAttributeList.size();++ai)
{
AttributeList& lhs_attributeList = _textureAttributeList[ai];
const AttributeList& rhs_attributeList = rhs._textureAttributeList[ai];
// 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 = lhs_attributeList.find(rhs_aitr->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 '"<<mode<<"'passed to setMode(mode,value), "<<std::endl;
notify(NOTICE)<<" assuming setTextureMode(unit=0,mode,value) instead."<<std::endl;
notify(NOTICE)<<" please change calling code to use appropriate call."<<std::endl;
setTextureMode(0,mode,value);
}
}
void StateSet::removeMode(StateAttribute::GLMode mode)
{
if (!s_textureGLModeSet.isTextureMode(mode))
{
setModeToInherit(_modeList,mode);
}
else
{
notify(NOTICE)<<"Warning: texture mode '"<<mode<<"'passed to setModeToInherit(mode), "<<std::endl;
notify(NOTICE)<<" assuming setTextureModeToInherit(unit=0,mode) instead."<<std::endl;
notify(NOTICE)<<" please change calling code to use appropriate call."<<std::endl;
removeTextureMode(0,mode);
}
}
StateAttribute::GLModeValue StateSet::getMode(StateAttribute::GLMode mode) const
{
if (!s_textureGLModeSet.isTextureMode(mode))
{
return getMode(_modeList,mode);
}
else
{
notify(NOTICE)<<"Warning: texture mode '"<<mode<<"'passed to getMode(mode), "<<std::endl;
notify(NOTICE)<<" assuming getTextureMode(unit=0,mode) instead."<<std::endl;
notify(NOTICE)<<" please change calling code to use appropriate call."<<std::endl;
return getTextureMode(0,mode);
}
}
void StateSet::setAttribute(StateAttribute *attribute, StateAttribute::OverrideValue value)
{
if (attribute)
{
if (!attribute->isTextureAttribute())
{
setAttribute(_attributeList,attribute,value);
}
else
{
notify(NOTICE)<<"Warning: texture attribute '"<<attribute->className()<<"'passed to setAttribute(attr,value), "<<std::endl;
notify(NOTICE)<<" assuming setTextureAttribute(unit=0,attr,value) instead."<<std::endl;
notify(NOTICE)<<" please change calling code to use appropriate call."<<std::endl;
setTextureAttribute(0,attribute,value);
}
}
}
void StateSet::setAttributeAndModes(StateAttribute *attribute, StateAttribute::GLModeValue value)
{
if (attribute)
{
if (!attribute->isTextureAttribute())
{
if (value&StateAttribute::INHERIT)
{
removeAttribute(attribute->getType());
}
else
{
setAttribute(_attributeList,attribute,value);
setAssociatedModes(attribute,value);
}
}
else
{
notify(NOTICE)<<"Warning: texture attribute '"<<attribute->className()<<"' passed to setAttributeAndModes(attr,value), "<<std::endl;
notify(NOTICE)<<" assuming setTextureAttributeAndModes(unit=0,attr,value) instead."<<std::endl;
notify(NOTICE)<<" please change calling code to use appropriate call."<<std::endl;
setTextureAttributeAndModes(0,attribute,value);
}
}
}
void StateSet::removeAttribute(StateAttribute::Type type, unsigned int member)
{
AttributeList::iterator itr = _attributeList.find(StateAttribute::TypeMemberPair(type,member));
if (itr!=_attributeList.end())
{
setAssociatedModes(itr->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 '"<<mode<<"'passed to setTextureMode(unit,mode,value), "<<std::endl;
notify(NOTICE)<<" assuming setMode(mode,value) instead."<<std::endl;
notify(NOTICE)<<" please change calling code to use appropriate call."<<std::endl;
setMode(mode,value);
}
}
void StateSet::removeTextureMode(unsigned int unit,StateAttribute::GLMode mode)
{
if (s_textureGLModeSet.isTextureMode(mode))
{
if (unit>=_textureModeList.size()) return;
setModeToInherit(_textureModeList[unit],mode);
}
else
{
notify(NOTICE)<<"Warning: non-texture mode '"<<mode<<"'passed to setTextureModeToInherit(unit,mode), "<<std::endl;
notify(NOTICE)<<" assuming setModeToInherit(unit=0,mode) instead."<<std::endl;
notify(NOTICE)<<" please change calling code to use appropriate call."<<std::endl;
removeMode(mode);
}
}
StateAttribute::GLModeValue StateSet::getTextureMode(unsigned int unit,StateAttribute::GLMode mode) const
{
if (s_textureGLModeSet.isTextureMode(mode))
{
if (unit>=_textureModeList.size()) return StateAttribute::INHERIT;
return getMode(_textureModeList[unit],mode);
}
else
{
notify(NOTICE)<<"Warning: non-texture mode '"<<mode<<"'passed to geTexturetMode(unit,mode), "<<std::endl;
notify(NOTICE)<<" assuming getMode(mode) instead."<<std::endl;
notify(NOTICE)<<" please change calling code to use appropriate call."<<std::endl;
return getMode(mode);
}
}
void StateSet::setTextureAttribute(unsigned int unit,StateAttribute *attribute, const StateAttribute::OverrideValue value)
{
if (attribute)
{
if (attribute->isTextureAttribute())
{
setAttribute(getOrCreateTextureAttributeList(unit),attribute,value);
}
else
{
notify(NOTICE)<<"Warning: texture attribute '"<<attribute->className()<<"' passed to setTextureAttribute(unit,attr,value), "<<std::endl;
notify(NOTICE)<<" assuming setAttribute(attr,value) instead."<<std::endl;
notify(NOTICE)<<" please change calling code to use appropriate call."<<std::endl;
setAttribute(attribute,value);
}
}
}
void StateSet::setTextureAttributeAndModes(unsigned int unit,StateAttribute *attribute, StateAttribute::GLModeValue value)
{
if (attribute)
{
if (attribute->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 '"<<attribute->className()<<"' passed to setTextureAttributeAndModes(unit,attr,value), "<<std::endl;
notify(NOTICE)<<" assuming setAttributeAndModes(attr,value) instead."<<std::endl;
notify(NOTICE)<<" please change calling code to use appropriate call."<<std::endl;
setAttribute(attribute,value);
}
}
}
void StateSet::removeTextureAttribute(unsigned int unit,StateAttribute::Type type)
{
if (unit>=_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;
}