Added support for lazy state updating of uniforms.
This commit is contained in:
parent
e025ba39f0
commit
97daa561f4
@ -389,11 +389,41 @@ class OSG_EXPORT Program : public osg::StateAttribute
|
||||
bool getInfoLog( std::string& infoLog ) const;
|
||||
|
||||
void useProgram() const;
|
||||
|
||||
void resetAppliedUnifroms() const
|
||||
{
|
||||
for(LastAppliedUniformList::iterator itr=_lastAppliedUniformList.begin();
|
||||
itr!=_lastAppliedUniformList.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr).first = 0;
|
||||
(*itr).second = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void apply(const Uniform& uniform) const
|
||||
|
||||
inline void apply(const Uniform& uniform) const
|
||||
{
|
||||
GLint location = getUniformLocation(uniform.getName());
|
||||
if (location>=0) uniform.apply(_extensions.get(),location);
|
||||
if (location>=0)
|
||||
{
|
||||
if ((unsigned int)location>=_lastAppliedUniformList.size()) _lastAppliedUniformList.resize(location+1);
|
||||
const Uniform* lastAppliedUniform = _lastAppliedUniformList[location].first;
|
||||
if (lastAppliedUniform != &uniform)
|
||||
{
|
||||
// new attribute
|
||||
uniform.apply(_extensions.get(),location);
|
||||
_lastAppliedUniformList[location].first = &uniform;
|
||||
_lastAppliedUniformList[location].second = uniform.getModifiedCount();
|
||||
}
|
||||
else if (_lastAppliedUniformList[location].second != uniform.getModifiedCount())
|
||||
{
|
||||
// existing attribute has been modified
|
||||
uniform.apply(_extensions.get(),location);
|
||||
_lastAppliedUniformList[location].first = &uniform;
|
||||
_lastAppliedUniformList[location].second = uniform.getModifiedCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline GLint getUniformLocation( const std::string& name ) const { NameLocationMap::const_iterator itr = _uniformLocationMap.find(name); return (itr!=_uniformLocationMap.end()) ? itr->second : -1; }
|
||||
@ -418,6 +448,10 @@ class OSG_EXPORT Program : public osg::StateAttribute
|
||||
typedef std::map<std::string, GLint> NameLocationMap;
|
||||
NameLocationMap _uniformLocationMap;
|
||||
NameLocationMap _attribLocationMap;
|
||||
|
||||
typedef std::pair<const osg::Uniform*, unsigned int> UniformModifiedCountPair;
|
||||
typedef std::vector<UniformModifiedCountPair> LastAppliedUniformList;
|
||||
mutable LastAppliedUniformList _lastAppliedUniformList;
|
||||
|
||||
private:
|
||||
PerContextProgram(); // disallowed
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#ifndef GL_TEXTURE0
|
||||
@ -662,7 +663,7 @@ class OSG_EXPORT State : public Referenced
|
||||
bool isVertexBufferObjectSupported() const { return _isVertexBufferObjectSupportResolved?_isVertexBufferObjectSupported:computeVertexBufferObjectSupported(); }
|
||||
|
||||
|
||||
void setLastAppliedProgramObject(const Program::PerContextProgram* program) { _lastAppliedProgramObject = program; }
|
||||
void setLastAppliedProgramObject(const Program::PerContextProgram* program) { if (_lastAppliedProgramObject!=program) { _lastAppliedProgramObject = program; if (program) _appliedProgramObjectSet.insert(program); } }
|
||||
const Program::PerContextProgram* getLastAppliedProgramObject() const { return _lastAppliedProgramObject; }
|
||||
|
||||
inline GLint getUniformLocation( const std::string& name ) const { return _lastAppliedProgramObject ? _lastAppliedProgramObject->getUniformLocation(name) : -1; }
|
||||
@ -797,36 +798,16 @@ class OSG_EXPORT State : public Referenced
|
||||
UniformStack()
|
||||
{
|
||||
changed = false;
|
||||
last_applied_uniform = 0L;
|
||||
global_default_uniform = 0L;
|
||||
}
|
||||
|
||||
/** apply an uniform if required */
|
||||
bool changed;
|
||||
const Uniform* last_applied_uniform;
|
||||
ref_ptr<const Uniform> global_default_uniform;
|
||||
UniformVec uniformVec;
|
||||
};
|
||||
|
||||
|
||||
struct ProgramStack
|
||||
{
|
||||
typedef std::vector<const Program*> ProgramVec;
|
||||
|
||||
ProgramStack()
|
||||
{
|
||||
changed = false;
|
||||
last_applied_program = 0L;
|
||||
global_default_program = 0L;
|
||||
}
|
||||
|
||||
/** apply an program if required */
|
||||
bool changed;
|
||||
const Program* last_applied_program;
|
||||
ref_ptr<const Program> global_default_program;
|
||||
ProgramVec programVec;
|
||||
};
|
||||
|
||||
/** Apply an OpenGL mode if required, passing in mode, enable flag and
|
||||
* appropriate mode stack. This is a wrapper around \c glEnable() and
|
||||
* \c glDisable(), that just actually calls these functions if the
|
||||
@ -899,6 +880,8 @@ class OSG_EXPORT State : public Referenced
|
||||
|
||||
typedef std::vector<const StateSet*> StateSetStack;
|
||||
typedef std::vector<ref_ptr<const Matrix> > MatrixStack;
|
||||
|
||||
typedef std::set<osg::ref_ptr<const Program::PerContextProgram> > AppliedProgramObjectSet;
|
||||
|
||||
ModeMap _modeMap;
|
||||
AttributeMap _attributeMap;
|
||||
@ -907,7 +890,7 @@ class OSG_EXPORT State : public Referenced
|
||||
TextureModeMapList _textureModeMapList;
|
||||
TextureAttributeMapList _textureAttributeMapList;
|
||||
|
||||
ProgramStack _programStack;
|
||||
AppliedProgramObjectSet _appliedProgramObjectSet;
|
||||
const Program::PerContextProgram* _lastAppliedProgramObject;
|
||||
|
||||
StateSetStack _stateStateStack;
|
||||
|
@ -300,6 +300,12 @@ class OSG_EXPORT Uniform : public Object
|
||||
/** Get the const EventCallback.*/
|
||||
const Callback* getEventCallback() const { return _eventCallback.get(); }
|
||||
|
||||
/** Increment the modified count on the Uniform so ProgramObjects watching it know it update themselves.
|
||||
* note, autoatmatically call bet Uniform::set(*). */
|
||||
inline void dirty() { ++_modifiedCount; }
|
||||
|
||||
inline void setModifiedCount(unsigned int mc) { _modifiedCount = mc; }
|
||||
inline unsigned int getModifiedCount() const { return _modifiedCount; }
|
||||
|
||||
|
||||
void apply(const GL2Extensions* ext, GLint location) const;
|
||||
@ -335,6 +341,8 @@ class OSG_EXPORT Uniform : public Object
|
||||
|
||||
ref_ptr<Callback> _updateCallback;
|
||||
ref_ptr<Callback> _eventCallback;
|
||||
|
||||
unsigned int _modifiedCount;
|
||||
|
||||
};
|
||||
|
||||
|
@ -51,6 +51,7 @@ State::~State()
|
||||
|
||||
void State::reset()
|
||||
{
|
||||
|
||||
/*
|
||||
for(ModeMap::iterator mitr=_modeMap.begin();
|
||||
mitr!=_modeMap.end();
|
||||
@ -114,6 +115,16 @@ void State::reset()
|
||||
setActiveTextureUnit(0);
|
||||
|
||||
_lastAppliedProgramObject = 0;
|
||||
|
||||
for(AppliedProgramObjectSet::iterator apitr=_appliedProgramObjectSet.begin();
|
||||
apitr!=_appliedProgramObjectSet.end();
|
||||
++apitr)
|
||||
{
|
||||
(*apitr)->resetAppliedUnifroms();
|
||||
}
|
||||
|
||||
_appliedProgramObjectSet.clear();
|
||||
|
||||
|
||||
// what about uniforms??? need to clear them too...
|
||||
// go through all active Unfirom's, setting to change to force update,
|
||||
@ -124,7 +135,6 @@ void State::reset()
|
||||
{
|
||||
UniformStack& us = uitr->second;
|
||||
us.uniformVec.clear();
|
||||
us.last_applied_uniform = NULL;
|
||||
us.changed = true;
|
||||
}
|
||||
|
||||
|
@ -28,14 +28,14 @@ using namespace osg;
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Uniform::Uniform() :
|
||||
_name(""), _type(UNDEFINED)
|
||||
_name(""), _type(UNDEFINED),_modifiedCount(0)
|
||||
{
|
||||
setDataVariance(STATIC);
|
||||
}
|
||||
|
||||
|
||||
Uniform::Uniform( const char* name, Type type ) :
|
||||
_name(name), _type(type)
|
||||
_name(name), _type(type),_modifiedCount(0)
|
||||
{
|
||||
setDataVariance(STATIC);
|
||||
|
||||
@ -91,8 +91,8 @@ bool Uniform::setType( Type t )
|
||||
{
|
||||
if( _type != UNDEFINED )
|
||||
{
|
||||
osg::notify(osg::WARN) << "cannot change Uniform type" << std::endl;
|
||||
return false;
|
||||
osg::notify(osg::WARN) << "cannot change Uniform type" << std::endl;
|
||||
return false;
|
||||
}
|
||||
_type = t;
|
||||
return true;
|
||||
@ -102,8 +102,8 @@ bool Uniform::setName( const std::string& name )
|
||||
{
|
||||
if( _name != "" )
|
||||
{
|
||||
osg::notify(osg::WARN) << "cannot change Uniform name" << std::endl;
|
||||
return false;
|
||||
osg::notify(osg::WARN) << "cannot change Uniform name" << std::endl;
|
||||
return false;
|
||||
}
|
||||
_name = name;
|
||||
return true;
|
||||
@ -273,6 +273,8 @@ void Uniform::copyData(const Uniform& rhs)
|
||||
osg::notify(osg::WARN) << "cannot copy UNDEFINED Uniform type" << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
dirty();
|
||||
}
|
||||
|
||||
bool Uniform::isCompatibleType( Type t ) const
|
||||
@ -465,6 +467,7 @@ bool Uniform::set( float f )
|
||||
{
|
||||
if( ! isCompatibleType(FLOAT) ) return false;
|
||||
_data.f1 = f;
|
||||
dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -473,6 +476,7 @@ bool Uniform::set( const osg::Vec2& v2 )
|
||||
if( ! isCompatibleType(FLOAT_VEC2) ) return false;
|
||||
_data.f2[0] = v2.x();
|
||||
_data.f2[1] = v2.y();
|
||||
dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -482,6 +486,7 @@ bool Uniform::set( const osg::Vec3& v3 )
|
||||
_data.f3[0] = v3.x();
|
||||
_data.f3[1] = v3.y();
|
||||
_data.f3[2] = v3.z();
|
||||
dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -492,6 +497,7 @@ bool Uniform::set( const osg::Vec4& v4 )
|
||||
_data.f4[1] = v4.y();
|
||||
_data.f4[2] = v4.z();
|
||||
_data.f4[3] = v4.w();
|
||||
dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -505,11 +511,12 @@ bool Uniform::set( const osg::Matrix& m4 )
|
||||
int n = 0;
|
||||
for(int row=0; row<4; ++row)
|
||||
{
|
||||
for(int col=0; col<4; ++col)
|
||||
{
|
||||
_data.f16[n++] = m4(row,col);
|
||||
}
|
||||
for(int col=0; col<4; ++col)
|
||||
{
|
||||
_data.f16[n++] = m4(row,col);
|
||||
}
|
||||
}
|
||||
dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -517,6 +524,7 @@ bool Uniform::set( int i )
|
||||
{
|
||||
if( ! isCompatibleType(INT) ) return false;
|
||||
_data.i1 = i;
|
||||
dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -525,6 +533,7 @@ bool Uniform::set( int i0, int i1 )
|
||||
if( ! isCompatibleType(INT_VEC2) ) return false;
|
||||
_data.i2[0] = i0;
|
||||
_data.i2[1] = i1;
|
||||
dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -534,6 +543,7 @@ bool Uniform::set( int i0, int i1, int i2 )
|
||||
_data.i3[0] = i0;
|
||||
_data.i3[1] = i1;
|
||||
_data.i3[2] = i2;
|
||||
dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -544,6 +554,7 @@ bool Uniform::set( int i0, int i1, int i2, int i3 )
|
||||
_data.i4[1] = i1;
|
||||
_data.i4[2] = i2;
|
||||
_data.i4[3] = i3;
|
||||
dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -551,6 +562,7 @@ bool Uniform::set( bool b )
|
||||
{
|
||||
if( ! isCompatibleType(BOOL) ) return false;
|
||||
_data.i1 = b;
|
||||
dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -559,6 +571,7 @@ bool Uniform::set( bool b0, bool b1 )
|
||||
if( ! isCompatibleType(BOOL_VEC2) ) return false;
|
||||
_data.i2[0] = b0;
|
||||
_data.i2[1] = b1;
|
||||
dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -568,6 +581,7 @@ bool Uniform::set( bool b0, bool b1, bool b2 )
|
||||
_data.i3[0] = b0;
|
||||
_data.i3[1] = b1;
|
||||
_data.i3[2] = b2;
|
||||
dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -578,6 +592,7 @@ bool Uniform::set( bool b0, bool b1, bool b2, bool b3 )
|
||||
_data.i4[1] = b1;
|
||||
_data.i4[2] = b2;
|
||||
_data.i4[3] = b3;
|
||||
dirty();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user