diff --git a/examples/osgshaders/GL2Scene.cpp b/examples/osgshaders/GL2Scene.cpp index 8f39b8662..e69ddc874 100644 --- a/examples/osgshaders/GL2Scene.cpp +++ b/examples/osgshaders/GL2Scene.cpp @@ -10,8 +10,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ -/* file: examples/osgshaders/GL2Scene.cpp - * author: Mike Weiblen 2005-05-01 +/* file: examples/osgshaders/GL2Scene.cpp + * author: Mike Weiblen 2006-05-14 * * Compose a scene of several instances of a model, with a different * OpenGL Shading Language shader applied to each. @@ -166,7 +166,7 @@ static const char *microshaderFragSource = { static osg::ref_ptr rootNode; -// Create some geometry upon which to render GL2 shaders. +// Create some geometry upon which to render GLSL shaders. static osg::Geode* CreateModel() { @@ -267,7 +267,7 @@ class AnimateCallback: public osg::Uniform::Callback }; /////////////////////////////////////////////////////////////////////////// -// Compose a scenegraph with examples of GL2 shaders +// Compose a scenegraph with examples of GLSL shaders #define TEXUNIT_SINE 1 #define TEXUNIT_NOISE 2 @@ -280,7 +280,6 @@ GL2Scene::buildScene() // the root of our scenegraph. rootNode = new osg::Group; - //rootNode->setUpdateCallback( new AnimateCallback ); // attach some Uniforms to the root, to be inherited by Programs. { @@ -299,9 +298,6 @@ GL2Scene::buildScene() ss->addUniform( SineUniform ); ss->addUniform( Color1Uniform ); ss->addUniform( Color2Uniform ); - - - //ss->setUpdateCallback(new AnimateCallback2); } // the simple Microshader (its source appears earlier in this file) @@ -362,6 +358,16 @@ GL2Scene::buildScene() ss->addUniform( new osg::Uniform("NoiseTex", TEXUNIT_NOISE) ); ss->addUniform( new osg::Uniform("SineTex", TEXUNIT_SINE) ); + + osg::Uniform* MarbleColor = new osg::Uniform( osg::Uniform::FLOAT_VEC3, "MarbleColor[0]", 2 ); + MarbleColor->setElement( 0, osg::Vec3( 0.7, 0.7, 0.7 ) ); + MarbleColor->setElement( 1, osg::Vec3( 0.2, 0.2, 0.2 ) ); + ss->addUniform( MarbleColor ); + + osg::Uniform* VeinColor = new osg::Uniform( osg::Uniform::FLOAT_VEC3, "VeinColor[0]", 2 ); + VeinColor->setElement( 0, osg::Vec3( 0.0, 0.15, 0.0 ) ); + VeinColor->setElement( 1, osg::Vec3( 0.9, 0.95, 0.9 ) ); + ss->addUniform( VeinColor ); } #ifdef INTERNAL_3DLABS //[ diff --git a/include/osg/StateSet b/include/osg/StateSet index c0378e5f0..ab4b35265 100644 --- a/include/osg/StateSet +++ b/include/osg/StateSet @@ -281,7 +281,7 @@ class OSG_EXPORT StateSet : public Object Uniform* getUniform(const std::string& name); /** Get Uniform for specified name, if one is not available create it, add it to this StateSet and return a pointer to it.*/ - Uniform* getOrCreateUniform(const std::string& name, Uniform::Type type); + Uniform* getOrCreateUniform(const std::string& name, Uniform::Type type, int numElements=1); /** Get const Uniform for specified name. * Returns NULL if no matching Uniform is contained within StateSet.*/ diff --git a/include/osg/Uniform b/include/osg/Uniform index 0d5401601..ad076265d 100644 --- a/include/osg/Uniform +++ b/include/osg/Uniform @@ -1,4 +1,4 @@ -/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * Copyright (C) 2003-2005 3Dlabs Inc. Ltd. * * This application is open source and may be redistributed and/or modified @@ -11,13 +11,14 @@ */ /* file: include/osg/Uniform - * author: Mike Weiblen 2005-06-03 + * author: Mike Weiblen 2006-05-14 */ #ifndef OSG_UNIFORM #define OSG_UNIFORM 1 #include +#include #include #include #include @@ -169,7 +170,7 @@ class OSG_EXPORT Uniform : public Object public: Uniform(); - Uniform( Type type, const std::string& name ); + Uniform( Type type, const std::string& name, int numElements=1 ); /** Copy constructor using CopyOp to manage deep vs shallow copy. */ Uniform(const Uniform& rhs, const CopyOp& copyop=CopyOp::SHALLOW_COPY); @@ -177,27 +178,41 @@ class OSG_EXPORT Uniform : public Object META_Object(osg, Uniform); - - - /** Set the type of glUniform. */ + /** Set the type of glUniform, ensuring it is only set once.*/ bool setType( Type t ); /** Get the type of glUniform as enum. */ const Type getType() const { return _type; } - /** Set the name of the glUniform, checking to make sure its only set once.*/ + /** Set the name of the glUniform, ensuring it is only set once.*/ void setName( const std::string& name ); + /** Set the length of a uniform array, ensuring it is only set once.*/ + void setNumElements( unsigned int numElements ); + + /** Get the number of GLSL elements of the osg::Uniform (>1 == array) */ + unsigned int getNumElements() const { return _numElements; } + + /** Get the number of elements required for the internal scalar data array. + * Returns 0 if the osg::Uniform is not properly configured. */ + unsigned int getInternalArrayNumElements() const; + /** Return the name of a Type enum as string. */ static const char* getTypename( Type t ); + /** Return the the number of scalar components for a GLSL type. */ + static int getTypeNumComponents( Type t ); + /** Return the Type enum of a Uniform typename string */ static Uniform::Type getTypeId( const std::string& tname ); /** Return the GL API type corresponding to a GLSL type */ static Type getGlApiType( Type t ); - /** convenient construction w/ assignment */ + /** Return the internal scalar data array type corresponding to a GLSL type */ + static GLenum getInternalArrayType( Type t ); + + /** convenient single-element constructors w/ assignment */ explicit Uniform( const char* name, float f ); explicit Uniform( const char* name, int i ); explicit Uniform( const char* name, bool b ); @@ -251,7 +266,7 @@ class OSG_EXPORT Uniform : public Object inline unsigned int getNumParents() const { return _parents.size(); } - /** value assignment */ + /** convenient single-element value assignment; may only be used w/ Uniforms where isScalar()==TRUE */ bool set( float f ); bool set( int i ); bool set( bool b ); @@ -269,7 +284,7 @@ class OSG_EXPORT Uniform : public Object bool set( bool b0, bool b1, bool b2 ); bool set( bool b0, bool b1, bool b2, bool b3 ); - /** value query */ + /** convenient single-element value query; may only be used w/ Uniforms where isScalar()==TRUE */ bool get( float& f ) const; bool get( int& i ) const; bool get( bool& b ) const; @@ -286,7 +301,13 @@ 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; - + + /** value assignment for array uniforms */ + bool setElement( unsigned int index, float f ); + bool setElement( unsigned int index, const osg::Vec2& v2 ); + bool setElement( unsigned int index, const osg::Vec3& v3 ); + bool setElement( unsigned int index, const osg::Vec4& v4 ); + struct Callback : public virtual osg::Object { @@ -319,10 +340,20 @@ 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(*). */ + /** Increment the modified count on the Uniform so Programs watching it know it update themselves. + * note: autotomatically called by Uniform::set(*); + * you must call if modify a data array directly. */ inline void dirty() { ++_modifiedCount; } + bool setArray( FloatArray* array ); + bool setArray( IntArray* array ); + + FloatArray* getFloatArray() { return _floatArray.get(); } + const FloatArray* getFloatArray() const { return _floatArray.get(); } + + IntArray* getIntArray() { return _intArray.get(); } + const IntArray* getIntArray() const { return _intArray.get(); } + inline void setModifiedCount(unsigned int mc) { _modifiedCount = mc; } inline unsigned int getModifiedCount() const { return _modifiedCount; } @@ -336,6 +367,8 @@ class OSG_EXPORT Uniform : public Object Uniform& operator=(const Uniform&) { return *this; } bool isCompatibleType( Type t ) const; + bool isScalar() const { return _numElements==1; } + void allocateDataArray(); void addParent(osg::StateSet* object); void removeParent(osg::StateSet* object); @@ -343,27 +376,18 @@ class OSG_EXPORT Uniform : public Object ParentList _parents; friend class osg::StateSet; - Type _type; + Type _type; + unsigned int _numElements; - union - { - GLfloat f1; // float - GLfloat f2[2]; // vec2 - GLfloat f3[3]; // vec3 - GLfloat f4[4]; // vec4, mat2 - GLfloat f9[9]; // mat3 - GLfloat f16[16]; // mat4 - GLint i1; // int, bool, sampler* - GLint i2[2]; // ivec2, bvec2 - GLint i3[3]; // ivec3, bvec3 - GLint i4[4]; // ivec4, bvec4 - } _data; + // The internal data for osg::Uniforms are stored as an array of + // getInternalArrayType() of length getInternalArrayNumElements(). + ref_ptr _floatArray; + ref_ptr _intArray; ref_ptr _updateCallback; ref_ptr _eventCallback; unsigned int _modifiedCount; - }; } diff --git a/src/osg/StateSet.cpp b/src/osg/StateSet.cpp index ae225ed85..cc7ce2528 100644 --- a/src/osg/StateSet.cpp +++ b/src/osg/StateSet.cpp @@ -924,7 +924,7 @@ Uniform* StateSet::getUniform(const std::string& name) else return 0; } -Uniform* StateSet::getOrCreateUniform(const std::string& name, Uniform::Type type) +Uniform* StateSet::getOrCreateUniform(const std::string& name, Uniform::Type type, int numElements) { // for look for an appropriate uniform. UniformList::iterator itr = _uniformList.find(name); @@ -936,7 +936,7 @@ Uniform* StateSet::getOrCreateUniform(const std::string& name, Uniform::Type typ // no uniform found matching name so create it.. - Uniform* uniform = new Uniform(type,name); + Uniform* uniform = new Uniform(type,name,numElements); addUniform(uniform); return uniform; diff --git a/src/osg/Uniform.cpp b/src/osg/Uniform.cpp index 96395ff5f..8271a6f3d 100644 --- a/src/osg/Uniform.cpp +++ b/src/osg/Uniform.cpp @@ -1,4 +1,4 @@ -/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * Copyright (C) 2003-2005 3Dlabs Inc. Ltd. * * This application is open source and may be redistributed and/or modified @@ -11,7 +11,7 @@ */ /* file: src/osg/Uniform.cpp - * author: Mike Weiblen 2005-06-03 + * author: Mike Weiblen 2006-05-14 */ #include @@ -28,45 +28,19 @@ using namespace osg; /////////////////////////////////////////////////////////////////////////// Uniform::Uniform() : - _type(UNDEFINED), _modifiedCount(0) + _type(UNDEFINED), _numElements(0), _modifiedCount(0) { setDataVariance(STATIC); } -Uniform::Uniform( Type type, const std::string& name ) : - _type(type), _modifiedCount(0) +Uniform::Uniform( Type type, const std::string& name, int numElements ) : + _type(type), _numElements(0), _modifiedCount(0) { setName(name); + setNumElements(numElements); setDataVariance(STATIC); - - switch( _type ) - { - case FLOAT: set( 0.0f ); break; - case FLOAT_VEC2: set( osg::Vec2() ); break; - case FLOAT_VEC3: set( osg::Vec3() ); break; - case FLOAT_VEC4: set( osg::Vec4() ); break; - case INT: set( 0 ); break; - case INT_VEC2: set( 0, 0 ); break; - case INT_VEC3: set( 0, 0, 0 ); break; - case INT_VEC4: set( 0, 0, 0, 0 ); break; - case BOOL: set( false ); break; - case BOOL_VEC2: set( false, false ); break; - case BOOL_VEC3: set( false, false, false ); break; - case BOOL_VEC4: set( false, false, false, false ); break; - case FLOAT_MAT2: set( osg::Matrix2() ); break; - case FLOAT_MAT3: set( osg::Matrix3() ); break; - case FLOAT_MAT4: set( osg::Matrixf() ); break; - case SAMPLER_1D: set( 0 ); break; - case SAMPLER_2D: set( 0 ); break; - case SAMPLER_3D: set( 0 ); break; - case SAMPLER_CUBE: set( 0 ); break; - case SAMPLER_1D_SHADOW: set( 0 ); break; - case SAMPLER_2D_SHADOW: set( 0 ); break; - default: - osg::notify(osg::WARN) << "UNDEFINED Uniform type" << std::endl; - break; - } + allocateDataArray(); } Uniform::Uniform( const Uniform& rhs, const CopyOp& copyop ) : @@ -102,6 +76,7 @@ bool Uniform::setType( Type t ) return false; } _type = t; + allocateDataArray(); return true; } @@ -115,6 +90,88 @@ void Uniform::setName( const std::string& name ) _name = name; } +void Uniform::setNumElements( unsigned int numElements ) +{ + if( numElements < 1 ) + { + osg::notify(osg::WARN) << "Uniform numElements < 1 is invalid" << std::endl; + return; + } + + if (numElements == _numElements) return; + + if( _numElements>0 ) + { + osg::notify(osg::WARN) << "Warning: Uniform::setNumElements() cannot change Uniform numElements, size already fixed." << std::endl; + return; + } + + _numElements = numElements; + allocateDataArray(); +} + +void Uniform::allocateDataArray() +{ + // if one array is already allocated, the job is done. + if( _floatArray.valid() != _intArray.valid() ) return; + + // array cannot be created until _type and _numElements are specified + int arrayNumElements = getInternalArrayNumElements(); + if( arrayNumElements ) + { + switch( getInternalArrayType(getType()) ) + { + case GL_FLOAT: + _floatArray = new FloatArray(arrayNumElements); + _intArray = 0; + return; + + case GL_INT: + _intArray = new IntArray(arrayNumElements); + _floatArray = 0; + return; + + default: + break; + } + } + _floatArray = 0; + _intArray = 0; +} + +bool Uniform::setArray( FloatArray* array ) +{ + if( !array ) return false; + + // incoming array must match configuration of the Uniform + if( getInternalArrayType(getType())!=GL_FLOAT || getInternalArrayNumElements()!=array->getNumElements() ) + { + osg::notify(osg::WARN) << "Uniform::setArray : incompatible array" << std::endl; + return false; + } + + _floatArray = array; + _intArray = 0; + dirty(); + return true; +} + +bool Uniform::setArray( IntArray* array ) +{ + if( !array ) return false; + + // incoming array must match configuration of the Uniform + if( getInternalArrayType(getType())!=GL_INT || getInternalArrayNumElements()!=array->getNumElements() ) + { + osg::notify(osg::WARN) << "Uniform::setArray : incompatible array" << std::endl; + return false; + } + + _intArray = array; + _floatArray = 0; + dirty(); + return true; +} /////////////////////////////////////////////////////////////////////////// @@ -126,6 +183,9 @@ int Uniform::compare(const Uniform& rhs) const if( _type < rhs._type ) return -1; if( rhs._type < _type ) return 1; + if( _numElements < rhs._numElements ) return -1; + if( rhs._numElements < _numElements ) return 1; + if( _name < rhs._name ) return -1; if( rhs._name < _name ) return 1; @@ -136,150 +196,30 @@ int Uniform::compareData(const Uniform& rhs) const { // caller must ensure that _type==rhs._type - switch( getGlApiType(getType()) ) + if( _floatArray.valid() ) { - 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_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_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 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_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; - - default: - osg::notify(osg::WARN) << "cannot compare UNDEFINED Uniform type" << std::endl; - return 0; + if( ! rhs._floatArray ) return 1; + if( _floatArray == rhs._floatArray ) return 0; + return memcmp( _floatArray->getDataPointer(), rhs._floatArray->getDataPointer(), + _floatArray->getTotalDataSize() ); } + + if( _intArray.valid() ) + { + if( ! rhs._intArray ) return 1; + if( _intArray == rhs._intArray ) return 0; + return memcmp( _intArray->getDataPointer(), rhs._intArray->getDataPointer(), + _intArray->getTotalDataSize() ); + } + return -1; // how got here? } void Uniform::copyData(const Uniform& rhs) { // caller must ensure that _type==rhs._type - - int i; - switch( getGlApiType(getType()) ) - { - 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_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_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 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_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; - - default: - osg::notify(osg::WARN) << "cannot copy UNDEFINED Uniform type" << std::endl; - break; - } - + _numElements = rhs._numElements; + if( _floatArray.valid() && rhs._floatArray.valid() ) *_floatArray = *rhs._floatArray; + if( _intArray.valid() && rhs._intArray.valid() ) *_intArray = *rhs._intArray; dirty(); } @@ -295,6 +235,13 @@ bool Uniform::isCompatibleType( Type t ) const return false; } +unsigned int Uniform::getInternalArrayNumElements() const +{ + if( getNumElements()<1 || getType()==UNDEFINED ) return 0; + return getNumElements() * getTypeNumComponents(getType()); +} + + /////////////////////////////////////////////////////////////////////////// // static methods @@ -327,6 +274,48 @@ const char* Uniform::getTypename( Type t ) } } +int Uniform::getTypeNumComponents( Type t ) +{ + switch( t ) + { + case FLOAT: + case INT: + case BOOL: + case SAMPLER_1D: + case SAMPLER_2D: + case SAMPLER_3D: + case SAMPLER_CUBE: + case SAMPLER_1D_SHADOW: + case SAMPLER_2D_SHADOW: + return 1; + + case FLOAT_VEC2: + case INT_VEC2: + case BOOL_VEC2: + return 2; + + case FLOAT_VEC3: + case INT_VEC3: + case BOOL_VEC3: + return 3; + + case FLOAT_VEC4: + case FLOAT_MAT2: + case INT_VEC4: + case BOOL_VEC4: + return 4; + + case FLOAT_MAT3: + return 9; + + case FLOAT_MAT4: + return 16; + + default: + return 0; + } +} + Uniform::Type Uniform::getTypeId( const std::string& tname ) { if( tname == "float" ) return FLOAT; @@ -380,167 +369,222 @@ Uniform::Type Uniform::getGlApiType( Type t ) } } +GLenum Uniform::getInternalArrayType( Type t ) +{ + switch( t ) + { + case FLOAT: + case FLOAT_VEC2: + case FLOAT_VEC3: + case FLOAT_VEC4: + case FLOAT_MAT2: + case FLOAT_MAT3: + case FLOAT_MAT4: + return GL_FLOAT; + + case INT: + case INT_VEC2: + case INT_VEC3: + case INT_VEC4: + case BOOL: + case BOOL_VEC2: + case BOOL_VEC3: + case BOOL_VEC4: + case SAMPLER_1D: + case SAMPLER_2D: + case SAMPLER_3D: + case SAMPLER_CUBE: + case SAMPLER_1D_SHADOW: + case SAMPLER_2D_SHADOW: + return GL_INT; + + default: + return 0; + } +} + /////////////////////////////////////////////////////////////////////////// -// value constructors +// value constructors for single-element (ie: non-array) uniforms Uniform::Uniform( const char* name, float f ) : - _type(FLOAT) + _type(FLOAT), _numElements(1), _modifiedCount(0) { setName(name); + allocateDataArray(); set( f ); } Uniform::Uniform( const char* name, const osg::Vec2& v2 ) : - _type(FLOAT_VEC2) + _type(FLOAT_VEC2), _numElements(1), _modifiedCount(0) { setName(name); + allocateDataArray(); set( v2 ); } Uniform::Uniform( const char* name, const osg::Vec3& v3 ) : - _type(FLOAT_VEC3) + _type(FLOAT_VEC3), _numElements(1), _modifiedCount(0) { setName(name); + allocateDataArray(); set( v3 ); } Uniform::Uniform( const char* name, const osg::Vec4& v4 ) : - _type(FLOAT_VEC4) + _type(FLOAT_VEC4), _numElements(1), _modifiedCount(0) { setName(name); + allocateDataArray(); set( v4 ); } Uniform::Uniform( const char* name, const osg::Matrix2& m2 ) : - _type(FLOAT_MAT2) + _type(FLOAT_MAT2), _numElements(1), _modifiedCount(0) { setName(name); + allocateDataArray(); set( m2 ); } Uniform::Uniform( const char* name, const osg::Matrix3& m3 ) : - _type(FLOAT_MAT3) + _type(FLOAT_MAT3), _numElements(1), _modifiedCount(0) { setName(name); + allocateDataArray(); set( m3 ); } Uniform::Uniform( const char* name, const osg::Matrixf& m4 ) : - _type(FLOAT_MAT4) + _type(FLOAT_MAT4), _numElements(1), _modifiedCount(0) { setName(name); + allocateDataArray(); set( m4 ); } Uniform::Uniform( const char* name, const osg::Matrixd& m4 ) : - _type(FLOAT_MAT4) + _type(FLOAT_MAT4), _numElements(1), _modifiedCount(0) { setName(name); + allocateDataArray(); set( m4 ); } Uniform::Uniform( const char* name, int i ) : - _type(INT) + _type(INT), _numElements(1), _modifiedCount(0) { setName(name); + allocateDataArray(); set( i ); } Uniform::Uniform( const char* name, int i0, int i1 ) : - _type(INT_VEC2) + _type(INT_VEC2), _numElements(1), _modifiedCount(0) { setName(name); + allocateDataArray(); set( i0, i1 ); } Uniform::Uniform( const char* name, int i0, int i1, int i2 ) : - _type(INT_VEC3) + _type(INT_VEC3), _numElements(1), _modifiedCount(0) { setName(name); + allocateDataArray(); set( i0, i1, i2 ); } Uniform::Uniform( const char* name, int i0, int i1, int i2, int i3 ) : - _type(INT_VEC4) + _type(INT_VEC4), _numElements(1), _modifiedCount(0) { setName(name); + allocateDataArray(); set( i0, i1, i2, i3 ); } Uniform::Uniform( const char* name, bool b ) : - _type(BOOL) + _type(BOOL), _numElements(1), _modifiedCount(0) { setName(name); + allocateDataArray(); set( b ); } Uniform::Uniform( const char* name, bool b0, bool b1 ) : - _type(BOOL_VEC2) + _type(BOOL_VEC2), _numElements(1), _modifiedCount(0) { setName(name); + allocateDataArray(); set( b0, b1 ); } Uniform::Uniform( const char* name, bool b0, bool b1, bool b2 ) : - _type(BOOL_VEC3) + _type(BOOL_VEC3), _numElements(1), _modifiedCount(0) { setName(name); + allocateDataArray(); set( b0, b1, b2 ); } Uniform::Uniform( const char* name, bool b0, bool b1, bool b2, bool b3 ) : - _type(BOOL_VEC4) + _type(BOOL_VEC4), _numElements(1), _modifiedCount(0) { setName(name); + allocateDataArray(); set( b0, b1, b2, b3 ); } /////////////////////////////////////////////////////////////////////////// -// value assignment +// Value assignment for single-element (ie: non-array) uniforms. bool Uniform::set( float f ) { - if( ! isCompatibleType(FLOAT) ) return false; - _data.f1 = f; + if( getNumElements() == 0 ) setNumElements(1); + if( ! (isScalar() && isCompatibleType(FLOAT)) ) return false; + (*_floatArray)[0] = f; dirty(); return true; } bool Uniform::set( const osg::Vec2& v2 ) { - if( ! isCompatibleType(FLOAT_VEC2) ) return false; - _data.f2[0] = v2.x(); - _data.f2[1] = v2.y(); + if( getNumElements() == 0 ) setNumElements(1); + if( ! (isScalar() && isCompatibleType(FLOAT_VEC2)) ) return false; + (*_floatArray)[0] = v2.x(); + (*_floatArray)[1] = v2.y(); dirty(); return true; } bool Uniform::set( const osg::Vec3& v3 ) { - if( ! isCompatibleType(FLOAT_VEC3) ) return false; - _data.f3[0] = v3.x(); - _data.f3[1] = v3.y(); - _data.f3[2] = v3.z(); + if( getNumElements() == 0 ) setNumElements(1); + if( ! (isScalar() && isCompatibleType(FLOAT_VEC3)) ) return false; + (*_floatArray)[0] = v3.x(); + (*_floatArray)[1] = v3.y(); + (*_floatArray)[2] = v3.z(); dirty(); return true; } bool Uniform::set( const osg::Vec4& v4 ) { - if( ! isCompatibleType(FLOAT_VEC4) ) return false; - _data.f4[0] = v4.x(); - _data.f4[1] = v4.y(); - _data.f4[2] = v4.z(); - _data.f4[3] = v4.w(); + if( getNumElements() == 0 ) setNumElements(1); + if( ! (isScalar() && isCompatibleType(FLOAT_VEC4)) ) return false; + (*_floatArray)[0] = v4.x(); + (*_floatArray)[1] = v4.y(); + (*_floatArray)[2] = v4.z(); + (*_floatArray)[3] = v4.w(); dirty(); return true; } bool Uniform::set( const osg::Matrix2& m2 ) { - if( ! isCompatibleType(FLOAT_MAT2) ) return false; - for( int i = 0; i < 4; ++i ) _data.f4[i] = m2[i]; + if( getNumElements() == 0 ) setNumElements(1); + if( ! (isScalar() && isCompatibleType(FLOAT_MAT2)) ) return false; + for( int i = 0; i < 4; ++i ) (*_floatArray)[i] = m2[i]; dirty(); return true; } @@ -548,286 +592,349 @@ bool Uniform::set( const osg::Matrix2& m2 ) bool Uniform::set( const osg::Matrix3& m3 ) { - if( ! isCompatibleType(FLOAT_MAT3) ) return false; - for( int i = 0; i < 9; ++i ) _data.f9[i] = m3[i]; + if( getNumElements() == 0 ) setNumElements(1); + if( ! (isScalar() && isCompatibleType(FLOAT_MAT3)) ) return false; + for( int i = 0; i < 9; ++i ) (*_floatArray)[i] = m3[i]; dirty(); return true; } bool Uniform::set( const osg::Matrixf& m4 ) { - if( ! isCompatibleType(FLOAT_MAT4) ) return false; + if( getNumElements() == 0 ) setNumElements(1); + if( ! (isScalar() && isCompatibleType(FLOAT_MAT4)) ) return false; const Matrixf::value_type* p = m4.ptr(); - for( int i = 0; i < 16; ++i ) _data.f16[i] = p[i]; + for( int i = 0; i < 16; ++i ) (*_floatArray)[i] = p[i]; dirty(); return true; } bool Uniform::set( const osg::Matrixd& m4 ) { - if( ! isCompatibleType(FLOAT_MAT4) ) return false; + if( getNumElements() == 0 ) setNumElements(1); + if( ! (isScalar() && isCompatibleType(FLOAT_MAT4)) ) return false; const Matrixd::value_type* p = m4.ptr(); - for( int i = 0; i < 16; ++i ) _data.f16[i] = static_cast(p[i]); + for( int i = 0; i < 16; ++i ) (*_floatArray)[i] = static_cast(p[i]); dirty(); return true; } bool Uniform::set( int i ) { - if( ! isCompatibleType(INT) ) return false; - _data.i1 = i; + if( getNumElements() == 0 ) setNumElements(1); + if( ! (isScalar() && isCompatibleType(INT)) ) return false; + (*_intArray)[0] = i; dirty(); return true; } bool Uniform::set( int i0, int i1 ) { - if( ! isCompatibleType(INT_VEC2) ) return false; - _data.i2[0] = i0; - _data.i2[1] = i1; + if( getNumElements() == 0 ) setNumElements(1); + if( ! (isScalar() && isCompatibleType(INT_VEC2)) ) return false; + (*_intArray)[0] = i0; + (*_intArray)[1] = i1; dirty(); return true; } bool Uniform::set( int i0, int i1, int i2 ) { - if( ! isCompatibleType(INT_VEC3) ) return false; - _data.i3[0] = i0; - _data.i3[1] = i1; - _data.i3[2] = i2; + if( getNumElements() == 0 ) setNumElements(1); + if( ! (isScalar() && isCompatibleType(INT_VEC3)) ) return false; + (*_intArray)[0] = i0; + (*_intArray)[1] = i1; + (*_intArray)[2] = i2; dirty(); return true; } bool Uniform::set( int i0, int i1, int i2, int i3 ) { - if( ! isCompatibleType(INT_VEC4) ) return false; - _data.i4[0] = i0; - _data.i4[1] = i1; - _data.i4[2] = i2; - _data.i4[3] = i3; + if( getNumElements() == 0 ) setNumElements(1); + if( ! (isScalar() && isCompatibleType(INT_VEC4)) ) return false; + (*_intArray)[0] = i0; + (*_intArray)[1] = i1; + (*_intArray)[2] = i2; + (*_intArray)[3] = i3; dirty(); return true; } bool Uniform::set( bool b ) { - if( ! isCompatibleType(BOOL) ) return false; - _data.i1 = b; + if( getNumElements() == 0 ) setNumElements(1); + if( ! (isScalar() && isCompatibleType(BOOL)) ) return false; + (*_intArray)[0] = b; dirty(); return true; } bool Uniform::set( bool b0, bool b1 ) { - if( ! isCompatibleType(BOOL_VEC2) ) return false; - _data.i2[0] = b0; - _data.i2[1] = b1; + if( getNumElements() == 0 ) setNumElements(1); + if( ! (isScalar() && isCompatibleType(BOOL_VEC2)) ) return false; + (*_intArray)[0] = b0; + (*_intArray)[1] = b1; dirty(); return true; } bool Uniform::set( bool b0, bool b1, bool b2 ) { - if( ! isCompatibleType(BOOL_VEC3) ) return false; - _data.i3[0] = b0; - _data.i3[1] = b1; - _data.i3[2] = b2; + if( getNumElements() == 0 ) setNumElements(1); + if( ! (isScalar() && isCompatibleType(BOOL_VEC3)) ) return false; + (*_intArray)[0] = b0; + (*_intArray)[1] = b1; + (*_intArray)[2] = b2; dirty(); return true; } bool Uniform::set( bool b0, bool b1, bool b2, bool b3 ) { - if( ! isCompatibleType(BOOL_VEC4) ) return false; - _data.i4[0] = b0; - _data.i4[1] = b1; - _data.i4[2] = b2; - _data.i4[3] = b3; + if( getNumElements() == 0 ) setNumElements(1); + if( ! (isScalar() && isCompatibleType(BOOL_VEC4)) ) return false; + (*_intArray)[0] = b0; + (*_intArray)[1] = b1; + (*_intArray)[2] = b2; + (*_intArray)[3] = b3; dirty(); return true; } /////////////////////////////////////////////////////////////////////////// -// value query +// Value query for single-element (ie: non-array) uniforms. bool Uniform::get( float& f ) const { - if( ! isCompatibleType(FLOAT) ) return false; - f = _data.f1; + if( ! (isScalar() && isCompatibleType(FLOAT)) ) return false; + f = (*_floatArray)[0]; return true; } bool Uniform::get( osg::Vec2& v2 ) const { - if( ! isCompatibleType(FLOAT_VEC2) ) return false; - v2.x() = _data.f2[0]; - v2.y() = _data.f2[1]; + if( ! (isScalar() && isCompatibleType(FLOAT_VEC2)) ) return false; + v2.x() = (*_floatArray)[0]; + v2.y() = (*_floatArray)[1]; return true; } bool Uniform::get( osg::Vec3& v3 ) const { - if( ! isCompatibleType(FLOAT_VEC3) ) return false; - v3.x() = _data.f3[0]; - v3.y() = _data.f3[1]; - v3.z() = _data.f3[2]; + if( ! (isScalar() && isCompatibleType(FLOAT_VEC3)) ) return false; + v3.x() = (*_floatArray)[0]; + v3.y() = (*_floatArray)[1]; + v3.z() = (*_floatArray)[2]; return true; } bool Uniform::get( osg::Vec4& v4 ) const { - if( ! isCompatibleType(FLOAT_VEC4) ) return false; - v4.x() = _data.f4[0]; - v4.y() = _data.f4[1]; - v4.z() = _data.f4[2]; - v4.w() = _data.f4[3]; + if( ! (isScalar() && isCompatibleType(FLOAT_VEC4)) ) return false; + v4.x() = (*_floatArray)[0]; + v4.y() = (*_floatArray)[1]; + v4.z() = (*_floatArray)[2]; + v4.w() = (*_floatArray)[3]; return true; } bool Uniform::get( osg::Matrix2& m2 ) const { - if( ! isCompatibleType(FLOAT_MAT2) ) return false; - m2.set( _data.f4 ); + if( ! (isScalar() && isCompatibleType(FLOAT_MAT2)) ) return false; + m2.set( &_floatArray->front() ); return true; } bool Uniform::get( osg::Matrix3& m3 ) const { - if( ! isCompatibleType(FLOAT_MAT3) ) return false; - m3.set( _data.f9 ); + if( ! (isScalar() && isCompatibleType(FLOAT_MAT3)) ) return false; + m3.set( &_floatArray->front() ); return true; } bool Uniform::get( osg::Matrixf& m4 ) const { - if( ! isCompatibleType(FLOAT_MAT4) ) return false; - m4.set( _data.f16 ); + if( ! (isScalar() && isCompatibleType(FLOAT_MAT4)) ) return false; + m4.set( &_floatArray->front() ); return true; } bool Uniform::get( osg::Matrixd& m4 ) const { - if( ! isCompatibleType(FLOAT_MAT4) ) return false; - m4.set( _data.f16 ); + if( ! (isScalar() && isCompatibleType(FLOAT_MAT4)) ) return false; + m4.set( &_floatArray->front() ); return true; } bool Uniform::get( int& i ) const { - if( ! isCompatibleType(INT) ) return false; - i = _data.i1; + if( ! (isScalar() && isCompatibleType(INT)) ) return false; + i = (*_intArray)[0]; return true; } bool Uniform::get( int& i0, int& i1 ) const { - if( ! isCompatibleType(INT_VEC2) ) return false; - i0 = _data.i2[0]; - i1 = _data.i2[1]; + if( ! (isScalar() && isCompatibleType(INT_VEC2)) ) return false; + i0 = (*_intArray)[0]; + i1 = (*_intArray)[1]; return true; } bool Uniform::get( int& i0, int& i1, int& i2 ) const { - if( ! isCompatibleType(INT_VEC3) ) return false; - i0 = _data.i3[0]; - i1 = _data.i3[1]; - i2 = _data.i3[2]; + if( ! (isScalar() && isCompatibleType(INT_VEC3)) ) return false; + i0 = (*_intArray)[0]; + i1 = (*_intArray)[1]; + i2 = (*_intArray)[2]; return true; } bool Uniform::get( int& i0, int& i1, int& i2, int& i3 ) const { - if( ! isCompatibleType(INT_VEC4) ) return false; - i0 = _data.i4[0]; - i1 = _data.i4[1]; - i2 = _data.i4[2]; - i3 = _data.i4[3]; + if( ! (isScalar() && isCompatibleType(INT_VEC4)) ) return false; + i0 = (*_intArray)[0]; + i1 = (*_intArray)[1]; + i2 = (*_intArray)[2]; + i3 = (*_intArray)[3]; return true; } bool Uniform::get( bool& b ) const { - if( ! isCompatibleType(BOOL) ) return false; - b = (_data.i1 != 0); + if( ! (isScalar() && isCompatibleType(BOOL)) ) return false; + b = ((*_intArray)[0] != 0); return true; } bool Uniform::get( bool& b0, bool& b1 ) const { - if( ! isCompatibleType(BOOL_VEC2) ) return false; - b0 = (_data.i2[0] != 0); - b1 = (_data.i2[1] != 0); + if( ! (isScalar() && isCompatibleType(BOOL_VEC2)) ) return false; + b0 = ((*_intArray)[0] != 0); + b1 = ((*_intArray)[1] != 0); return true; } bool Uniform::get( bool& b0, bool& b1, bool& b2 ) const { - if( ! isCompatibleType(BOOL_VEC3) ) return false; - b0 = (_data.i3[0] != 0); - b1 = (_data.i3[1] != 0); - b2 = (_data.i3[2] != 0); + if( ! (isScalar() && isCompatibleType(BOOL_VEC3)) ) return false; + b0 = ((*_intArray)[0] != 0); + b1 = ((*_intArray)[1] != 0); + b2 = ((*_intArray)[2] != 0); return true; } bool Uniform::get( bool& b0, bool& b1, bool& b2, bool& b3 ) const { - if( ! isCompatibleType(BOOL_VEC4) ) return false; - b0 = (_data.i4[0] != 0); - b1 = (_data.i4[1] != 0); - b2 = (_data.i4[2] != 0); - b3 = (_data.i4[3] != 0); + if( ! (isScalar() && isCompatibleType(BOOL_VEC4)) ) return false; + b0 = ((*_intArray)[0] != 0); + b1 = ((*_intArray)[1] != 0); + b2 = ((*_intArray)[2] != 0); + b3 = ((*_intArray)[3] != 0); return true; } +/////////////////////////////////////////////////////////////////////////// +// Value assignment for array uniforms. +// TODO just a few of all the type variations are implemented so far + +bool Uniform::setElement( unsigned int index, float f ) +{ + if( index>=getNumElements() || !isCompatibleType(FLOAT) ) return false; + int i = index * getTypeNumComponents(getType()); + (*_floatArray)[i] = f; + dirty(); + return true; +} + +bool Uniform::setElement( unsigned int index, const osg::Vec2& v2 ) +{ + if( index>=getNumElements() || !isCompatibleType(FLOAT_VEC2) ) return false; + int i = index * getTypeNumComponents(getType()); + (*_floatArray)[i] = v2.x(); + (*_floatArray)[i+1] = v2.y(); + dirty(); + return true; +} + +bool Uniform::setElement( unsigned int index, const osg::Vec3& v3 ) +{ + if( index>=getNumElements() || !isCompatibleType(FLOAT_VEC3) ) return false; + int i = index * getTypeNumComponents(getType()); + (*_floatArray)[i] = v3.x(); + (*_floatArray)[i+1] = v3.y(); + (*_floatArray)[i+2] = v3.z(); + dirty(); + return true; +} + +bool Uniform::setElement( unsigned int index, const osg::Vec4& v4 ) +{ + if( index>=getNumElements() || !isCompatibleType(FLOAT_VEC4) ) return false; + int i = index * getTypeNumComponents(getType()); + (*_floatArray)[i] = v4.x(); + (*_floatArray)[i+1] = v4.y(); + (*_floatArray)[i+2] = v4.z(); + (*_floatArray)[i+3] = v4.w(); + dirty(); + return true; +} + +/////////////////////////////////////////////////////////////////////////// + void Uniform::apply(const GL2Extensions* ext, GLint location) const { // osg::notify(osg::NOTICE) << "uniform at "<glUniform1f( location, _data.f1 ); + if( _floatArray.valid() ) ext->glUniform1fv( location, num, &_floatArray->front() ); break; case FLOAT_VEC2: - ext->glUniform2fv( location, 1, _data.f2 ); + if( _floatArray.valid() ) ext->glUniform2fv( location, num, &_floatArray->front() ); break; case FLOAT_VEC3: - ext->glUniform3fv( location, 1, _data.f3 ); + if( _floatArray.valid() ) ext->glUniform3fv( location, num, &_floatArray->front() ); break; case FLOAT_VEC4: - ext->glUniform4fv( location, 1, _data.f4 ); + if( _floatArray.valid() ) ext->glUniform4fv( location, num, &_floatArray->front() ); break; case FLOAT_MAT2: - ext->glUniformMatrix2fv( location, 1, GL_FALSE, _data.f4 ); + if( _floatArray.valid() ) ext->glUniformMatrix2fv( location, num, GL_FALSE, &_floatArray->front() ); break; case FLOAT_MAT3: - ext->glUniformMatrix3fv( location, 1, GL_FALSE, _data.f9 ); + if( _floatArray.valid() ) ext->glUniformMatrix3fv( location, num, GL_FALSE, &_floatArray->front() ); break; case FLOAT_MAT4: - ext->glUniformMatrix4fv( location, 1, GL_FALSE, _data.f16 ); + if( _floatArray.valid() ) ext->glUniformMatrix4fv( location, num, GL_FALSE, &_floatArray->front() ); break; case INT: - ext->glUniform1i( location, _data.i1 ); + if( _intArray.valid() ) ext->glUniform1iv( location, num, &_intArray->front() ); break; case INT_VEC2: - ext->glUniform2iv( location, 1, _data.i2 ); + if( _intArray.valid() ) ext->glUniform2iv( location, num, &_intArray->front() ); break; case INT_VEC3: - ext->glUniform3iv( location, 1, _data.i3 ); + if( _intArray.valid() ) ext->glUniform3iv( location, num, &_intArray->front() ); break; case INT_VEC4: - ext->glUniform4iv( location, 1, _data.i4 ); + if( _intArray.valid() ) ext->glUniform4iv( location, num, &_intArray->front() ); break; default: diff --git a/src/osgPlugins/osg/Uniform.cpp b/src/osgPlugins/osg/Uniform.cpp index f684fa7a0..4c156be7a 100644 --- a/src/osgPlugins/osg/Uniform.cpp +++ b/src/osgPlugins/osg/Uniform.cpp @@ -1,3 +1,6 @@ + +// Mike Weiblen 2006-05-14 + #include "osg/Uniform" #include "osg/io_utils" #include "osg/Notify" @@ -12,6 +15,10 @@ using namespace osg; using namespace osgDB; using namespace std; +// reuse from Geometry.cpp +bool Array_writeLocalData(const Array& array,Output& fw); +Array* Array_readLocalData(Input& fr); + // forward declare functions to use later. bool Uniform_readLocalData(Object& obj, Input& fr); bool Uniform_writeLocalData(const Object& obj, Output& fw); @@ -30,247 +37,178 @@ RegisterDotOsgWrapperProxy g_UniformProxy bool Uniform_readLocalData(Object& obj, Input& fr) { bool iteratorAdvanced = false; - Uniform& uniform = static_cast(obj); - - if (fr[0].isWord()) + if (fr[0].matchWord("type")) { + // post-May 2006 format (OSG versions > 1.0) + uniform.setType( Uniform::getTypeId( fr[1].getStr() ) ); + + unsigned int numElements; + fr[2].getUInt(numElements); + uniform.setNumElements( numElements ); + + fr+=3; + iteratorAdvanced = true; + + Array* data = Array_readLocalData(fr); + uniform.setArray( dynamic_cast(data) ); + uniform.setArray( dynamic_cast(data) ); + } +#if 1 //[ +// Deprecated; for backwards compatibility only. +// when can we safely delete this code, I wonder... + else + { + // pre-May 2006 format (OSG versions <= 1.0) uniform.setType( Uniform::getTypeId(fr[0].getStr()) ); fr+=1; iteratorAdvanced = true; - } - - switch( Uniform::getGlApiType(uniform.getType()) ) - { - case(osg::Uniform::FLOAT): + + switch( Uniform::getGlApiType(uniform.getType()) ) { - float value; - if (fr[0].getFloat(value)) + case(osg::Uniform::FLOAT): { - uniform.set(value); - fr+=1; - iteratorAdvanced = true; + float value; + if (fr[0].getFloat(value)) + { + uniform.set(value); + fr+=1; + iteratorAdvanced = true; + } + break; } - break; - } - case(osg::Uniform::FLOAT_VEC2): - { - osg::Vec2 value; - if (fr[0].getFloat(value[0]) && fr[1].getFloat(value[1])) + case(osg::Uniform::FLOAT_VEC2): { - uniform.set(value); - fr+=2; - iteratorAdvanced = true; + osg::Vec2 value; + if (fr[0].getFloat(value[0]) && fr[1].getFloat(value[1])) + { + uniform.set(value); + fr+=2; + iteratorAdvanced = true; + } + break; } - break; - } - case(osg::Uniform::FLOAT_VEC3): - { - osg::Vec3 value; - if (fr[0].getFloat(value[0]) && fr[1].getFloat(value[1]) && fr[2].getFloat(value[2])) + case(osg::Uniform::FLOAT_VEC3): { - uniform.set(value); - fr+=3; - iteratorAdvanced = true; + osg::Vec3 value; + if (fr[0].getFloat(value[0]) && fr[1].getFloat(value[1]) && fr[2].getFloat(value[2])) + { + uniform.set(value); + fr+=3; + iteratorAdvanced = true; + } + break; } - break; - } - case(osg::Uniform::FLOAT_VEC4): - { - osg::Vec4 value; - if (fr[0].getFloat(value[0]) && fr[1].getFloat(value[1]) && fr[2].getFloat(value[2]) && fr[3].getFloat(value[3])) + case(osg::Uniform::FLOAT_VEC4): { - uniform.set(value); - fr+=4; - iteratorAdvanced = true; + osg::Vec4 value; + if (fr[0].getFloat(value[0]) && fr[1].getFloat(value[1]) && fr[2].getFloat(value[2]) && fr[3].getFloat(value[3])) + { + uniform.set(value); + fr+=4; + iteratorAdvanced = true; + } + break; } - break; - } - case(osg::Uniform::INT): - { - int value; - if (fr[0].getInt(value)) + case(osg::Uniform::INT): { - uniform.set(value); - fr+=1; - iteratorAdvanced = true; + int value; + if (fr[0].getInt(value)) + { + uniform.set(value); + fr+=1; + iteratorAdvanced = true; + } + break; } - break; - } - case(osg::Uniform::INT_VEC2): - { - int value[2]; - if (fr[0].getInt(value[0]) && fr[1].getInt(value[1])) + case(osg::Uniform::INT_VEC2): { - uniform.set(value[0],value[1]); - fr+=2; - iteratorAdvanced = true; + int value[2]; + if (fr[0].getInt(value[0]) && fr[1].getInt(value[1])) + { + uniform.set(value[0],value[1]); + fr+=2; + iteratorAdvanced = true; + } + break; } - break; - } - case(osg::Uniform::INT_VEC3): - { - int value[3]; - if (fr[0].getInt(value[0]) && fr[1].getInt(value[1]) && fr[2].getInt(value[2])) + case(osg::Uniform::INT_VEC3): { - uniform.set(value[0],value[1],value[2]); - fr+=3; - iteratorAdvanced = true; + int value[3]; + if (fr[0].getInt(value[0]) && fr[1].getInt(value[1]) && fr[2].getInt(value[2])) + { + uniform.set(value[0],value[1],value[2]); + fr+=3; + iteratorAdvanced = true; + } + break; } - break; - } - case(osg::Uniform::INT_VEC4): - { - int value[4]; - if (fr[0].getInt(value[0]) && fr[1].getInt(value[1]) && fr[2].getInt(value[2]) && fr[3].getInt(value[3])) + case(osg::Uniform::INT_VEC4): { - uniform.set(value[0],value[1],value[2],value[3]); - fr+=4; - iteratorAdvanced = true; + int value[4]; + if (fr[0].getInt(value[0]) && fr[1].getInt(value[1]) && fr[2].getInt(value[2]) && fr[3].getInt(value[3])) + { + uniform.set(value[0],value[1],value[2],value[3]); + fr+=4; + iteratorAdvanced = true; + } + break; } - break; - } - case(osg::Uniform::FLOAT_MAT2): - { - osg::Matrix2 value; - if (fr[0].getFloat(value[0]) && fr[1].getFloat(value[1]) && - fr[2].getFloat(value[2]) && fr[3].getFloat(value[3])) + case(osg::Uniform::FLOAT_MAT2): { - uniform.set(value); - fr+=4; - iteratorAdvanced = true; + osg::Matrix2 value; + if (fr[0].getFloat(value[0]) && fr[1].getFloat(value[1]) && + fr[2].getFloat(value[2]) && fr[3].getFloat(value[3])) + { + uniform.set(value); + fr+=4; + iteratorAdvanced = true; + } + break; } - break; - } - case(osg::Uniform::FLOAT_MAT3): - { - osg::Matrix3 value; - if (fr[0].getFloat(value[0]) && fr[1].getFloat(value[1]) && fr[2].getFloat(value[2]) && - fr[3].getFloat(value[3]) && fr[4].getFloat(value[4]) && fr[5].getFloat(value[5]) && - fr[6].getFloat(value[6]) && fr[7].getFloat(value[7]) && fr[8].getFloat(value[8])) + case(osg::Uniform::FLOAT_MAT3): { - uniform.set(value); - fr+=9; - iteratorAdvanced = true; + osg::Matrix3 value; + if (fr[0].getFloat(value[0]) && fr[1].getFloat(value[1]) && fr[2].getFloat(value[2]) && + fr[3].getFloat(value[3]) && fr[4].getFloat(value[4]) && fr[5].getFloat(value[5]) && + fr[6].getFloat(value[6]) && fr[7].getFloat(value[7]) && fr[8].getFloat(value[8])) + { + uniform.set(value); + fr+=9; + iteratorAdvanced = true; + } + break; } - break; - } - case(osg::Uniform::FLOAT_MAT4): - { - Matrix value; - if( readMatrix(value,fr) ) + case(osg::Uniform::FLOAT_MAT4): { - uniform.set(value); - iteratorAdvanced = true; + Matrix value; + if( readMatrix(value,fr) ) + { + uniform.set(value); + iteratorAdvanced = true; + } + break; } - break; - } - default: - { - break; + default: + break; } } +#endif //] return iteratorAdvanced; } - bool Uniform_writeLocalData(const Object& obj,Output& fw) { const Uniform& uniform = static_cast(obj); - fw.indent() << Uniform::getTypename( uniform.getType() ) << " "; - - switch( Uniform::getGlApiType(uniform.getType()) ) - { - case(osg::Uniform::FLOAT): - { - float value = 0.0f; - uniform.get(value); - fw << value; - break; - } - case(osg::Uniform::FLOAT_VEC2): - { - Vec2 value; - uniform.get(value); - fw << value; - break; - } - case(osg::Uniform::FLOAT_VEC3): - { - Vec3 value; - uniform.get(value); - fw << value; - break; - } - case(osg::Uniform::FLOAT_VEC4): - { - Vec4 value; - uniform.get(value); - fw << value; - break; - } - case(osg::Uniform::INT): - { - int value = 0; - uniform.get(value); - fw << value; - break; - } - case(osg::Uniform::INT_VEC2): - { - int value[2]; - uniform.get(value[0],value[1]); - fw << value[0]<<" "< 1.0) + fw.indent() << "type " + << Uniform::getTypename( uniform.getType() ) << " " + << uniform.getNumElements() << " "; + + if( uniform.getFloatArray() ) Array_writeLocalData( *uniform.getFloatArray(), fw ); + if( uniform.getIntArray() ) Array_writeLocalData( *uniform.getIntArray(), fw ); return true; } diff --git a/src/osgProducer/ViewerEventHandler.cpp b/src/osgProducer/ViewerEventHandler.cpp index ffee46b4c..a49729374 100644 --- a/src/osgProducer/ViewerEventHandler.cpp +++ b/src/osgProducer/ViewerEventHandler.cpp @@ -923,8 +923,7 @@ ViewerEventHandler::ViewerEventHandler(OsgCameraGroup* cg): Viewer* viewer = dynamic_cast(cg); if (viewer) setWriteImageFileName(viewer->getWriteImageFileName()); - else setWriteImageFileName("saved_image.jpg"); - + else setWriteImageFileName( Viewer::getDefaultImageFileName() ); } void ViewerEventHandler::setWriteImageOnNextFrame(bool writeImageOnNextFrame)