Added ParentList's into StateSet, Uniform and StateAttribute in preparation for

providing update and event handling.
This commit is contained in:
Robert Osfield
2005-04-24 21:04:54 +00:00
parent 4262366f62
commit 193c83cb9c
12 changed files with 345 additions and 35 deletions

View File

@@ -432,6 +432,10 @@ SOURCE=..\..\src\osg\State.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osg\StateAttribute.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osg\StateSet.cpp
# End Source File
# Begin Source File

View File

@@ -135,7 +135,7 @@ class OSG_EXPORT Drawable : public Object
/** Set the StateSet attached to the Drawable.
Previously attached StateSet are automatically unreferenced on
assignment of a new drawstate.*/
inline void setStateSet(StateSet *state) { _stateset = state; }
void setStateSet(StateSet* stateset);
/** Get the attached StateSet.*/
inline StateSet* getStateSet() { return _stateset.get();}

View File

@@ -221,7 +221,7 @@ class OSG_EXPORT Node : public Object
/** Set the node's StateSet.*/
inline void setStateSet(osg::StateSet* dstate) { _stateset = dstate; }
void setStateSet(osg::StateSet* stateset);
/** return the node's StateSet, if one does not already exist create it
* set the node and return the newly created StateSet. This ensures

View File

@@ -20,6 +20,7 @@
#include <typeinfo>
#include <utility>
#include <vector>
// define for the GL_EXT_secondary_color extension, GL_COLOR_SUM is OpenGL
// mode to be used to enable and disable the second color.
@@ -231,7 +232,28 @@ class OSG_EXPORT StateAttribute : public Object
bool operator < (const StateAttribute& rhs) const { return compare(rhs)<0; }
bool operator == (const StateAttribute& rhs) const { return compare(rhs)==0; }
bool operator != (const StateAttribute& rhs) const { return compare(rhs)!=0; }
/** A vector of osg::StateSet pointers which is used to store the parent(s) of this StateAttribute.*/
typedef std::vector<StateSet*> ParentList;
/** Get the parent list of this StateAttribute. */
inline const ParentList& getParents() const { return _parents; }
inline StateSet* getParent(unsigned int i) { return _parents[i]; }
/**
* Get a single const parent of this StateAttribute.
* @param i index of the parent to get.
* @return the parent i.
*/
inline const StateSet* getParent(unsigned int i) const { return _parents[i]; }
/**
* Get the number of parents of this StateAttribute.
* @return the number of parents of this StateAttribute.
*/
inline unsigned int getNumParents() const { return _parents.size(); }
struct ModeUsage
{
@@ -299,6 +321,12 @@ class OSG_EXPORT StateAttribute : public Object
virtual ~StateAttribute() {}
void addParent(osg::StateSet* object);
void removeParent(osg::StateSet* object);
ParentList _parents;
friend class osg::StateSet;
ref_ptr<Callback> _updateCallback;
ref_ptr<Callback> _eventCallback;
};

View File

@@ -66,6 +66,32 @@ class OSG_EXPORT StateSet : public Object
bool operator == (const StateSet& rhs) const { return compare(rhs)==0; }
bool operator != (const StateSet& rhs) const { return compare(rhs)!=0; }
/** A vector of osg::Object pointers which is used to store the parent(s) of this Stateset, the parents could be osg::Node or osg::Drawable.*/
typedef std::vector<Object*> ParentList;
/** Get the parent list of this StateSet. */
inline const ParentList& getParents() const { return _parents; }
/** Get the a copy of parent list of node. A copy is returned to
* prevent modification of the parent list.*/
inline ParentList getParents() { return _parents; }
inline Object* getParent(unsigned int i) { return _parents[i]; }
/**
* Get a single const parent of this StateSet.
* @param i index of the parent to get.
* @return the parent i.
*/
inline const Object* getParent(unsigned int i) const { return _parents[i]; }
/**
* Get the number of parents of this StateSet.
* @return the number of parents of this StateSet.
*/
inline unsigned int getNumParents() const { return _parents.size(); }
/** Set all the modes to on or off so that it defines a
complete state, typically used for a default global state.*/
void setGlobalDefaults();
@@ -410,6 +436,13 @@ class OSG_EXPORT StateSet : public Object
StateSet& operator = (const StateSet&) { return *this; }
void addParent(osg::Object* object);
void removeParent(osg::Object* object);
ParentList _parents;
friend class osg::Node;
friend class osg::Drawable;
ModeList _modeList;
AttributeList _attributeList;

View File

