Futher work on supporting update and event callbacks in StateSet, Uniform and StateAttribute
This commit is contained in:
@@ -224,20 +224,26 @@ static osg::Program* MarbleProgram;
|
||||
static osg::Shader* MarbleVertObj;
|
||||
static osg::Shader* MarbleFragObj;
|
||||
|
||||
static osg::Uniform* OffsetUniform;
|
||||
static osg::Uniform* SineUniform;
|
||||
static osg::Uniform* Color1Uniform;
|
||||
static osg::Uniform* Color2Uniform;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// for demo simplicity, this one callback animates all the shaders.
|
||||
// for demo simplicity, this one callback animates all the shaders, instancing
|
||||
// for each uniform but with a specific operation each time.
|
||||
|
||||
class AnimateCallback: public osg::NodeCallback
|
||||
class AnimateCallback: public osg::Uniform::Callback
|
||||
{
|
||||
public:
|
||||
AnimateCallback() : osg::NodeCallback(), _enabled(true) {}
|
||||
|
||||
enum Operation
|
||||
{
|
||||
OFFSET,
|
||||
SIN,
|
||||
COLOR1,
|
||||
COLOR2
|
||||
};
|
||||
|
||||
AnimateCallback(Operation op) : _enabled(true),_operation(op) {}
|
||||
|
||||
virtual void operator() ( osg::Node* node, osg::NodeVisitor* nv )
|
||||
virtual void operator() ( osg::Uniform* uniform, osg::NodeVisitor* nv )
|
||||
{
|
||||
if( _enabled )
|
||||
{
|
||||
@@ -245,17 +251,19 @@ class AnimateCallback: public osg::NodeCallback
|
||||
float sine = sinf( angle ); // -1 -> 1
|
||||
float v01 = 0.5f * sine + 0.5f; // 0 -> 1
|
||||
float v10 = 1.0f - v01; // 1 -> 0
|
||||
|
||||
OffsetUniform->set( osg::Vec3(0.505f, 0.8f*v01, 0.0f) );
|
||||
SineUniform->set( sine );
|
||||
Color1Uniform->set( osg::Vec3(v10, 0.0f, 0.0f) );
|
||||
Color2Uniform->set( osg::Vec3(v01, v01, v10) );
|
||||
switch(_operation)
|
||||
{
|
||||
case OFFSET : uniform->set( osg::Vec3(0.505f, 0.8f*v01, 0.0f) ); break;
|
||||
case SIN : uniform->set( sine ); break;
|
||||
case COLOR1 : uniform->set( osg::Vec3(v10, 0.0f, 0.0f) ); break;
|
||||
case COLOR2 : uniform->set( osg::Vec3(v01, v01, v10) ); break;
|
||||
}
|
||||
}
|
||||
traverse(node, nv);
|
||||
}
|
||||
|
||||
private:
|
||||
bool _enabled;
|
||||
Operation _operation;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
@@ -272,20 +280,28 @@ GL2Scene::buildScene()
|
||||
|
||||
// the root of our scenegraph.
|
||||
rootNode = new osg::Group;
|
||||
rootNode->setUpdateCallback( new AnimateCallback );
|
||||
//rootNode->setUpdateCallback( new AnimateCallback );
|
||||
|
||||
// attach some Uniforms to the root, to be inherited by Programs.
|
||||
{
|
||||
OffsetUniform = new osg::Uniform( "Offset", osg::Vec3(0.0f, 0.0f, 0.0f) );
|
||||
SineUniform = new osg::Uniform( "Sine", 0.0f );
|
||||
Color1Uniform = new osg::Uniform( "Color1", osg::Vec3(0.0f, 0.0f, 0.0f) );
|
||||
Color2Uniform = new osg::Uniform( "Color2", osg::Vec3(0.0f, 0.0f, 0.0f) );
|
||||
osg::Uniform* OffsetUniform = new osg::Uniform( "Offset", osg::Vec3(0.0f, 0.0f, 0.0f) );
|
||||
osg::Uniform* SineUniform = new osg::Uniform( "Sine", 0.0f );
|
||||
osg::Uniform* Color1Uniform = new osg::Uniform( "Color1", osg::Vec3(0.0f, 0.0f, 0.0f) );
|
||||
osg::Uniform* Color2Uniform = new osg::Uniform( "Color2", osg::Vec3(0.0f, 0.0f, 0.0f) );
|
||||
|
||||
OffsetUniform->setUpdateCallback(new AnimateCallback(AnimateCallback::OFFSET));
|
||||
SineUniform->setUpdateCallback(new AnimateCallback(AnimateCallback::SIN));
|
||||
Color1Uniform->setUpdateCallback(new AnimateCallback(AnimateCallback::COLOR1));
|
||||
Color2Uniform->setUpdateCallback(new AnimateCallback(AnimateCallback::COLOR2));
|
||||
|
||||
osg::StateSet* ss = rootNode->getOrCreateStateSet();
|
||||
ss->addUniform( OffsetUniform );
|
||||
ss->addUniform( SineUniform );
|
||||
ss->addUniform( Color1Uniform );
|
||||
ss->addUniform( Color2Uniform );
|
||||
|
||||
|
||||
//ss->setUpdateCallback(new AnimateCallback2);
|
||||
}
|
||||
|
||||
// the simple Microshader (its source appears earlier in this file)
|
||||
|
||||
@@ -276,6 +276,7 @@ class OSG_EXPORT Node : public Object
|
||||
ParentList _parents;
|
||||
friend class osg::Group;
|
||||
friend class osg::Drawable;
|
||||
friend class osg::StateSet;
|
||||
|
||||
ref_ptr<NodeCallback> _updateCallback;
|
||||
unsigned int _numChildrenRequiringUpdateTraversal;
|
||||
|
||||
@@ -45,8 +45,8 @@ class OSG_EXPORT Shader : public osg::Object
|
||||
UNDEFINED = -1
|
||||
};
|
||||
|
||||
Shader();
|
||||
Shader( Type type, const char* sourceText = 0 );
|
||||
Shader( Type type = UNDEFINED);
|
||||
Shader( Type type, const std::string& source );
|
||||
|
||||
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
|
||||
Shader(const Shader& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
|
||||
@@ -56,12 +56,17 @@ class OSG_EXPORT Shader : public osg::Object
|
||||
int compare(const Shader& rhs) const;
|
||||
|
||||
bool setType( Type t );
|
||||
|
||||
|
||||
/** Load the Shader's source code text from a string. */
|
||||
void setShaderSource( const char* sourceText );
|
||||
void setShaderSource( const std::string& sourceText );
|
||||
|
||||
/** Read shader source from file and then constructor shader of specified type.
|
||||
* Return the resulting Shader or 0 if no valid shader source code be read.*/
|
||||
static Shader* readShaderFile( Type type, const std::string& fileName );
|
||||
|
||||
/** Load the Shader's source code text from a file. */
|
||||
bool loadShaderSourceFromFile( const char* fileName );
|
||||
bool loadShaderSourceFromFile( const std::string& fileName );
|
||||
|
||||
/** Query the shader's source code text */
|
||||
inline const std::string& getShaderSource() const { return _shaderSource; }
|
||||
|
||||
@@ -282,7 +282,7 @@ class OSG_EXPORT StateAttribute : public Object
|
||||
};
|
||||
|
||||
/** Set the UpdateCallback which allows users to attach customize the updating of an object during the update traversal.*/
|
||||
void setUpdateCallback(Callback* uc) { _updateCallback = uc; }
|
||||
void setUpdateCallback(Callback* uc);
|
||||
|
||||
/** Get the non const UpdateCallback.*/
|
||||
Callback* getUpdateCallback() { return _updateCallback.get(); }
|
||||
@@ -292,7 +292,7 @@ class OSG_EXPORT StateAttribute : public Object
|
||||
|
||||
|
||||
/** Set the EventCallback which allows users to attach customize the updating of an object during the Event traversal.*/
|
||||
void setEventCallback(Callback* ec) { _eventCallback = ec; }
|
||||
void setEventCallback(Callback* ec);
|
||||
|
||||
/** Get the non const EventCallback.*/
|
||||
Callback* getEventCallback() { return _eventCallback.get(); }
|
||||
|
||||
@@ -454,6 +454,8 @@ class OSG_EXPORT StateSet : public Object
|
||||
ParentList _parents;
|
||||
friend class osg::Node;
|
||||
friend class osg::Drawable;
|
||||
friend class osg::Uniform;
|
||||
friend class osg::StateAttribute;
|
||||
|
||||
ModeList _modeList;
|
||||
AttributeList _attributeList;
|
||||
|
||||
@@ -280,7 +280,7 @@ class OSG_EXPORT Uniform : public Object
|
||||
};
|
||||
|
||||
/** Set the UpdateCallback which allows users to attach customize the updating of an object during the update traversal.*/
|
||||
void setUpdateCallback(Callback* uc) { _updateCallback = uc; }
|
||||
void setUpdateCallback(Callback* uc);
|
||||
|
||||
/** Get the non const UpdateCallback.*/
|
||||
Callback* getUpdateCallback() { return _updateCallback.get(); }
|
||||
@@ -290,7 +290,7 @@ class OSG_EXPORT Uniform : public Object
|
||||
|
||||
|
||||
/** Set the EventCallback which allows users to attach customize the updating of an object during the Event traversal.*/
|
||||
void setEventCallback(Callback* ec) { _eventCallback = ec; }
|
||||
void setEventCallback(Callback* ec);
|
||||
|
||||
/** Get the non const EventCallback.*/
|
||||
Callback* getEventCallback() { return _eventCallback.get(); }
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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*/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user