Futher work on supporting update and event callbacks in StateSet, Uniform and StateAttribute

This commit is contained in:
Robert Osfield
2005-04-25 13:37:12 +00:00
parent 78f88247f8
commit e24cfa0370
13 changed files with 432 additions and 50 deletions

View File

@@ -363,7 +363,7 @@ void Drawable::setStateSet(osg::StateSet* stateset)
osg::StateSet* Drawable::getOrCreateStateSet()
{
if (!_stateset) _stateset = new StateSet;
if (!_stateset) setStateSet(new StateSet);
return _stateset.get();
}

View File

@@ -57,12 +57,12 @@ bool Geode::addDrawable( Drawable *drawable )
// register as parent of drawable.
drawable->addParent(this);
if (drawable->getUpdateCallback())
if (drawable->getUpdateCallback() && !(_stateset.valid() && _stateset->requiresUpdateTraversal()))
{
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1);
}
if (drawable->getEventCallback())
if (drawable->getEventCallback() && !(_stateset.valid() && _stateset->requiresEventTraversal()))
{
setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()+1);
}
@@ -105,12 +105,12 @@ bool Geode::removeDrawable(unsigned int pos,unsigned int numDrawablesToRemove)
_drawables.erase(_drawables.begin()+pos,_drawables.begin()+endOfRemoveRange);
if (updateCallbackRemoved)
if (updateCallbackRemoved && !(_stateset.valid() && _stateset->requiresUpdateTraversal()))
{
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()-updateCallbackRemoved);
}
if (eventCallbackRemoved)
if (eventCallbackRemoved && !(_stateset.valid() && _stateset->requiresEventTraversal()))
{
setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()-eventCallbackRemoved);
}

View File

@@ -127,7 +127,7 @@ void Node::setStateSet(osg::StateSet* stateset)
osg::StateSet* Node::getOrCreateStateSet()
{
if (!_stateset) _stateset = new StateSet;
if (!_stateset) setStateSet(new StateSet);
return _stateset.get();
}

View File

