From 2e10cffb4d60a408086d7ebc6fbfb2a17045e004 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 13 Apr 2005 12:00:28 +0000 Subject: [PATCH] Work in progress on shader language uniform support --- include/osg/Program | 38 +--- include/osg/State | 82 +++++-- include/osg/Uniform | 2 + src/osg/Program.cpp | 137 ++++-------- src/osg/State.cpp | 43 +++- src/osg/Uniform.cpp | 504 ++++++++++++++++++++++++-------------------- 6 files changed, 425 insertions(+), 381 deletions(-) diff --git a/include/osg/Program b/include/osg/Program index ce65fd8f8..085d82b07 100644 --- a/include/osg/Program +++ b/include/osg/Program @@ -365,26 +365,7 @@ class OSG_EXPORT Program : public osg::StateAttribute static void flushDeletedGlPrograms(unsigned int contextID,double currentTime, double& availableTime); - protected: - class ActiveUniform : public osg::Uniform - { - public: - ActiveUniform( const char* name, GLenum type, GLint loc ); - void applyData( const GL2Extensions* ext, GLuint prog ); - - protected: - virtual ~ActiveUniform() {} - const GLint _location; - - private: - ActiveUniform(); // disallowed - ActiveUniform(ActiveUniform&); // disallowed - ActiveUniform& operator=(ActiveUniform&); // disallowed - }; - typedef std::vector< osg::ref_ptr > ActiveUniformList; - - - protected: + public: // make PerContextProgram a friend to allow it access Program's protected // methods and member variables. @@ -395,6 +376,8 @@ class OSG_EXPORT Program : public osg::StateAttribute class PerContextProgram : public osg::Referenced { public: + + PerContextProgram(const Program* program, unsigned int contextID); GLuint getHandle() const {return _glProgramHandle;} @@ -406,10 +389,9 @@ class OSG_EXPORT Program : public osg::StateAttribute void getInfoLog( std::string& infoLog ) const; void useProgram() const; - void applyUniforms( osg::State& state ) const; - GLint getUniformLocation( const char* name ) const; - GLint getAttribLocation( const char* name ) const; + inline GLint getUniformLocation( const std::string& name ) const { NameLocationMap::const_iterator itr = _uniformLocationMap.find(name); return (itr!=_uniformLocationMap.end()) ? itr->second : -1; } + inline GLint getAttribLocation( const std::string& name ) const { NameLocationMap::const_iterator itr = _attribLocationMap.find(name); return (itr!=_attribLocationMap.end()) ? itr->second : -1; } protected: /*methods*/ ~PerContextProgram(); @@ -426,8 +408,10 @@ class OSG_EXPORT Program : public osg::StateAttribute /** Is our glProgram successfully linked? */ bool _isLinked; const unsigned int _contextID; - /** List of PCP's active uniforms */ - ActiveUniformList _activeUniformList; + + typedef std::map NameLocationMap; + NameLocationMap _uniformLocationMap; + NameLocationMap _attribLocationMap; private: PerContextProgram(); // disallowed @@ -435,11 +419,11 @@ class OSG_EXPORT Program : public osg::StateAttribute PerContextProgram& operator=(const PerContextProgram&); // disallowed }; + /** Get the PCP for a particular GL context */ + PerContextProgram* getPCP(unsigned int contextID) const; protected: /*methods*/ virtual ~Program(); - /** Get the PCP for a particular GL context */ - PerContextProgram* getPCP(unsigned int contextID) const; protected: /*data*/ std::string _name; diff --git a/include/osg/State b/include/osg/State index 24708d019..ed6042964 100644 --- a/include/osg/State +++ b/include/osg/State @@ -662,6 +662,12 @@ class OSG_EXPORT State : public Referenced bool isVertexBufferObjectSupported() const { return _isVertexBufferObjectSupportResolved?_isVertexBufferObjectSupported:computeVertexBufferObjectSupported(); } + void setLastAppliedProgramObject(const Program::PerContextProgram* program) { _lastAppliedProgramObject = program; } + const Program::PerContextProgram* getLastAppliedProgramObject() const { return _lastAppliedProgramObject; } + + inline GLint getUniformLocation( const std::string& name ) const { return _lastAppliedProgramObject ? getUniformLocation(name) : -1; } + inline GLint getAttribLocation( const std::string& name ) const { return _lastAppliedProgramObject ? getAttribLocation(name) : -1; } + /** Set the current OpenGL context uniqueID. Note, it is the application developers responsibility to set up unique ID for each OpenGL context. This value is @@ -693,9 +699,6 @@ class OSG_EXPORT State : public Referenced /** Get the DisplaySettings */ inline const DisplaySettings* getDisplaySettings() const { return _displaySettings.get(); } - typedef std::pair AttributePair; - typedef std::vector AttributeVec; - typedef std::vector ValueVec; /** Set flag for early termination of the draw traversal.*/ @@ -712,13 +715,6 @@ class OSG_EXPORT State : public Referenced bool checkGLErrors(StateAttribute::GLMode mode) const; bool checkGLErrors(const StateAttribute* attribute) const; - typedef std::map< std::string,ref_ptr > UniformMap; - const Uniform* findUniform( const std::string& name ) - { - UniformMap::const_iterator itr = _uniformMap.find( name ); - return (itr != _uniformMap.end()) ? itr->second.get() : 0; - } - protected: virtual ~State(); @@ -740,6 +736,8 @@ class OSG_EXPORT State : public Referenced struct ModeStack { + typedef std::vector ValueVec; + ModeStack() { changed = false; @@ -753,10 +751,11 @@ class OSG_EXPORT State : public Referenced ValueVec valueVec; }; - - struct AttributeStack { + typedef std::pair AttributeStack::AttributePair; + typedef std::vector AttributeVec; + AttributeStack() { changed = false; @@ -772,6 +771,44 @@ class OSG_EXPORT State : public Referenced }; + struct UniformStack + { + typedef std::pair UniformPair; + typedef std::vector UniformVec; + + 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 global_default_uniform; + UniformVec uniformVec; + }; + + + struct ProgramStack + { + typedef std::vector 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 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 @@ -840,18 +877,22 @@ class OSG_EXPORT State : public Referenced typedef std::map AttributeMap; typedef std::vector TextureAttributeMapList; + typedef std::map UniformMap; + typedef std::vector StateSetStack; typedef std::vector > MatrixStack; ModeMap _modeMap; AttributeMap _attributeMap; + UniformMap _uniformMap; TextureModeMapList _textureModeMapList; TextureAttributeMapList _textureAttributeMapList; - UniformMap _uniformMap; + ProgramStack _programStack; + const Program::PerContextProgram* _lastAppliedProgramObject; - StateSetStack _drawStateStack; + StateSetStack _stateStateStack; struct EnabledArrayPair { @@ -966,7 +1007,7 @@ inline void State::pushAttributeList(AttributeMap& attributeMap,const StateSet:: { // first pair so simply push incoming pair to back. as.attributeVec.push_back( - AttributePair(aitr->second.first.get(),aitr->second.second)); + AttributeStack::AttributePair(aitr->second.first.get(),aitr->second.second)); } else if ((as.attributeVec.back().second & StateAttribute::OVERRIDE) && !(aitr->second.second & StateAttribute::PROTECTED)) // check the existing override flag { @@ -977,7 +1018,7 @@ inline void State::pushAttributeList(AttributeMap& attributeMap,const StateSet:: { // no override on so simply push incoming pair to back. as.attributeVec.push_back( - AttributePair(aitr->second.first.get(),aitr->second.second)); + AttributeStack::AttributePair(aitr->second.first.get(),aitr->second.second)); } as.changed = true; } @@ -1177,7 +1218,6 @@ inline void State::applyAttributeList(AttributeMap& attributeMap,const StateSet: const StateAttribute* new_attr = ds_aitr->second.first.get(); applyAttribute(new_attr,as); - // will need to disable this mode on next apply so set it to changed. as.changed = true; ++ds_aitr; @@ -1192,7 +1232,7 @@ inline void State::applyAttributeList(AttributeMap& attributeMap,const StateSet: if (!as.attributeVec.empty() && (as.attributeVec.back().second & StateAttribute::OVERRIDE) && !(ds_aitr->second.second & StateAttribute::PROTECTED)) { - // override is on, just treat as a normal apply on modes. + // override is on, just treat as a normal apply on attribute. if (as.changed) { @@ -1203,7 +1243,7 @@ inline void State::applyAttributeList(AttributeMap& attributeMap,const StateSet: } else { - // no override on or no previous entry, therefore consider incoming mode. + // no override on or no previous entry, therefore consider incoming attribute. const StateAttribute* new_attr = ds_aitr->second.first.get(); if (applyAttribute(new_attr,as)) { @@ -1216,7 +1256,7 @@ inline void State::applyAttributeList(AttributeMap& attributeMap,const StateSet: } } - // iterator over the remaining state modes to apply any previous changes. + // iterator over the remaining state attributes to apply any previous changes. for(; this_aitr!=attributeMap.end(); ++this_aitr) @@ -1238,7 +1278,7 @@ inline void State::applyAttributeList(AttributeMap& attributeMap,const StateSet: } } - // iterator over the remaining incoming modes to apply any new mode. + // iterator over the remaining incoming attribute to apply any new attribute. for(; ds_aitr!=attributeList.end(); ++ds_aitr) diff --git a/include/osg/Uniform b/include/osg/Uniform index 6297a088d..1166cf22f 100644 --- a/include/osg/Uniform +++ b/include/osg/Uniform @@ -238,6 +238,8 @@ class OSG_EXPORT Uniform : public Object bool get( bool& b0, bool& b1 ) const; bool get( bool& b0, bool& b1, bool& b2 ) const; bool get( bool& b0, bool& b1, bool& b2, bool& b3 ) const; + + void apply(const GL2Extensions* ext, GLint location) const; protected: diff --git a/src/osg/Program.cpp b/src/osg/Program.cpp index 7a0a93670..8f3a76739 100644 --- a/src/osg/Program.cpp +++ b/src/osg/Program.cpp @@ -2050,6 +2050,7 @@ void Program::apply( osg::State& state ) const if( isFixedFunction() ) { extensions->glUseProgram( 0 ); + state.setLastAppliedProgramObject(0); return; } @@ -2058,12 +2059,13 @@ void Program::apply( osg::State& state ) const if( pcp->isLinked() ) { pcp->useProgram(); - pcp->applyUniforms( state ); + state.setLastAppliedProgramObject(pcp); } else { // program not usable, fallback to fixed function. extensions->glUseProgram( 0 ); + state.setLastAppliedProgramObject(0); } } @@ -2098,70 +2100,6 @@ void Program::getGlProgramInfoLog(unsigned int contextID, std::string& log) cons getPCP( contextID )->getInfoLog( log ); } - -/////////////////////////////////////////////////////////////////////////// -// osg::Program::ActiveUniform -/////////////////////////////////////////////////////////////////////////// - -Program::ActiveUniform::ActiveUniform( const char* name, GLenum type, GLint loc ) : - Uniform(name, static_cast(type)), _location(loc) -{ -} - -void Program::ActiveUniform::applyData( const GL2Extensions* ext, GLuint /*prog*/ ) -{ - switch( repType(getType()) ) - { - case FLOAT: - ext->glUniform1f( _location, _data.f1 ); - break; - - case FLOAT_VEC2: - ext->glUniform2fv( _location, 1, _data.f2 ); - break; - - case FLOAT_VEC3: - ext->glUniform3fv( _location, 1, _data.f3 ); - break; - - case FLOAT_VEC4: - ext->glUniform4fv( _location, 1, _data.f4 ); - break; - - case FLOAT_MAT2: - ext->glUniformMatrix2fv( _location, 1, GL_FALSE, _data.f4 ); - break; - - case FLOAT_MAT3: - ext->glUniformMatrix3fv( _location, 1, GL_FALSE, _data.f9 ); - break; - - case FLOAT_MAT4: - ext->glUniformMatrix4fv( _location, 1, GL_FALSE, _data.f16 ); - break; - - case INT: - ext->glUniform1i( _location, _data.i1 ); - break; - - case INT_VEC2: - ext->glUniform2iv( _location, 1, _data.i2 ); - break; - - case INT_VEC3: - ext->glUniform3iv( _location, 1, _data.i3 ); - break; - - case INT_VEC4: - ext->glUniform4iv( _location, 1, _data.i4 ); - break; - - default: - osg::notify(osg::FATAL) << "how got here?" << std::endl; - break; - } -} - /////////////////////////////////////////////////////////////////////////// // osg::Program::PerContextProgram // PCP is an OSG abstraction of the per-context glProgram @@ -2195,8 +2133,6 @@ void Program::PerContextProgram::linkProgram() if( ! _needsLink ) return; _needsLink = false; - _activeUniformList.clear(); - // set any explicit vertex attribute bindings const AttribBindingList& bindlist = _program->getAttribBindingList(); for( AttribBindingList::const_iterator itr = bindlist.begin(); @@ -2219,6 +2155,8 @@ void Program::PerContextProgram::linkProgram() return; } + notify(NOTICE)<<"Program "<glGetActiveUniform( _glProgramHandle, i, maxLen, 0, &size, &type, name ); GLint loc = getUniformLocation( name ); - + if( loc != -1 ) { - _activeUniformList.push_back( new ActiveUniform( name, type, loc ) ); + notify(NOTICE)<<" Active uniform "<glGetProgramiv( _glProgramHandle, GL_ACTIVE_ATTRIBUTES, &numAttrib ); + _extensions->glGetProgramiv( _glProgramHandle, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxLen ); + if( (numAttrib > 0) && (maxLen > 1) ) + { + GLint size = 0; + GLenum type = 0; + GLchar* name = new GLchar[maxLen]; + + for( GLint i = 0; i < numAttrib; ++i ) + { + _extensions->glGetActiveAttrib( _glProgramHandle, + i, maxLen, 0, &size, &type, name ); + GLint loc = getUniformLocation( name ); + + if( loc != -1 ) + { + notify(NOTICE)<<" Active attribute "<glUseProgram( _glProgramHandle ); } -GLint Program::PerContextProgram::getUniformLocation( const char* name ) const -{ - return _extensions->glGetUniformLocation( _glProgramHandle, name ); -} - -GLint Program::PerContextProgram::getAttribLocation( const char* name ) const -{ - return _extensions->glGetAttribLocation( _glProgramHandle, name ); -} - - -void Program::PerContextProgram::applyUniforms( osg::State& state ) const -{ - for( ActiveUniformList::const_iterator itr = _activeUniformList.begin(); - itr != _activeUniformList.end(); ++itr ) - { - ActiveUniform* au = const_cast( itr->get() ); - - // use name of active uniform to find a value uniform - const osg::Uniform* vu = state.findUniform( au->getName() ); - if( ! vu ) continue; - - // skip if types are not identical - if( au->getType() != vu->getType() ) continue; - - // skip if values are already identical - if( au->compareData( *vu ) == 0 ) continue; - - au->copyData( *vu ); - au->applyData( _extensions.get(), _glProgramHandle ); - } -} /*EOF*/ diff --git a/src/osg/State.cpp b/src/osg/State.cpp index dac9bb73f..3eb417761 100644 --- a/src/osg/State.cpp +++ b/src/osg/State.cpp @@ -28,7 +28,7 @@ State::State() _modelView = _identity; _abortRenderingPtr = false; - _reportGLErrors = false; + _reportGLErrors = true; _currentActiveTextureUnit=0; _currentClientActiveTextureUnit=0; @@ -41,6 +41,8 @@ State::State() _isVertexBufferObjectSupportResolved = false; _isVertexBufferObjectSupported = false; + + _lastAppliedProgramObject = 0; } State::~State() @@ -103,13 +105,29 @@ void State::reset() } } - _drawStateStack.clear(); + _stateStateStack.clear(); _modelView = _identity; _projection = _identity; dirtyAllVertexArrays(); setActiveTextureUnit(0); + + _lastAppliedProgramObject = 0; + + // what about uniforms??? need to clear them too... + // go through all active Unfirom's, setting to change to force update, + // the idea is to leave only the global defaults left. + for(UniformMap::iterator uitr=_uniformMap.begin(); + uitr!=_uniformMap.end(); + ++uitr) + { + UniformStack& us = uitr->second; + us.uniformVec.clear(); + us.last_applied_uniform = NULL; + us.changed = true; + } + } void State::setInitialViewMatrix(const osg::RefMatrix* matrix) @@ -122,7 +140,7 @@ void State::setInitialViewMatrix(const osg::RefMatrix* matrix) void State::pushStateSet(const StateSet* dstate) { - _drawStateStack.push_back(dstate); + _stateStateStack.push_back(dstate); if (dstate) { @@ -150,7 +168,7 @@ void State::pushStateSet(const StateSet* dstate) void State::popAllStateSets() { - while (!_drawStateStack.empty()) popStateSet(); + while (!_stateStateStack.empty()) popStateSet(); applyProjectionMatrix(0); applyModelViewMatrix(0); @@ -158,9 +176,9 @@ void State::popAllStateSets() void State::popStateSet() { - if (_drawStateStack.empty()) return; + if (_stateStateStack.empty()) return; - const StateSet* dstate = _drawStateStack.back(); + const StateSet* dstate = _stateStateStack.back(); if (dstate) { @@ -186,7 +204,7 @@ void State::popStateSet() } // remove the top draw state from the stack. - _drawStateStack.pop_back(); + _stateStateStack.pop_back(); } void State::captureCurrentState(StateSet& stateset) const @@ -261,6 +279,12 @@ void State::apply(const StateSet* dstate) else if (unit<_textureAttributeMapList.size()) applyAttributeMap(_textureAttributeMapList[unit]); } } + + if (_lastAppliedProgramObject) + { + osg::notify(osg::NOTICE)<<"Ready to apply uniforms A"< rhs._data.f1 ) return 1; - return 0; + case FLOAT: + if( _data.f1 < rhs._data.f1 ) return -1; + if( _data.f1 > rhs._data.f1 ) return 1; + return 0; - case FLOAT_VEC2: - if( _data.f2[0] < rhs._data.f2[0] ) return -1; - if( _data.f2[0] > rhs._data.f2[0] ) return 1; - if( _data.f2[1] < rhs._data.f2[1] ) return -1; - if( _data.f2[1] > rhs._data.f2[1] ) return 1; - return 0; + case FLOAT_VEC2: + if( _data.f2[0] < rhs._data.f2[0] ) return -1; + if( _data.f2[0] > rhs._data.f2[0] ) return 1; + if( _data.f2[1] < rhs._data.f2[1] ) return -1; + if( _data.f2[1] > rhs._data.f2[1] ) return 1; + return 0; - case FLOAT_VEC3: - if( _data.f3[0] < rhs._data.f3[0] ) return -1; - if( _data.f3[0] > rhs._data.f3[0] ) return 1; - if( _data.f3[1] < rhs._data.f3[1] ) return -1; - if( _data.f3[1] > rhs._data.f3[1] ) return 1; - if( _data.f3[2] < rhs._data.f3[2] ) return -1; - if( _data.f3[2] > rhs._data.f3[2] ) return 1; - return 0; + case FLOAT_VEC3: + if( _data.f3[0] < rhs._data.f3[0] ) return -1; + if( _data.f3[0] > rhs._data.f3[0] ) return 1; + if( _data.f3[1] < rhs._data.f3[1] ) return -1; + if( _data.f3[1] > rhs._data.f3[1] ) return 1; + if( _data.f3[2] < rhs._data.f3[2] ) return -1; + if( _data.f3[2] > rhs._data.f3[2] ) return 1; + return 0; - case FLOAT_VEC4: - case FLOAT_MAT2: - if( _data.f4[0] < rhs._data.f4[0] ) return -1; - if( _data.f4[0] > rhs._data.f4[0] ) return 1; - if( _data.f4[1] < rhs._data.f4[1] ) return -1; - if( _data.f4[1] > rhs._data.f4[1] ) return 1; - if( _data.f4[2] < rhs._data.f4[2] ) return -1; - if( _data.f4[2] > rhs._data.f4[2] ) return 1; - if( _data.f4[3] < rhs._data.f4[3] ) return -1; - if( _data.f4[3] > rhs._data.f4[3] ) return 1; - return 0; + case FLOAT_VEC4: + case FLOAT_MAT2: + if( _data.f4[0] < rhs._data.f4[0] ) return -1; + if( _data.f4[0] > rhs._data.f4[0] ) return 1; + if( _data.f4[1] < rhs._data.f4[1] ) return -1; + if( _data.f4[1] > rhs._data.f4[1] ) return 1; + if( _data.f4[2] < rhs._data.f4[2] ) return -1; + if( _data.f4[2] > rhs._data.f4[2] ) return 1; + if( _data.f4[3] < rhs._data.f4[3] ) return -1; + if( _data.f4[3] > rhs._data.f4[3] ) return 1; + return 0; - case FLOAT_MAT3: - return memcmp(_data.f9, rhs._data.f9, sizeof(_data.f9)); + case FLOAT_MAT3: + return memcmp(_data.f9, rhs._data.f9, sizeof(_data.f9)); - case FLOAT_MAT4: - return memcmp(_data.f16, rhs._data.f16, sizeof(_data.f16)); + case FLOAT_MAT4: + return memcmp(_data.f16, rhs._data.f16, sizeof(_data.f16)); - case INT: - if( _data.i1 < rhs._data.i1 ) return -1; - if( _data.i1 > rhs._data.i1 ) return 1; - return 0; + case INT: + if( _data.i1 < rhs._data.i1 ) return -1; + if( _data.i1 > rhs._data.i1 ) return 1; + return 0; - case INT_VEC2: - if( _data.i2[0] < rhs._data.i2[0] ) return -1; - if( _data.i2[0] > rhs._data.i2[0] ) return 1; - if( _data.i2[1] < rhs._data.i2[1] ) return -1; - if( _data.i2[1] > rhs._data.i2[1] ) return 1; - return 0; + case INT_VEC2: + if( _data.i2[0] < rhs._data.i2[0] ) return -1; + if( _data.i2[0] > rhs._data.i2[0] ) return 1; + if( _data.i2[1] < rhs._data.i2[1] ) return -1; + if( _data.i2[1] > rhs._data.i2[1] ) return 1; + return 0; - case INT_VEC3: - if( _data.i3[0] < rhs._data.i3[0] ) return -1; - if( _data.i3[0] > rhs._data.i3[0] ) return 1; - if( _data.i3[1] < rhs._data.i3[1] ) return -1; - if( _data.i3[1] > rhs._data.i3[1] ) return 1; - if( _data.i3[2] < rhs._data.i3[2] ) return -1; - if( _data.i3[2] > rhs._data.i3[2] ) return 1; - return 0; + case INT_VEC3: + if( _data.i3[0] < rhs._data.i3[0] ) return -1; + if( _data.i3[0] > rhs._data.i3[0] ) return 1; + if( _data.i3[1] < rhs._data.i3[1] ) return -1; + if( _data.i3[1] > rhs._data.i3[1] ) return 1; + if( _data.i3[2] < rhs._data.i3[2] ) return -1; + if( _data.i3[2] > rhs._data.i3[2] ) return 1; + return 0; - case INT_VEC4: - if( _data.i4[0] < rhs._data.i4[0] ) return -1; - if( _data.i4[0] > rhs._data.i4[0] ) return 1; - if( _data.i4[1] < rhs._data.i4[1] ) return -1; - if( _data.i4[1] > rhs._data.i4[1] ) return 1; - if( _data.i4[2] < rhs._data.i4[2] ) return -1; - if( _data.i4[2] > rhs._data.i4[2] ) return 1; - if( _data.i4[3] < rhs._data.i4[3] ) return -1; - if( _data.i4[3] > rhs._data.i4[3] ) return 1; - return 0; + case INT_VEC4: + if( _data.i4[0] < rhs._data.i4[0] ) return -1; + if( _data.i4[0] > rhs._data.i4[0] ) return 1; + if( _data.i4[1] < rhs._data.i4[1] ) return -1; + if( _data.i4[1] > rhs._data.i4[1] ) return 1; + if( _data.i4[2] < rhs._data.i4[2] ) return -1; + if( _data.i4[2] > rhs._data.i4[2] ) return 1; + if( _data.i4[3] < rhs._data.i4[3] ) return -1; + if( _data.i4[3] > rhs._data.i4[3] ) return 1; + return 0; - default: - osg::notify(osg::WARN) << "cannot compare UNDEFINED Uniform type" << std::endl; - return 0; + default: + osg::notify(osg::WARN) << "cannot compare UNDEFINED Uniform type" << std::endl; + return 0; } } @@ -203,62 +203,62 @@ void Uniform::copyData(const Uniform& rhs) int i; switch( repType(getType()) ) { - case FLOAT: - _data.f1 = rhs._data.f1; - break; + case FLOAT: + _data.f1 = rhs._data.f1; + break; - case FLOAT_VEC2: - _data.f2[0] = rhs._data.f2[0]; - _data.f2[1] = rhs._data.f2[1]; - break; + case FLOAT_VEC2: + _data.f2[0] = rhs._data.f2[0]; + _data.f2[1] = rhs._data.f2[1]; + break; - case FLOAT_VEC3: - _data.f3[0] = rhs._data.f3[0]; - _data.f3[1] = rhs._data.f3[1]; - _data.f3[2] = rhs._data.f3[2]; - break; + case FLOAT_VEC3: + _data.f3[0] = rhs._data.f3[0]; + _data.f3[1] = rhs._data.f3[1]; + _data.f3[2] = rhs._data.f3[2]; + break; - case FLOAT_VEC4: - case FLOAT_MAT2: - _data.f4[0] = rhs._data.f4[0]; - _data.f4[1] = rhs._data.f4[1]; - _data.f4[2] = rhs._data.f4[2]; - _data.f4[3] = rhs._data.f4[3]; - break; + case FLOAT_VEC4: + case FLOAT_MAT2: + _data.f4[0] = rhs._data.f4[0]; + _data.f4[1] = rhs._data.f4[1]; + _data.f4[2] = rhs._data.f4[2]; + _data.f4[3] = rhs._data.f4[3]; + break; - case FLOAT_MAT3: - for(i=0;i<9;++i) _data.f9[i]=rhs._data.f9[i]; - break; + case FLOAT_MAT3: + for(i=0;i<9;++i) _data.f9[i]=rhs._data.f9[i]; + break; - case FLOAT_MAT4: - for(i=0;i<16;++i) _data.f16[i]=rhs._data.f16[i]; - break; + case FLOAT_MAT4: + for(i=0;i<16;++i) _data.f16[i]=rhs._data.f16[i]; + break; - case INT: - _data.i1 = rhs._data.i1; - break; + case INT: + _data.i1 = rhs._data.i1; + break; - case INT_VEC2: - _data.i2[0] = rhs._data.i2[0]; - _data.i2[1] = rhs._data.i2[1]; - break; + case INT_VEC2: + _data.i2[0] = rhs._data.i2[0]; + _data.i2[1] = rhs._data.i2[1]; + break; - case INT_VEC3: - _data.i3[0] = rhs._data.i3[0]; - _data.i3[1] = rhs._data.i3[1]; - _data.i3[2] = rhs._data.i3[2]; - break; + case INT_VEC3: + _data.i3[0] = rhs._data.i3[0]; + _data.i3[1] = rhs._data.i3[1]; + _data.i3[2] = rhs._data.i3[2]; + break; - case INT_VEC4: - _data.i4[0] = rhs._data.i4[0]; - _data.i4[1] = rhs._data.i4[1]; - _data.i4[2] = rhs._data.i4[2]; - _data.i4[3] = rhs._data.i4[3]; - break; + case INT_VEC4: + _data.i4[0] = rhs._data.i4[0]; + _data.i4[1] = rhs._data.i4[1]; + _data.i4[2] = rhs._data.i4[2]; + _data.i4[3] = rhs._data.i4[3]; + break; - default: - osg::notify(osg::WARN) << "cannot copy UNDEFINED Uniform type" << std::endl; - break; + default: + osg::notify(osg::WARN) << "cannot copy UNDEFINED Uniform type" << std::endl; + break; } } @@ -269,8 +269,8 @@ bool Uniform::isCompatibleType( Type t ) const if( repType(t) == repType(getType()) ) return true; osg::notify(osg::WARN) - << "Cannot assign between Uniform types " << getTypename(t) - << " and " << getTypename(getType()) << std::endl; + << "Cannot assign between Uniform types " << getTypename(t) + << " and " << getTypename(getType()) << std::endl; return false; } @@ -281,54 +281,54 @@ const char* Uniform::getTypename( Type t ) { switch( t ) { - case FLOAT: return "float"; - case FLOAT_VEC2: return "vec2"; - case FLOAT_VEC3: return "vec3"; - case FLOAT_VEC4: return "vec4"; - case INT: return "int"; - case INT_VEC2: return "ivec2"; - case INT_VEC3: return "ivec3"; - case INT_VEC4: return "ivec4"; - case BOOL: return "bool"; - case BOOL_VEC2: return "bvec2"; - case BOOL_VEC3: return "bvec3"; - case BOOL_VEC4: return "bvec4"; - case FLOAT_MAT2: return "mat2"; - case FLOAT_MAT3: return "mat3"; - case FLOAT_MAT4: return "mat4"; - case SAMPLER_1D: return "sampler1D"; - case SAMPLER_2D: return "sampler2D"; - case SAMPLER_3D: return "sampler3D"; - case SAMPLER_CUBE: return "samplerCube"; - case SAMPLER_1D_SHADOW: return "sampler1DShadow"; - case SAMPLER_2D_SHADOW: return "sampler2DShadow"; - default: return "UNDEFINED"; + case FLOAT: return "float"; + case FLOAT_VEC2: return "vec2"; + case FLOAT_VEC3: return "vec3"; + case FLOAT_VEC4: return "vec4"; + case INT: return "int"; + case INT_VEC2: return "ivec2"; + case INT_VEC3: return "ivec3"; + case INT_VEC4: return "ivec4"; + case BOOL: return "bool"; + case BOOL_VEC2: return "bvec2"; + case BOOL_VEC3: return "bvec3"; + case BOOL_VEC4: return "bvec4"; + case FLOAT_MAT2: return "mat2"; + case FLOAT_MAT3: return "mat3"; + case FLOAT_MAT4: return "mat4"; + case SAMPLER_1D: return "sampler1D"; + case SAMPLER_2D: return "sampler2D"; + case SAMPLER_3D: return "sampler3D"; + case SAMPLER_CUBE: return "samplerCube"; + case SAMPLER_1D_SHADOW: return "sampler1DShadow"; + case SAMPLER_2D_SHADOW: return "sampler2DShadow"; + default: return "UNDEFINED"; } } Uniform::Type Uniform::getTypeId( const std::string& tname ) { - if( tname == "float" ) return FLOAT; - if( tname == "vec2" ) return FLOAT_VEC2; - if( tname == "vec3" ) return FLOAT_VEC3; - if( tname == "vec4" ) return FLOAT_VEC4; - if( tname == "int" ) return INT; - if( tname == "ivec2" ) return INT_VEC2; - if( tname == "ivec3" ) return INT_VEC3; - if( tname == "ivec4" ) return INT_VEC4; - if( tname == "bool" ) return BOOL; - if( tname == "bvec2" ) return BOOL_VEC2; - if( tname == "bvec3" ) return BOOL_VEC3; - if( tname == "bvec4" ) return BOOL_VEC4; - if( tname == "mat2" ) return FLOAT_MAT2; - if( tname == "mat3" ) return FLOAT_MAT3; - if( tname == "mat4" ) return FLOAT_MAT4; - if( tname == "sampler1D" ) return SAMPLER_1D; - if( tname == "sampler2D" ) return SAMPLER_2D; - if( tname == "sampler3D" ) return SAMPLER_3D; - if( tname == "samplerCube" ) return SAMPLER_CUBE; - if( tname == "sampler1DShadow" ) return SAMPLER_1D_SHADOW; - if( tname == "sampler2DShadow" ) return SAMPLER_2D_SHADOW; + if( tname == "float" ) return FLOAT; + if( tname == "vec2" ) return FLOAT_VEC2; + if( tname == "vec3" ) return FLOAT_VEC3; + if( tname == "vec4" ) return FLOAT_VEC4; + if( tname == "int" ) return INT; + if( tname == "ivec2" ) return INT_VEC2; + if( tname == "ivec3" ) return INT_VEC3; + if( tname == "ivec4" ) return INT_VEC4; + if( tname == "bool" ) return BOOL; + if( tname == "bvec2" ) return BOOL_VEC2; + if( tname == "bvec3" ) return BOOL_VEC3; + if( tname == "bvec4" ) return BOOL_VEC4; + if( tname == "mat2" ) return FLOAT_MAT2; + if( tname == "mat3" ) return FLOAT_MAT3; + if( tname == "mat4" ) return FLOAT_MAT4; + if( tname == "sampler1D" ) return SAMPLER_1D; + if( tname == "sampler2D" ) return SAMPLER_2D; + if( tname == "sampler3D" ) return SAMPLER_3D; + if( tname == "samplerCube" ) return SAMPLER_CUBE; + if( tname == "sampler1DShadow" ) return SAMPLER_1D_SHADOW; + if( tname == "sampler2DShadow" ) return SAMPLER_2D_SHADOW; return UNDEFINED; } @@ -336,26 +336,26 @@ Uniform::Type Uniform::repType( Type t ) { switch( t ) { - case BOOL: - case SAMPLER_1D: - case SAMPLER_2D: - case SAMPLER_3D: - case SAMPLER_CUBE: - case SAMPLER_1D_SHADOW: - case SAMPLER_2D_SHADOW: - return INT; + case BOOL: + case SAMPLER_1D: + case SAMPLER_2D: + case SAMPLER_3D: + case SAMPLER_CUBE: + case SAMPLER_1D_SHADOW: + case SAMPLER_2D_SHADOW: + return INT; - case BOOL_VEC2: - return INT_VEC2; + case BOOL_VEC2: + return INT_VEC2; - case BOOL_VEC3: - return INT_VEC3; + case BOOL_VEC3: + return INT_VEC3; - case BOOL_VEC4: - return INT_VEC4; + case BOOL_VEC4: + return INT_VEC4; - default: - return t; + default: + return t; } } @@ -364,25 +364,25 @@ Uniform::Type Uniform::repType( Type t ) // value constructors Uniform::Uniform( const char* name, float f ) : - _name(name), _type(FLOAT) + _name(name), _type(FLOAT) { set( f ); } Uniform::Uniform( const char* name, const osg::Vec2& v2 ) : - _name(name), _type(FLOAT_VEC2) + _name(name), _type(FLOAT_VEC2) { set( v2 ); } Uniform::Uniform( const char* name, const osg::Vec3& v3 ) : - _name(name), _type(FLOAT_VEC3) + _name(name), _type(FLOAT_VEC3) { set( v3 ); } Uniform::Uniform( const char* name, const osg::Vec4& v4 ) : - _name(name), _type(FLOAT_VEC4) + _name(name), _type(FLOAT_VEC4) { set( v4 ); } @@ -392,55 +392,55 @@ Uniform::Uniform( const char* name, const osg::Vec4& v4 ) : //Uniform::Uniform( const char* name, const osg::Matrix3& m3 ) Uniform::Uniform( const char* name, const osg::Matrix& m4 ) : - _name(name), _type(FLOAT_MAT4) + _name(name), _type(FLOAT_MAT4) { set( m4 ); } Uniform::Uniform( const char* name, int i ) : - _name(name), _type(INT) + _name(name), _type(INT) { set( i ); } Uniform::Uniform( const char* name, int i0, int i1 ) : - _name(name), _type(INT_VEC2) + _name(name), _type(INT_VEC2) { set( i0, i1 ); } Uniform::Uniform( const char* name, int i0, int i1, int i2 ) : - _name(name), _type(INT_VEC3) + _name(name), _type(INT_VEC3) { set( i0, i1, i2 ); } Uniform::Uniform( const char* name, int i0, int i1, int i2, int i3 ) : - _name(name), _type(INT_VEC4) + _name(name), _type(INT_VEC4) { set( i0, i1, i2, i3 ); } Uniform::Uniform( const char* name, bool b ) : - _name(name), _type(BOOL) + _name(name), _type(BOOL) { set( b ); } Uniform::Uniform( const char* name, bool b0, bool b1 ) : - _name(name), _type(BOOL_VEC2) + _name(name), _type(BOOL_VEC2) { set( b0, b1 ); } Uniform::Uniform( const char* name, bool b0, bool b1, bool b2 ) : - _name(name), _type(BOOL_VEC3) + _name(name), _type(BOOL_VEC3) { set( b0, b1, b2 ); } Uniform::Uniform( const char* name, bool b0, bool b1, bool b2, bool b3 ) : - _name(name), _type(BOOL_VEC4) + _name(name), _type(BOOL_VEC4) { set( b0, b1, b2, b3 ); } @@ -492,10 +492,10 @@ 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); + } } return true; } @@ -615,10 +615,10 @@ bool Uniform::get( osg::Matrix& m4 ) const int n = 0; for(int row=0; row<4; ++row) { - for(int col=0; col<4; ++col) - { - m4(row,col) = _data.f16[n++]; - } + for(int col=0; col<4; ++col) + { + m4(row,col) = _data.f16[n++]; + } } return true; } @@ -691,4 +691,58 @@ bool Uniform::get( bool& b0, bool& b1, bool& b2, bool& b3 ) const return true; } +void Uniform::apply(const GL2Extensions* ext, GLint location) const +{ + switch( _type ) + { + case FLOAT: + ext->glUniform1f( location, _data.f1 ); + break; + + case FLOAT_VEC2: + ext->glUniform2fv( location, 1, _data.f2 ); + break; + + case FLOAT_VEC3: + ext->glUniform3fv( location, 1, _data.f3 ); + break; + + case FLOAT_VEC4: + ext->glUniform4fv( location, 1, _data.f4 ); + break; + + case FLOAT_MAT2: + ext->glUniformMatrix2fv( location, 1, GL_FALSE, _data.f4 ); + break; + + case FLOAT_MAT3: + ext->glUniformMatrix3fv( location, 1, GL_FALSE, _data.f9 ); + break; + + case FLOAT_MAT4: + ext->glUniformMatrix4fv( location, 1, GL_FALSE, _data.f16 ); + break; + + case INT: + ext->glUniform1i( location, _data.i1 ); + break; + + case INT_VEC2: + ext->glUniform2iv( location, 1, _data.i2 ); + break; + + case INT_VEC3: + ext->glUniform3iv( location, 1, _data.i3 ); + break; + + case INT_VEC4: + ext->glUniform4iv( location, 1, _data.i4 ); + break; + + default: + osg::notify(osg::FATAL) << "how got here?" << std::endl; + break; + } +} + /*EOF*/