@@ -25,6 +25,7 @@
#include <osg/GL>
#include <string>
#include <vector>
#ifndef GL_VERSION_2_0 //[
#define GL_VERSION_2_0 1
@@ -159,6 +160,9 @@ class OSG_EXPORT Uniform : public Object
META_Object(osg, Uniform);
bool setType( Type t );
bool setName( const std::string& name );
@@ -202,6 +206,32 @@ class OSG_EXPORT Uniform : public Object
void copyData( const Uniform& rhs );
/** A vector of osg::StateSet pointers which is used to store the parent(s) of this Uniform, the parents could be osg::Node or osg::Drawable.*/
typedef std::vector<StateSet*> ParentList;
/** Get the parent list of this Uniform. */
inline const ParentList& getParents() const { return _parents; }
/** Get the a copy of parent list of node. A copy is returned to
* prevent modification of the parent list.*/
inline ParentList getParents() { return _parents; }
inline StateSet* getParent(unsigned int i) { return _parents[i]; }
/**
* Get a single const parent of this Uniform.
* @param i index of the parent to get.
* @return the parent i.
*/
inline const StateSet* getParent(unsigned int i) const { return _parents[i]; }
/**
* Get the number of parents of this Uniform.
* @return the number of parents of this Uniform.
*/
inline unsigned int getNumParents() const { return _parents.size(); }
/** value assignment */
bool set( float f );
bool set( int i );
@@ -280,6 +310,12 @@ class OSG_EXPORT Uniform : public Object
bool isCompatibleType( Type t ) const;
void addParent(osg::StateSet* object);
void removeParent(osg::StateSet* object);
ParentList _parents;
friend class osg::StateSet;
std::string _name;
Type _type;
union {

View File

@@ -306,6 +306,22 @@ void Drawable::removeParent(osg::Node* node)
if (pitr!=_parents.end()) _parents.erase(pitr);
}
void Drawable::setStateSet(osg::StateSet* stateset)
{
// do nothing if nothing changed.
if (_stateset==stateset) return;
// remove this node from the current statesets parent list
if (_stateset.valid()) _stateset->removeParent(this);
// set the stateset.
_stateset = stateset;
// add this node to the new stateset to the parent list.
if (_stateset.valid()) _stateset->addParent(this);
}
osg::StateSet* Drawable::getOrCreateStateSet()
{
if (!_stateset) _stateset = new StateSet;

View File

@@ -86,6 +86,7 @@ CXXFILES =\
Shape.cpp\
ShapeDrawable.cpp\
State.cpp\
StateAttribute.cpp\
StateSet.cpp\
Stencil.cpp\
Switch.cpp\

View File

@@ -86,6 +86,21 @@ void Node::ascend(NodeVisitor& nv)
std::for_each(_parents.begin(),_parents.end(),NodeAcceptOp(nv));
}
void Node::setStateSet(osg::StateSet* stateset)
{
// do nothing if nothing changed.
if (_stateset==stateset) return;
// remove this node from the current statesets parent list
if (_stateset.valid()) _stateset->removeParent(this);
// set the stateset.
_stateset = stateset;
// add this node to the new stateset to the parent list.
if (_stateset.valid()) _stateset->addParent(this);
}
osg::StateSet* Node::getOrCreateStateSet()
{
if (!_stateset) _stateset = new StateSet;

View File

@@ -0,0 +1,27 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield
*
* This application is open source and may be redistributed and/or modified
* freely and without restriction, both in commericial and non commericial
* applications, as long as this copyright notice is maintained.
*
* This application 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.
*/
#include <osg/StateAttribute>
#include <algorithm>
using namespace osg;
void StateAttribute::addParent(osg::StateSet* object)
{
_parents.push_back(object);
}
void StateAttribute::removeParent(osg::StateSet* object)
{
ParentList::iterator pitr = std::find(_parents.begin(),_parents.end(),object);
if (pitr!=_parents.end()) _parents.erase(pitr);
}

View File

@@ -45,7 +45,7 @@ class TextureGLModeSet
_textureModeSet.insert(GL_TEXTURE_3D);
_textureModeSet.insert(GL_TEXTURE_CUBE_MAP);
_textureModeSet.insert(GL_TEXTURE_RECTANGLE_NV);
_textureModeSet.insert(GL_TEXTURE_RECTANGLE_NV);
_textureModeSet.insert(GL_TEXTURE_GEN_Q);
_textureModeSet.insert(GL_TEXTURE_GEN_R);
@@ -87,7 +87,11 @@ StateSet::StateSet(const StateSet& rhs,const CopyOp& copyop):Object(rhs,copyop)
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);
if (attr)
{
_attributeList[typemember]=RefAttributePair(attr,rap.second);
attr->addParent(this);
}
}
// copy texture related modes.
@@ -109,7 +113,11 @@ StateSet::StateSet(const StateSet& rhs,const CopyOp& copyop):Object(rhs,copyop)
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 (attr)
{
lhs_attributeList[typemember]=RefAttributePair(attr,rap.second);
attr->addParent(this);
}
}
}
@@ -118,10 +126,14 @@ StateSet::StateSet(const StateSet& rhs,const CopyOp& copyop):Object(rhs,copyop)
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);
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);
uni->addParent(this);
}
}
_renderingHint = rhs._renderingHint;
@@ -133,9 +145,18 @@ StateSet::StateSet(const StateSet& rhs,const CopyOp& copyop):Object(rhs,copyop)
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.
clear();
}
void StateSet::addParent(osg::Object* object)
{
_parents.push_back(object);
}
void StateSet::removeParent(osg::Object* object)
{
ParentList::iterator pitr = std::find(_parents.begin(),_parents.end(),object);
if (pitr!=_parents.end()) _parents.erase(pitr);
}
int StateSet::compare(const StateSet& rhs,bool compareAttributeContents) const
@@ -402,12 +423,42 @@ void StateSet::clear()
setRenderBinToInherit();
// remove self from as attributes parent
for(AttributeList::iterator itr=_attributeList.begin();
itr!=_attributeList.end();
++itr)
{
itr->second.first->removeParent(this);
}
_modeList.clear();
_attributeList.clear();
_textureModeList.clear();
_textureAttributeList.clear();
// remove self from as texture attributes parent
for(unsigned int i=0;i<_textureAttributeList.size();++i)
{
AttributeList& attributeList = _textureAttributeList[i];
for(AttributeList::iterator itr=attributeList.begin();
itr!=attributeList.end();
++itr)
{
itr->second.first->removeParent(this);
}
}
// remove self from uniforms parent
for(UniformList::iterator uitr = _uniformList.begin();
uitr != _uniformList.end();
++uitr)
{
uitr->second.first->removeParent(this);
}
_uniformList.clear();
}
@@ -449,13 +500,29 @@ void StateSet::merge(const StateSet& rhs)
{
// override isn't on in rhs, so overrite it with incomming
// value.
lhs_aitr->second = rhs_aitr->second;
if (lhs_aitr->second.first!=rhs_aitr->second.first)
{
// new attribute so need to remove self from outgoing attribute
lhs_aitr->second.first->removeParent(this);
// override isn't on in rhs, so overrite it with incomming
// value.
lhs_aitr->second = rhs_aitr->second;
lhs_aitr->second.first->addParent(this);
}
else
{
// same attribute but with override to set.
lhs_aitr->second = rhs_aitr->second;
}
}
}
else
{
// entry doesn't exist so insert it.
_attributeList.insert(*rhs_aitr);
// entry doesn't exist so insert it, and then tell it about self by adding self as parent.
_attributeList.insert(*rhs_aitr).first->second.first->addParent(this);
}
}
@@ -508,13 +575,23 @@ void StateSet::merge(const StateSet& rhs)
{
// override isn't on in rhs, so overrite it with incomming
// value.
lhs_aitr->second = rhs_aitr->second;
if (lhs_aitr->second.first!=rhs_aitr->second.first)
{
lhs_aitr->second.first->removeParent(this);
lhs_aitr->second = rhs_aitr->second;
lhs_aitr->second.first->addParent(this);
}
else
{
lhs_aitr->second = rhs_aitr->second;
}
}
}
else
{
// entry doesn't exist so insert it.
lhs_attributeList.insert(*rhs_aitr);
// entry doesn't exist so insert it and add self as parent
lhs_attributeList.insert(*rhs_aitr).first->second.first->addParent(this);
}
}
}
@@ -532,13 +609,24 @@ void StateSet::merge(const StateSet& rhs)
{
// override isn't on in rhs, so overrite it with incomming
// value.
lhs_uitr->second = rhs_uitr->second;
if (lhs_uitr->second.first!=rhs_uitr->second.first)
{
lhs_uitr->second.first->removeParent(this);
lhs_uitr->second = rhs_uitr->second;
lhs_uitr->second.first->addParent(this);
}
else
{
lhs_uitr->second = rhs_uitr->second;
}
}
}
else
{
// entry doesn't exist so insert it.
_uniformList.insert(*rhs_uitr);
// entry doesn't exist so insert it and add self as parent
_uniformList.insert(*rhs_uitr).first->second.first->addParent(this);
}
}
@@ -649,6 +737,7 @@ void StateSet::removeAttribute(StateAttribute::Type type, unsigned int member)
AttributeList::iterator itr = _attributeList.find(StateAttribute::TypeMemberPair(type,member));
if (itr!=_attributeList.end())
{
itr->second.first->removeParent(this);
setAssociatedModes(itr->second.first.get(),StateAttribute::INHERIT);
_attributeList.erase(itr);
}
@@ -663,6 +752,8 @@ void StateSet::removeAttribute(StateAttribute* attribute)
{
if (itr->second.first != attribute) return;
itr->second.first->removeParent(this);
setAssociatedModes(itr->second.first.get(),StateAttribute::INHERIT);
_attributeList.erase(itr);
}
@@ -687,9 +778,31 @@ void StateSet::addUniform(Uniform* uniform, StateAttribute::OverrideValue value)
{
if (uniform)
{
RefUniformPair& up = _uniformList[uniform->getName()];
up.first = uniform;
up.second = value;
UniformList::iterator itr=_uniformList.find(uniform->getName());
if (itr==_uniformList.end())
{
// new entry.
RefUniformPair& up = _uniformList[uniform->getName()];
up.first = uniform;
up.second = value&(StateAttribute::OVERRIDE|StateAttribute::PROTECTED);
uniform->addParent(this);
}
else
{
if (itr->second.first==uniform)
{
// chaning just override
itr->second.second = value&(StateAttribute::OVERRIDE|StateAttribute::PROTECTED);
}
else
{
itr->second.first->removeParent(this);
uniform->addParent(this);
itr->second.first = uniform;
itr->second.second = value&(StateAttribute::OVERRIDE|StateAttribute::PROTECTED);
}
}
}
}
@@ -698,6 +811,7 @@ void StateSet::removeUniform(const std::string& name)
UniformList::iterator itr = _uniformList.find(name);
if (itr!=_uniformList.end())
{
itr->second.first->removeParent(this);
_uniformList.erase(itr);
}
}
@@ -710,6 +824,8 @@ void StateSet::removeUniform(Uniform* uniform)
if (itr!=_uniformList.end())
{
if (itr->second.first != uniform) return;
itr->second.first->removeParent(this);
_uniformList.erase(itr);
}
}
@@ -844,24 +960,26 @@ void StateSet::removeTextureAttribute(unsigned int unit,StateAttribute::Type typ
{
setAssociatedTextureModes(unit,itr->second.first.get(),StateAttribute::INHERIT);
}
itr->second.first->removeParent(this);
attributeList.erase(itr);
}
}
void StateSet::removeTextureAttribute(unsigned int unit, StateAttribute* attribute)
{
if (!attribute) return;
if (unit>=_textureAttributeList.size()) return;
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;
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);
}
setAssociatedTextureModes(unit,itr->second.first.get(),StateAttribute::INHERIT);
itr->second.first->removeParent(this);
attributeList.erase(itr);
}
}
StateAttribute* StateSet::getTextureAttribute(unsigned int unit,StateAttribute::Type type)
@@ -1040,7 +1158,28 @@ void StateSet::setAttribute(AttributeList& attributeList,StateAttribute *attribu
{
if (attribute)
{
attributeList[attribute->getTypeMemberPair()] = RefAttributePair(attribute,value&(StateAttribute::OVERRIDE|StateAttribute::PROTECTED));
AttributeList::iterator itr=attributeList.find(attribute->getTypeMemberPair());
if (itr==attributeList.end())
{
// new entry.
attributeList[attribute->getTypeMemberPair()] = RefAttributePair(attribute,value&(StateAttribute::OVERRIDE|StateAttribute::PROTECTED));
attribute->addParent(this);
}
else
{
if (itr->second.first==attribute)
{
// changing just override
itr->second.second = value&(StateAttribute::OVERRIDE|StateAttribute::PROTECTED);
}
else
{
itr->second.first->removeParent(this);
attribute->addParent(this);
itr->second.first = attribute;
itr->second.second = value&(StateAttribute::OVERRIDE|StateAttribute::PROTECTED);
}
}
}
}

View File

@@ -68,6 +68,17 @@ Uniform::Uniform( const Uniform& rhs, const CopyOp& copyop ) :
copyData( rhs );
}
void Uniform::addParent(osg::StateSet* object)
{
_parents.push_back(object);
}
void Uniform::removeParent(osg::StateSet* object)
{
ParentList::iterator pitr = std::find(_parents.begin(),_parents.end(),object);
if (pitr!=_parents.end()) _parents.erase(pitr);
}
bool Uniform::setType( Type t )
{
if( _type != UNDEFINED )