@@ -92,15 +92,15 @@ void Shader::flushDeletedGlShaders(unsigned int contextID,double /*currentTime*/
// osg::Shader
///////////////////////////////////////////////////////////////////////////
Shader::Shader(Type type, const char* sourceText) :
Shader::Shader(Type type) :
_type(type)
{
setShaderSource( sourceText );
}
Shader::Shader() :
_type(UNDEFINED)
Shader::Shader(Type type, const std::string& source) :
_type(type)
{
setShaderSource( source);
}
Shader::Shader(const Shader& rhs, const osg::CopyOp& copyop):
@@ -142,18 +142,25 @@ int Shader::compare(const Shader& rhs) const
return 0;
}
void Shader::setShaderSource( const char* sourceText )
void Shader::setShaderSource( const std::string& sourceText )
{
_shaderSource = ( sourceText ? sourceText : "" );
_shaderSource = sourceText;
dirtyShader();
}
bool Shader::loadShaderSourceFromFile( const char* fileName )
Shader* Shader::readShaderFile( Type type, const std::string& fileName )
{
ref_ptr<Shader> shader = new Shader(type);
if (shader->loadShaderSourceFromFile(fileName)) return shader.release();
return 0;
}
bool Shader::loadShaderSourceFromFile( const std::string& fileName )
{
std::ifstream sourceFile;
sourceFile.open(fileName, std::ios::binary);
sourceFile.open(fileName.c_str(), std::ios::binary);
if(!sourceFile)
{
osg::notify(osg::WARN)<<"Error: can't open file \""<<fileName<<"\""<<std::endl;

View File

@@ -10,6 +10,8 @@
*/
#include <osg/StateAttribute>
#include <osg/StateSet>
#include <osg/Notify>
#include <algorithm>
@@ -25,3 +27,52 @@ void StateAttribute::removeParent(osg::StateSet* object)
ParentList::iterator pitr = std::find(_parents.begin(),_parents.end(),object);
if (pitr!=_parents.end()) _parents.erase(pitr);
}
void StateAttribute::setUpdateCallback(Callback* uc)
{
osg::notify(osg::NOTICE)<<"Uniform::Setting Update callbacks"<<std::endl;
if (_updateCallback==uc) return;
int delta = 0;
if (_updateCallback.valid()) --delta;
if (uc) ++delta;
_updateCallback = uc;
if (delta!=0)
{
osg::notify(osg::NOTICE)<<"Going to set StateSet parents"<<std::endl;
for(ParentList::iterator itr=_parents.begin();
itr!=_parents.end();
++itr)
{
(*itr)->setNumChildrenRequiringUpdateTraversal((*itr)->getNumChildrenRequiringUpdateTraversal()+delta);
}
}
}
void StateAttribute::setEventCallback(Callback* ec)
{
osg::notify(osg::NOTICE)<<"Uniform::Setting Event callbacks"<<std::endl;
if (_updateCallback==ec) return;
int delta = 0;
if (_updateCallback.valid()) --delta;
if (ec) ++delta;
_updateCallback = ec;
if (delta!=0)
{
for(ParentList::iterator itr=_parents.begin();
itr!=_parents.end();
++itr)
{
(*itr)->setNumChildrenRequiringUpdateTraversal((*itr)->getNumChildrenRequiringUpdateTraversal()+delta);
}
}
}

View File

@@ -23,6 +23,8 @@
#include <osg/PolygonMode>
#include <osg/BlendFunc>
#include <osg/Depth>
#include <osg/Drawable>
#include <osg/Node>
#include <osg/TextureCubeMap>
#include <osg/TextureRectangle>
@@ -157,6 +159,8 @@ StateSet::~StateSet()
void StateSet::addParent(osg::Object* object)
{
osg::notify(osg::INFO)<<"Adding parent"<<std::endl;
_parents.push_back(object);
}
@@ -744,6 +748,16 @@ void StateSet::removeAttribute(StateAttribute::Type type, unsigned int member)
AttributeList::iterator itr = _attributeList.find(StateAttribute::TypeMemberPair(type,member));
if (itr!=_attributeList.end())
{
if (itr->second.first->getUpdateCallback())
{
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()-1);
}
if (itr->second.first->getEventCallback())
{
setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()-1);
}
itr->second.first->removeParent(this);
setAssociatedModes(itr->second.first.get(),StateAttribute::INHERIT);
_attributeList.erase(itr);
@@ -759,6 +773,16 @@ void StateSet::removeAttribute(StateAttribute* attribute)
{
if (itr->second.first != attribute) return;
if (itr->second.first->getUpdateCallback())
{
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()-1);
}
if (itr->second.first->getEventCallback())
{
setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()-1);
}
itr->second.first->removeParent(this);
setAssociatedModes(itr->second.first.get(),StateAttribute::INHERIT);
@@ -785,6 +809,9 @@ void StateSet::addUniform(Uniform* uniform, StateAttribute::OverrideValue value)
{
if (uniform)
{
int delta_update = 0;
int delta_event = 0;
UniformList::iterator itr=_uniformList.find(uniform->getName());
if (itr==_uniformList.end())
{
@@ -794,6 +821,16 @@ void StateSet::addUniform(Uniform* uniform, StateAttribute::OverrideValue value)
up.second = value&(StateAttribute::OVERRIDE|StateAttribute::PROTECTED);
uniform->addParent(this);
if (uniform->getUpdateCallback())
{
delta_update = 1;
}
if (uniform->getEventCallback())
{
delta_event = 1;
}
}
else
{
@@ -805,11 +842,28 @@ void StateSet::addUniform(Uniform* uniform, StateAttribute::OverrideValue value)
else
{
itr->second.first->removeParent(this);
if (itr->second.first->getUpdateCallback()) --delta_update;
if (itr->second.first->getEventCallback()) --delta_event;
uniform->addParent(this);
itr->second.first = uniform;
if (itr->second.first->getUpdateCallback()) ++delta_update;
if (itr->second.first->getEventCallback()) ++delta_event;
itr->second.second = value&(StateAttribute::OVERRIDE|StateAttribute::PROTECTED);
}
}
if (delta_update!=0)
{
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+delta_update);
}
if (delta_event!=0)
{
setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()+delta_event);
}
}
}
@@ -818,7 +872,18 @@ void StateSet::removeUniform(const std::string& name)
UniformList::iterator itr = _uniformList.find(name);
if (itr!=_uniformList.end())
{
if (itr->second.first->getUpdateCallback())
{
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()-1);
}
if (itr->second.first->getEventCallback())
{
setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()-1);
}
itr->second.first->removeParent(this);
_uniformList.erase(itr);
}
}
@@ -832,6 +897,16 @@ void StateSet::removeUniform(Uniform* uniform)
{
if (itr->second.first != uniform) return;
if (itr->second.first->getUpdateCallback())
{
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()-1);
}
if (itr->second.first->getEventCallback())
{
setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()-1);
}
itr->second.first->removeParent(this);
_uniformList.erase(itr);
}
@@ -967,6 +1042,18 @@ void StateSet::removeTextureAttribute(unsigned int unit,StateAttribute::Type typ
{
setAssociatedTextureModes(unit,itr->second.first.get(),StateAttribute::INHERIT);
}
if (itr->second.first->getUpdateCallback())
{
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()-1);
}
if (itr->second.first->getEventCallback())
{
setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()-1);
}
itr->second.first->removeParent(this);
attributeList.erase(itr);
}
@@ -984,6 +1071,17 @@ void StateSet::removeTextureAttribute(unsigned int unit, StateAttribute* attribu
if (itr->second.first != attribute) return;
setAssociatedTextureModes(unit,itr->second.first.get(),StateAttribute::INHERIT);
if (itr->second.first->getUpdateCallback())
{
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()-1);
}
if (itr->second.first->getEventCallback())
{
setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()-1);
}
itr->second.first->removeParent(this);
attributeList.erase(itr);
}
@@ -1165,12 +1263,25 @@ void StateSet::setAttribute(AttributeList& attributeList,StateAttribute *attribu
{
if (attribute)
{
int delta_update = 0;
int delta_event = 0;
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);
if (attribute->getUpdateCallback())
{
delta_update = 1;
}
if (attribute->getEventCallback())
{
delta_event = 1;
}
}
else
{
@@ -1182,11 +1293,27 @@ void StateSet::setAttribute(AttributeList& attributeList,StateAttribute *attribu
else
{
itr->second.first->removeParent(this);
if (itr->second.first->getUpdateCallback()) --delta_update;
if (itr->second.first->getEventCallback()) --delta_event;
attribute->addParent(this);
itr->second.first = attribute;
itr->second.second = value&(StateAttribute::OVERRIDE|StateAttribute::PROTECTED);
if (itr->second.first->getUpdateCallback()) ++delta_update;
if (itr->second.first->getEventCallback()) ++delta_event;
itr->second.second = value&(StateAttribute::OVERRIDE|StateAttribute::PROTECTED);
}
}
if (delta_update!=0)
{
setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+delta_update);
}
if (delta_event!=0)
{
setNumChildrenRequiringEventTraversal(getNumChildrenRequiringEventTraversal()+delta_event);
}
}
}
@@ -1229,6 +1356,8 @@ const StateSet::RefAttributePair* StateSet::getAttributePair(const AttributeList
void StateSet::setUpdateCallback(Callback* ac)
{
osg::notify(osg::INFO)<<"Setting StateSet callbacks"<<std::endl;
if (_updateCallback==ac) return;
int delta = 0;
@@ -1237,21 +1366,37 @@ void StateSet::setUpdateCallback(Callback* ac)
_updateCallback = ac;
if (delta!=0)
if (delta!=0 && _numChildrenRequiringUpdateTraversal==0)
{
#if 0
osg::notify(osg::INFO)<<"Going to set StateSet parents"<<std::endl;
for(ParentList::iterator itr=_parents.begin();
itr!=_parents.end();
++itr)
{
(*itr)->setNumChildrenRequiringUpdateTraversal((*itr)->getNumChildrenRequiringUpdateTraversal()+delta);
osg::notify(osg::INFO)<<"Setting StateSet parent"<<std::endl;
osg::Drawable* drawable = dynamic_cast<osg::Drawable*>(*itr);
if (drawable)
{
//drawable->setNumChildrenRequiringUpdateTraversal(drawable->getNumChildrenRequiringUpdateTraversal()+delta);
}
else
{
osg::Node* node = dynamic_cast<osg::Node*>(*itr);
if (node)
{
node->setNumChildrenRequiringUpdateTraversal(node->getNumChildrenRequiringUpdateTraversal()+delta);
}
}
}
#endif
}
}
void StateSet::runUpdateCallbacks(osg::NodeVisitor* nv)
{
osg::notify(osg::INFO)<<"Running StateSet callbacks"<<std::endl;
if (_updateCallback.valid()) (*_updateCallback)(this,nv);
if (_numChildrenRequiringUpdateTraversal!=0)
@@ -1301,16 +1446,26 @@ void StateSet::setEventCallback(Callback* ac)
_eventCallback = ac;
if (delta!=0)
if (delta!=0 && _numChildrenRequiringEventTraversal==0)
{
#if 0
for(ParentList::iterator itr=_parents.begin();
itr!=_parents.end();
++itr)
{
(*itr)->setNumChildrenRequiringEventTraversal((*itr)->getNumChildrenRequiringEventTraversal()+delta);
osg::Drawable* drawable = dynamic_cast<osg::Drawable*>(*itr);
if (drawable)
{
//drawable->setNumChildrenRequiringUpdateTraversal(drawable->getNumChildrenRequiringUpdateTraversal()+delta);
}
else
{
osg::Node* node = dynamic_cast<osg::Node*>(*itr);
if (node)
{
node->setNumChildrenRequiringEventTraversal(node->getNumChildrenRequiringEventTraversal()+delta);
}
}
}
#endif
}
}
@@ -1354,3 +1509,93 @@ void StateSet::runEventCallbacks(osg::NodeVisitor* nv)
}
}
}
void StateSet::setNumChildrenRequiringUpdateTraversal(unsigned int num)
{
// if no changes just return.
if (_numChildrenRequiringUpdateTraversal==num) return;
// note, if _updateCallback is set then the
// parents won't be affected by any changes to
// _numChildrenRequiringUpdateTraversal so no need to inform them.
if (!_updateCallback && !_parents.empty())
{
// need to pass on changes to parents.
int delta = 0;
if (_numChildrenRequiringUpdateTraversal>0) --delta;
if (num>0) ++delta;
if (delta!=0)
{
// the number of callbacks has changed, need to pass this
// on to parents so they know whether app traversal is
// reqired on this subgraph.
for(ParentList::iterator itr =_parents.begin();
itr != _parents.end();
++itr)
{
osg::Drawable* drawable = dynamic_cast<osg::Drawable*>(*itr);
if (drawable)
{
//drawable->setNumChildrenRequiringUpdateTraversal(drawable->getNumChildrenRequiringUpdateTraversal()+delta);
}
else
{
osg::Node* node = dynamic_cast<osg::Node*>(*itr);
if (node)
{
node->setNumChildrenRequiringUpdateTraversal(node->getNumChildrenRequiringUpdateTraversal()+delta);
}
}
}
}
}
// finally update this objects value.
_numChildrenRequiringUpdateTraversal=num;
}
void StateSet::setNumChildrenRequiringEventTraversal(unsigned int num)
{
// if no changes just return.
if (_numChildrenRequiringEventTraversal==num) return;
// note, if _EventCallback is set then the
// parents won't be affected by any changes to
// _numChildrenRequiringEventTraversal so no need to inform them.
if (!_eventCallback && !_parents.empty())
{
// need to pass on changes to parents.
int delta = 0;
if (_numChildrenRequiringEventTraversal>0) --delta;
if (num>0) ++delta;
if (delta!=0)
{
// the number of callbacks has changed, need to pass this
// on to parents so they know whether app traversal is
// reqired on this subgraph.
for(ParentList::iterator itr =_parents.begin();
itr != _parents.end();
++itr)
{
osg::Drawable* drawable = dynamic_cast<osg::Drawable*>(*itr);
if (drawable)
{
//drawable->setNumChildrenRequiringEventTraversal(drawable->getNumChildrenRequiringEventTraversal()+delta);
}
else
{
osg::Node* node = dynamic_cast<osg::Node*>(*itr);
if (node)
{
node->setNumChildrenRequiringEventTraversal(node->getNumChildrenRequiringEventTraversal()+delta);
}
}
}
}
}
// finally Event this objects value.
_numChildrenRequiringEventTraversal=num;
}

View File

@@ -17,6 +17,7 @@
#include <osg/Notify>
#include <osg/Uniform>
#include <osg/Program>
#include <osg/StateSet>
using namespace osg;
@@ -70,6 +71,8 @@ Uniform::Uniform( const Uniform& rhs, const CopyOp& copyop ) :
void Uniform::addParent(osg::StateSet* object)
{
osg::notify(osg::INFO)<<"Uniform Adding parent"<<std::endl;
_parents.push_back(object);
}
@@ -102,6 +105,7 @@ bool Uniform::setName( const std::string& name )
}
///////////////////////////////////////////////////////////////////////////
int Uniform::compare(const Uniform& rhs) const
@@ -749,4 +753,55 @@ void Uniform::apply(const GL2Extensions* ext, GLint location) const
}
}
void Uniform::setUpdateCallback(Callback* uc)
{
osg::notify(osg::INFO)<<"Uniform::Setting Update callbacks"<<std::endl;
if (_updateCallback==uc) return;
int delta = 0;
if (_updateCallback.valid()) --delta;
if (uc) ++delta;
_updateCallback = uc;
if (delta!=0)
{
osg::notify(osg::INFO)<<"Going to set Uniform parents"<<std::endl;
for(ParentList::iterator itr=_parents.begin();
itr!=_parents.end();
++itr)
{
osg::notify(osg::INFO)<<" setting Uniform parent"<<std::endl;
(*itr)->setNumChildrenRequiringUpdateTraversal((*itr)->getNumChildrenRequiringUpdateTraversal()+delta);
}
}
}
void Uniform::setEventCallback(Callback* ec)
{
osg::notify(osg::INFO)<<"Uniform::Setting Event callbacks"<<std::endl;
if (_updateCallback==ec) return;
int delta = 0;
if (_updateCallback.valid()) --delta;
if (ec) ++delta;
_updateCallback = ec;
if (delta!=0)
{
for(ParentList::iterator itr=_parents.begin();
itr!=_parents.end();
++itr)
{
(*itr)->setNumChildrenRequiringUpdateTraversal((*itr)->getNumChildrenRequiringUpdateTraversal()+delta);
}
}
}
/*EOF*/