OpenSceneGraph/src/osg/Uniform.cpp
Robert Osfield df48d440e4 From Colin McDonald, "Attached are some fixes to build osg using the Solaris Studio compiler.
I've also checked the modified files still build ok with other
compilers (Linux gcc, Windows Visual Studio).

osgDB/OutputStream.cpp and osgPlugins/lws/SceneLoader.cpp require
stdlib.h for atoi use.

In osg/Uniform.cpp the compiler complains that base_class is unknown
unless I add a class name qualifier.

Not a build fix, but I spotted a typo in osgUtil/SceneView."
2013-09-05 10:23:05 +00:00

2659 lines
80 KiB
C++

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
* Copyright (C) 2003-2005 3Dlabs Inc. Ltd.
* Copyright (C) 2008 Zebra Imaging
* Copyright (C) 2012 David Callu
*
* This application is open source and may be redistributed and/or modified
* freely and without restriction, both in commercial and non commercial
* applications, as long as this copyright notice is maintained.
*
* This application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
/* file: src/osg/Uniform.cpp
* author: Mike Weiblen 2008-01-02
*/
#include <string.h>
#include <osg/Notify>
#include <osg/Uniform>
#include <osg/Program>
#include <osg/StateSet>
#include <limits.h>
#include <algorithm>
using namespace osg;
///////////////////////////////////////////////////////////////////////////
// osg::Uniform
///////////////////////////////////////////////////////////////////////////
Uniform::Uniform() :
_type(UNDEFINED), _numElements(0), _nameID(UINT_MAX), _modifiedCount(0)
{
}
Uniform::Uniform( Type type, const std::string& name, int numElements ) :
_type(type), _numElements(0), _nameID(UINT_MAX), _modifiedCount(0)
{
setName(name);
setNumElements(numElements);
allocateDataArray();
}
Uniform::Uniform( const Uniform& rhs, const CopyOp& copyop ) :
Object(rhs,copyop), _type(rhs._type)
{
copyData( rhs );
}
Uniform::~Uniform()
{
}
void Uniform::addParent(osg::StateSet* object)
{
OSG_DEBUG_FP<<"Uniform Adding parent"<<std::endl;
OpenThreads::ScopedPointerLock<OpenThreads::Mutex> lock(getRefMutex());
_parents.push_back(object);
}
void Uniform::removeParent(osg::StateSet* object)
{
OpenThreads::ScopedPointerLock<OpenThreads::Mutex> lock(getRefMutex());
ParentList::iterator pitr = std::find(_parents.begin(),_parents.end(),object);
if (pitr!=_parents.end()) _parents.erase(pitr);
}
bool Uniform::setType( Type t )
{
if (_type==t) return true;
if( _type != UNDEFINED )
{
OSG_WARN << "cannot change Uniform type" << std::endl;
return false;
}
_type = t;
allocateDataArray();
return true;
}
void Uniform::setName( const std::string& name )
{
if( _name != "" )
{
OSG_WARN << "cannot change Uniform name" << std::endl;
return;
}
Object::setName(name);
_nameID = getNameID(_name);
}
void Uniform::setNumElements( unsigned int numElements )
{
if( numElements < 1 )
{
OSG_WARN << "Uniform numElements < 1 is invalid" << std::endl;
return;
}
if (numElements == _numElements) return;
if( _numElements>0 )
{
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() || _doubleArray.valid() || _intArray.valid() || _uintArray.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);
return;
case GL_DOUBLE:
_doubleArray = new DoubleArray(arrayNumElements);
return;
case GL_INT:
_intArray = new IntArray(arrayNumElements);
return;
case GL_UNSIGNED_INT:
_uintArray = new UIntArray(arrayNumElements);
return;
default:
break;
}
}
}
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_WARN << "Uniform::setArray : incompatible array" << std::endl;
return false;
}
_floatArray = array;
_doubleArray = 0;
_intArray = 0;
_uintArray = 0;
dirty();
return true;
}
bool Uniform::setArray( DoubleArray* array )
{
if( !array ) return false;
// incoming array must match configuration of the Uniform
if( getInternalArrayType(getType())!=GL_DOUBLE || getInternalArrayNumElements()!=array->getNumElements() )
{
OSG_WARN << "Uniform::setArray : incompatible array" << std::endl;
return false;
}
_doubleArray = array;
_floatArray = 0;
_intArray = 0;
_uintArray = 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_WARN << "Uniform::setArray : incompatible array" << std::endl;
return false;
}
_intArray = array;
_floatArray = 0;
_doubleArray = 0;
_uintArray = 0;
dirty();
return true;
}
bool Uniform::setArray( UIntArray* array )
{
if( !array ) return false;
// incoming array must match configuration of the Uniform
if( getInternalArrayType(getType())!=GL_UNSIGNED_INT || getInternalArrayNumElements()!=array->getNumElements() )
{
OSG_WARN << "Uniform::setArray : incompatible array" << std::endl;
return false;
}
_uintArray = array;
_floatArray = 0;
_doubleArray = 0;
_intArray = 0;
dirty();
return true;
}
///////////////////////////////////////////////////////////////////////////
int Uniform::compare(const Uniform& rhs) const
{
if( this == &rhs ) return 0;
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;
return compareData( rhs );
}
int Uniform::compareData(const Uniform& rhs) const
{
// caller must ensure that _type==rhs._type
if( _floatArray.valid() )
{
if( ! rhs._floatArray ) return 1;
if( _floatArray == rhs._floatArray ) return 0;
return memcmp( _floatArray->getDataPointer(), rhs._floatArray->getDataPointer(),
_floatArray->getTotalDataSize() );
}
else if( _doubleArray.valid() )
{
if( ! rhs._doubleArray ) return 1;
if( _doubleArray == rhs._doubleArray ) return 0;
return memcmp( _doubleArray->getDataPointer(), rhs._doubleArray->getDataPointer(),
_doubleArray->getTotalDataSize() );
}
else if( _intArray.valid() )
{
if( ! rhs._intArray ) return 1;
if( _intArray == rhs._intArray ) return 0;
return memcmp( _intArray->getDataPointer(), rhs._intArray->getDataPointer(),
_intArray->getTotalDataSize() );
}
else if( _uintArray.valid() )
{
if( ! rhs._uintArray ) return 1;
if( _uintArray == rhs._uintArray ) return 0;
return memcmp( _uintArray->getDataPointer(), rhs._uintArray->getDataPointer(),
_uintArray->getTotalDataSize() );
}
return -1; // how got here?
}
void Uniform::copyData(const Uniform& rhs)
{
// caller must ensure that _type==rhs._type
_numElements = rhs._numElements;
_nameID = rhs._nameID;
if (rhs._floatArray.valid() || rhs._doubleArray.valid() || rhs._intArray.valid() || rhs._uintArray.valid()) allocateDataArray();
if( _floatArray.valid() && rhs._floatArray.valid() ) *_floatArray = *rhs._floatArray;
if( _doubleArray.valid() && rhs._doubleArray.valid() ) *_doubleArray = *rhs._doubleArray;
if( _intArray.valid() && rhs._intArray.valid() ) *_intArray = *rhs._intArray;
if( _uintArray.valid() && rhs._uintArray.valid() ) *_uintArray = *rhs._uintArray;
dirty();
}
bool Uniform::isCompatibleType( Type t ) const
{
if( (t==UNDEFINED) || (getType()==UNDEFINED) ) return false;
if( t == getType() ) return true;
if( getGlApiType(t) == getGlApiType(getType()) ) return true;
OSG_WARN << "Cannot assign between Uniform types " << getTypename(t)
<< " and " << getTypename(getType()) << std::endl;
return false;
}
bool Uniform::isCompatibleType( Type t1, Type t2 ) const
{
if( (t1==UNDEFINED) || (t2==UNDEFINED) || (getType()==UNDEFINED) ) return false;
if( (t1 == getType()) || (t2 == getType()) ) return true;
if( getGlApiType(t1) == getGlApiType(getType()) ) return true;
if( getGlApiType(t2) == getGlApiType(getType()) ) return true;
OSG_WARN << "Cannot assign between Uniform types " << getTypename(t1) << " or " << getTypename(t2)
<< " and " << getTypename(getType()) << std::endl;
return false;
}
unsigned int Uniform::getInternalArrayNumElements() const
{
if( getNumElements()<1 || getType()==UNDEFINED ) return 0;
return getNumElements() * getTypeNumComponents(getType());
}
///////////////////////////////////////////////////////////////////////////
// static methods
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 DOUBLE: return "double";
case DOUBLE_VEC2: return "dvec2";
case DOUBLE_VEC3: return "dvec3";
case DOUBLE_VEC4: return "dvec4";
case INT: return "int";
case INT_VEC2: return "ivec2";
case INT_VEC3: return "ivec3";
case INT_VEC4: return "ivec4";
case UNSIGNED_INT: return "uint";
case UNSIGNED_INT_VEC2: return "uivec2";
case UNSIGNED_INT_VEC3: return "uivec3";
case UNSIGNED_INT_VEC4: return "uivec4";
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 FLOAT_MAT2x3: return "mat2x3";
case FLOAT_MAT2x4: return "mat2x4";
case FLOAT_MAT3x2: return "mat3x2";
case FLOAT_MAT3x4: return "mat3x4";
case FLOAT_MAT4x2: return "mat4x2";
case FLOAT_MAT4x3: return "mat4x3";
case DOUBLE_MAT2: return "dmat2";
case DOUBLE_MAT3: return "dmat3";
case DOUBLE_MAT4: return "dmat4";
case DOUBLE_MAT2x3: return "dmat2x3";
case DOUBLE_MAT2x4: return "dmat2x4";
case DOUBLE_MAT3x2: return "dmat3x2";
case DOUBLE_MAT3x4: return "dmat3x4";
case DOUBLE_MAT4x2: return "dmat4x2";
case DOUBLE_MAT4x3: return "dmat4x3";
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";
case SAMPLER_1D_ARRAY: return "sampler1DArray";
case SAMPLER_2D_ARRAY: return "sampler2DArray";
case SAMPLER_CUBE_MAP_ARRAY: return "samplerCubeMapArray";
case SAMPLER_1D_ARRAY_SHADOW: return "sampler1DArrayShadow";
case SAMPLER_2D_ARRAY_SHADOW: return "sampler2DArrayShadow";
case SAMPLER_2D_MULTISAMPLE: return "sampler2DMS";
case SAMPLER_2D_MULTISAMPLE_ARRAY: return "sampler2DMSArray";
case SAMPLER_CUBE_SHADOW: return "samplerCubeShadow";
case SAMPLER_CUBE_MAP_ARRAY_SHADOW: return "samplerCubeMapArrayShadow";
case SAMPLER_BUFFER: return "samplerBuffer";
case SAMPLER_2D_RECT: return "sampler2DRect";
case SAMPLER_2D_RECT_SHADOW: return "sampler2DRectShadow";
case INT_SAMPLER_1D: return "isampler1D";
case INT_SAMPLER_2D: return "isampler2D";
case INT_SAMPLER_3D: return "isampler3D";
case INT_SAMPLER_CUBE: return "isamplerCube";
case INT_SAMPLER_1D_ARRAY: return "isampler1DArray";
case INT_SAMPLER_2D_ARRAY: return "isampler2DArray";
case INT_SAMPLER_CUBE_MAP_ARRAY: return "isamplerCubeMapArray";
case INT_SAMPLER_2D_MULTISAMPLE: return "isampler2DMS";
case INT_SAMPLER_2D_MULTISAMPLE_ARRAY: return "isampler2DMSArray";
case INT_SAMPLER_BUFFER: return "isamplerBuffer";
case INT_SAMPLER_2D_RECT: return "isampler2DRect";
case UNSIGNED_INT_SAMPLER_1D: return "usample1D";
case UNSIGNED_INT_SAMPLER_2D: return "usample2D";
case UNSIGNED_INT_SAMPLER_3D: return "usample3D";
case UNSIGNED_INT_SAMPLER_CUBE: return "usampleCube";
case UNSIGNED_INT_SAMPLER_1D_ARRAY: return "usample1DArray";
case UNSIGNED_INT_SAMPLER_2D_ARRAY: return "usample2DArray";
case UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY: return "usampleCubeMapArray";
case UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: return "usample2DMS";
case UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: return "usample2DMSArray";
case UNSIGNED_INT_SAMPLER_BUFFER: return "usampleBuffer";
case UNSIGNED_INT_SAMPLER_2D_RECT: return "usample2DRect";
case IMAGE_1D: return "image1D";
case IMAGE_2D: return "image2D";
case IMAGE_3D: return "image3D";
case IMAGE_2D_RECT: return "image2DRect";
case IMAGE_CUBE: return "imageCube";
case IMAGE_BUFFER: return "imageBuffer";
case IMAGE_1D_ARRAY: return "image1DArray";
case IMAGE_2D_ARRAY: return "image2DArray";
case IMAGE_CUBE_MAP_ARRAY: return "imageCubeArray";
case IMAGE_2D_MULTISAMPLE: return "image2DMS";
case IMAGE_2D_MULTISAMPLE_ARRAY: return "image2DMSArray";
case INT_IMAGE_1D: return "iimage1D";
case INT_IMAGE_2D: return "iimage2D";
case INT_IMAGE_3D: return "iimage3D";
case INT_IMAGE_2D_RECT: return "iimage2DRect";
case INT_IMAGE_CUBE: return "iimageCube";
case INT_IMAGE_BUFFER: return "iimageBuffer";
case INT_IMAGE_1D_ARRAY: return "iimage1DArray";
case INT_IMAGE_2D_ARRAY: return "iimage2DArray";
case INT_IMAGE_CUBE_MAP_ARRAY: return "iimageCubeArray";
case INT_IMAGE_2D_MULTISAMPLE: return "iimage2DMS";
case INT_IMAGE_2D_MULTISAMPLE_ARRAY: return "iimage2DMSArray";
case UNSIGNED_INT_IMAGE_1D: return "uimage1D";
case UNSIGNED_INT_IMAGE_2D: return "uimage2D";
case UNSIGNED_INT_IMAGE_3D: return "uimage3D";
case UNSIGNED_INT_IMAGE_2D_RECT: return "uimage2DRect";
case UNSIGNED_INT_IMAGE_CUBE: return "uimageCube";
case UNSIGNED_INT_IMAGE_BUFFER: return "uimageBuffer";
case UNSIGNED_INT_IMAGE_1D_ARRAY: return "uimage1DArray";
case UNSIGNED_INT_IMAGE_2D_ARRAY: return "uimage2DArray";
case UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY: return "uimageCubeArray";
case UNSIGNED_INT_IMAGE_2D_MULTISAMPLE: return "uimage2DMS";
case UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY: return "uimage2DMSArray";
default: return "UNDEFINED";
}
}
int Uniform::getTypeNumComponents( Type t )
{
switch( t )
{
case FLOAT:
case DOUBLE:
case INT:
case UNSIGNED_INT:
case BOOL:
case SAMPLER_1D:
case SAMPLER_2D:
case SAMPLER_3D:
case SAMPLER_CUBE:
case SAMPLER_1D_SHADOW:
case SAMPLER_2D_SHADOW:
case SAMPLER_1D_ARRAY:
case SAMPLER_2D_ARRAY:
case SAMPLER_CUBE_MAP_ARRAY:
case SAMPLER_1D_ARRAY_SHADOW:
case SAMPLER_2D_ARRAY_SHADOW:
case SAMPLER_2D_MULTISAMPLE:
case SAMPLER_2D_MULTISAMPLE_ARRAY:
case SAMPLER_CUBE_SHADOW:
case SAMPLER_CUBE_MAP_ARRAY_SHADOW:
case SAMPLER_BUFFER:
case SAMPLER_2D_RECT:
case SAMPLER_2D_RECT_SHADOW:
case INT_SAMPLER_1D:
case INT_SAMPLER_2D:
case INT_SAMPLER_3D:
case INT_SAMPLER_CUBE:
case INT_SAMPLER_1D_ARRAY:
case INT_SAMPLER_2D_ARRAY:
case INT_SAMPLER_CUBE_MAP_ARRAY:
case INT_SAMPLER_2D_MULTISAMPLE:
case INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
case INT_SAMPLER_BUFFER:
case INT_SAMPLER_2D_RECT:
case UNSIGNED_INT_SAMPLER_1D:
case UNSIGNED_INT_SAMPLER_2D:
case UNSIGNED_INT_SAMPLER_3D:
case UNSIGNED_INT_SAMPLER_CUBE:
case UNSIGNED_INT_SAMPLER_1D_ARRAY:
case UNSIGNED_INT_SAMPLER_2D_ARRAY:
case UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
case UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
case UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
case UNSIGNED_INT_SAMPLER_BUFFER:
case UNSIGNED_INT_SAMPLER_2D_RECT:
case IMAGE_1D:
case IMAGE_2D:
case IMAGE_3D:
case IMAGE_2D_RECT:
case IMAGE_CUBE:
case IMAGE_BUFFER:
case IMAGE_1D_ARRAY:
case IMAGE_2D_ARRAY:
case IMAGE_CUBE_MAP_ARRAY:
case IMAGE_2D_MULTISAMPLE:
case IMAGE_2D_MULTISAMPLE_ARRAY:
case INT_IMAGE_1D:
case INT_IMAGE_2D:
case INT_IMAGE_3D:
case INT_IMAGE_2D_RECT:
case INT_IMAGE_CUBE:
case INT_IMAGE_BUFFER:
case INT_IMAGE_1D_ARRAY:
case INT_IMAGE_2D_ARRAY:
case INT_IMAGE_CUBE_MAP_ARRAY:
case INT_IMAGE_2D_MULTISAMPLE:
case INT_IMAGE_2D_MULTISAMPLE_ARRAY:
case UNSIGNED_INT_IMAGE_1D:
case UNSIGNED_INT_IMAGE_2D:
case UNSIGNED_INT_IMAGE_3D:
case UNSIGNED_INT_IMAGE_2D_RECT:
case UNSIGNED_INT_IMAGE_CUBE:
case UNSIGNED_INT_IMAGE_BUFFER:
case UNSIGNED_INT_IMAGE_1D_ARRAY:
case UNSIGNED_INT_IMAGE_2D_ARRAY:
case UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
case UNSIGNED_INT_IMAGE_2D_MULTISAMPLE:
case UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
return 1;
case FLOAT_VEC2:
case DOUBLE_VEC2:
case INT_VEC2:
case UNSIGNED_INT_VEC2:
case BOOL_VEC2:
return 2;
case FLOAT_VEC3:
case DOUBLE_VEC3:
case INT_VEC3:
case UNSIGNED_INT_VEC3:
case BOOL_VEC3:
return 3;
case FLOAT_VEC4:
case DOUBLE_VEC4:
case FLOAT_MAT2:
case DOUBLE_MAT2:
case INT_VEC4:
case UNSIGNED_INT_VEC4:
case BOOL_VEC4:
return 4;
case FLOAT_MAT2x3:
case FLOAT_MAT3x2:
case DOUBLE_MAT2x3:
case DOUBLE_MAT3x2:
return 6;
case FLOAT_MAT2x4:
case FLOAT_MAT4x2:
case DOUBLE_MAT2x4:
case DOUBLE_MAT4x2:
return 8;
case FLOAT_MAT3:
case DOUBLE_MAT3:
return 9;
case FLOAT_MAT3x4:
case FLOAT_MAT4x3:
case DOUBLE_MAT3x4:
case DOUBLE_MAT4x3:
return 12;
case FLOAT_MAT4:
case DOUBLE_MAT4:
return 16;
default:
return 0;
}
}
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 == "double" ) return DOUBLE;
if( tname == "dvec2" ) return DOUBLE_VEC2;
if( tname == "dvec3" ) return DOUBLE_VEC3;
if( tname == "dvec4" ) return DOUBLE_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 == "unsigned int" || tname == "uint" ) return UNSIGNED_INT;
if( tname == "uvec2" ) return UNSIGNED_INT_VEC2;
if( tname == "uvec3" ) return UNSIGNED_INT_VEC3;
if( tname == "uvec4" ) return UNSIGNED_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" || tname == "mat2x2" ) return FLOAT_MAT2;
if( tname == "mat3" || tname == "mat3x3" ) return FLOAT_MAT3;
if( tname == "mat4" || tname == "mat4x4" ) return FLOAT_MAT4;
if( tname == "mat2x3" ) return FLOAT_MAT2x3;
if( tname == "mat2x4" ) return FLOAT_MAT2x4;
if( tname == "mat3x2" ) return FLOAT_MAT3x2;
if( tname == "mat3x4" ) return FLOAT_MAT3x4;
if( tname == "mat4x2" ) return FLOAT_MAT4x2;
if( tname == "mat4x3" ) return FLOAT_MAT4x3;
if( tname == "mat2d" || tname == "mat2x2d" ) return DOUBLE_MAT2;
if( tname == "mat3d" || tname == "mat3x3d" ) return DOUBLE_MAT3;
if( tname == "mat4d" || tname == "mat4x4d" ) return DOUBLE_MAT4;
if( tname == "mat2x3d" ) return DOUBLE_MAT2x3;
if( tname == "mat2x4d" ) return DOUBLE_MAT2x4;
if( tname == "mat3x2d" ) return DOUBLE_MAT3x2;
if( tname == "mat3x4d" ) return DOUBLE_MAT3x4;
if( tname == "mat4x2d" ) return DOUBLE_MAT4x2;
if( tname == "mat4x3d" ) return DOUBLE_MAT4x3;
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 == "sampler1DArray" ) return SAMPLER_1D_ARRAY;
if( tname == "sampler2DArray" ) return SAMPLER_2D_ARRAY;
if( tname == "samplerCubeMapArray" ) return SAMPLER_CUBE_MAP_ARRAY;
if( tname == "sampler1DArrayShadow" ) return SAMPLER_1D_ARRAY_SHADOW;
if( tname == "sampler2DArrayShadow" ) return SAMPLER_2D_ARRAY_SHADOW;
if( tname == "sampler2DMS" ) return SAMPLER_2D_MULTISAMPLE;
if( tname == "sampler2DMSArray" ) return SAMPLER_2D_MULTISAMPLE_ARRAY;
if( tname == "samplerCubeShadow" ) return SAMPLER_CUBE_SHADOW;
if( tname == "samplerCubeMapArrayShadow" ) return SAMPLER_CUBE_MAP_ARRAY_SHADOW;
if( tname == "samplerBuffer" ) return SAMPLER_BUFFER;
if( tname == "sampler2DRect" ) return SAMPLER_2D_RECT;
if( tname == "sampler2DRectShadow" ) return SAMPLER_2D_RECT_SHADOW;
if( tname == "isampler1D" ) return INT_SAMPLER_1D;
if( tname == "isampler2D" ) return INT_SAMPLER_2D;
if( tname == "isampler3D" ) return INT_SAMPLER_3D;
if( tname == "isamplerCube" ) return INT_SAMPLER_CUBE;
if( tname == "isampler1DArray" ) return INT_SAMPLER_1D_ARRAY;
if( tname == "isampler2DArray" ) return INT_SAMPLER_2D_ARRAY;
if( tname == "isamplerCubeMapArray" ) return INT_SAMPLER_CUBE_MAP_ARRAY;
if( tname == "isampler2DMS" ) return INT_SAMPLER_2D_MULTISAMPLE;
if( tname == "isampler2DMSArray" ) return INT_SAMPLER_2D_MULTISAMPLE_ARRAY;
if( tname == "isamplerBuffer" ) return INT_SAMPLER_BUFFER;
if( tname == "isampler2DRect" ) return INT_SAMPLER_2D_RECT;
if( tname == "usampler1D" ) return UNSIGNED_INT_SAMPLER_1D;
if( tname == "usampler2D" ) return UNSIGNED_INT_SAMPLER_2D;
if( tname == "usampler3D" ) return UNSIGNED_INT_SAMPLER_3D;
if( tname == "usamplerCube" ) return UNSIGNED_INT_SAMPLER_CUBE;
if( tname == "usampler1DArray" ) return UNSIGNED_INT_SAMPLER_1D_ARRAY;
if( tname == "usampler2DArray" ) return UNSIGNED_INT_SAMPLER_2D_ARRAY;
if( tname == "usamplerCubeMapArray" ) return UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY;
if( tname == "usampler2DMS" ) return UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE;
if( tname == "usampler2DMSArray" ) return UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY;
if( tname == "usamplerBuffer" ) return UNSIGNED_INT_SAMPLER_BUFFER;
if( tname == "usampler2DRect" ) return UNSIGNED_INT_SAMPLER_2D_RECT;
if( tname == "image1D" ) return IMAGE_1D;
if( tname == "image2D" ) return IMAGE_2D;
if( tname == "image3D" ) return IMAGE_3D;
if( tname == "image2DRect" ) return IMAGE_2D_RECT;
if( tname == "imageCube" ) return IMAGE_CUBE;
if( tname == "imageBuffer" ) return IMAGE_BUFFER;
if( tname == "image1DArray" ) return IMAGE_1D_ARRAY;
if( tname == "image2DArray" ) return IMAGE_2D_ARRAY;
if( tname == "imageCubeArray" ) return IMAGE_CUBE_MAP_ARRAY;
if( tname == "image2DMS" ) return IMAGE_2D_MULTISAMPLE;
if( tname == "image2DMSArray" ) return IMAGE_2D_MULTISAMPLE_ARRAY;
if( tname == "iimage1D" ) return INT_IMAGE_1D;
if( tname == "iimage2D" ) return INT_IMAGE_2D;
if( tname == "iimage3D" ) return INT_IMAGE_3D;
if( tname == "iimage2DRect" ) return INT_IMAGE_2D_RECT;
if( tname == "iimageCube" ) return INT_IMAGE_CUBE;
if( tname == "iimageBuffer" ) return INT_IMAGE_BUFFER;
if( tname == "iimage1DArray" ) return INT_IMAGE_1D_ARRAY;
if( tname == "iimage2DArray" ) return INT_IMAGE_2D_ARRAY;
if( tname == "iimageCubeArray" ) return INT_IMAGE_CUBE_MAP_ARRAY;
if( tname == "iimage2DMS" ) return INT_IMAGE_2D_MULTISAMPLE;
if( tname == "iimage2DMSArray" ) return INT_IMAGE_2D_MULTISAMPLE_ARRAY;
if( tname == "uimage1D" ) return UNSIGNED_INT_IMAGE_1D;
if( tname == "uimage2D" ) return UNSIGNED_INT_IMAGE_2D;
if( tname == "uimage3D" ) return UNSIGNED_INT_IMAGE_3D;
if( tname == "uimage2DRect" ) return UNSIGNED_INT_IMAGE_2D_RECT;
if( tname == "uimageCube" ) return UNSIGNED_INT_IMAGE_CUBE;
if( tname == "uimageBuffer" ) return UNSIGNED_INT_IMAGE_BUFFER;
if( tname == "uimage1DArray" ) return UNSIGNED_INT_IMAGE_1D_ARRAY;
if( tname == "uimage2DArray" ) return UNSIGNED_INT_IMAGE_2D_ARRAY;
if( tname == "uimageCubeArray" ) return UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY;
if( tname == "uimage2DMS" ) return UNSIGNED_INT_IMAGE_2D_MULTISAMPLE;
if( tname == "uimage2DMSArray" ) return UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY;
return UNDEFINED;
}
Uniform::Type Uniform::getGlApiType( 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:
case SAMPLER_1D_ARRAY:
case SAMPLER_2D_ARRAY:
case SAMPLER_CUBE_MAP_ARRAY:
case SAMPLER_1D_ARRAY_SHADOW:
case SAMPLER_2D_ARRAY_SHADOW:
case SAMPLER_2D_MULTISAMPLE:
case SAMPLER_2D_MULTISAMPLE_ARRAY:
case SAMPLER_CUBE_SHADOW:
case SAMPLER_CUBE_MAP_ARRAY_SHADOW:
case SAMPLER_BUFFER:
case SAMPLER_2D_RECT:
case SAMPLER_2D_RECT_SHADOW:
case INT_SAMPLER_1D:
case INT_SAMPLER_2D:
case INT_SAMPLER_3D:
case INT_SAMPLER_CUBE:
case INT_SAMPLER_1D_ARRAY:
case INT_SAMPLER_2D_ARRAY:
case INT_SAMPLER_CUBE_MAP_ARRAY:
case INT_SAMPLER_2D_MULTISAMPLE:
case INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
case INT_SAMPLER_BUFFER:
case INT_SAMPLER_2D_RECT:
case UNSIGNED_INT_SAMPLER_1D:
case UNSIGNED_INT_SAMPLER_2D:
case UNSIGNED_INT_SAMPLER_3D:
case UNSIGNED_INT_SAMPLER_CUBE:
case UNSIGNED_INT_SAMPLER_1D_ARRAY:
case UNSIGNED_INT_SAMPLER_2D_ARRAY:
case UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
case UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
case UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
case UNSIGNED_INT_SAMPLER_BUFFER:
case UNSIGNED_INT_SAMPLER_2D_RECT:
case IMAGE_1D:
case IMAGE_2D:
case IMAGE_3D:
case IMAGE_2D_RECT:
case IMAGE_CUBE:
case IMAGE_BUFFER:
case IMAGE_1D_ARRAY:
case IMAGE_2D_ARRAY:
case IMAGE_CUBE_MAP_ARRAY:
case IMAGE_2D_MULTISAMPLE:
case IMAGE_2D_MULTISAMPLE_ARRAY:
case INT_IMAGE_1D:
case INT_IMAGE_2D:
case INT_IMAGE_3D:
case INT_IMAGE_2D_RECT:
case INT_IMAGE_CUBE:
case INT_IMAGE_BUFFER:
case INT_IMAGE_1D_ARRAY:
case INT_IMAGE_2D_ARRAY:
case INT_IMAGE_CUBE_MAP_ARRAY:
case INT_IMAGE_2D_MULTISAMPLE:
case INT_IMAGE_2D_MULTISAMPLE_ARRAY:
case UNSIGNED_INT_IMAGE_1D:
case UNSIGNED_INT_IMAGE_2D:
case UNSIGNED_INT_IMAGE_3D:
case UNSIGNED_INT_IMAGE_2D_RECT:
case UNSIGNED_INT_IMAGE_CUBE:
case UNSIGNED_INT_IMAGE_BUFFER:
case UNSIGNED_INT_IMAGE_1D_ARRAY:
case UNSIGNED_INT_IMAGE_2D_ARRAY:
case UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
case UNSIGNED_INT_IMAGE_2D_MULTISAMPLE:
case UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
return INT;
case BOOL_VEC2:
return INT_VEC2;
case BOOL_VEC3:
return INT_VEC3;
case BOOL_VEC4:
return INT_VEC4;
default:
return 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:
case FLOAT_MAT2x3:
case FLOAT_MAT2x4:
case FLOAT_MAT3x2:
case FLOAT_MAT3x4:
case FLOAT_MAT4x2:
case FLOAT_MAT4x3:
return GL_FLOAT;
case DOUBLE:
case DOUBLE_VEC2:
case DOUBLE_VEC3:
case DOUBLE_VEC4:
case DOUBLE_MAT2:
case DOUBLE_MAT3:
case DOUBLE_MAT4:
case DOUBLE_MAT2x3:
case DOUBLE_MAT2x4:
case DOUBLE_MAT3x2:
case DOUBLE_MAT3x4:
case DOUBLE_MAT4x2:
case DOUBLE_MAT4x3:
return GL_DOUBLE;
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:
case SAMPLER_1D_ARRAY:
case SAMPLER_2D_ARRAY:
case SAMPLER_CUBE_MAP_ARRAY:
case SAMPLER_1D_ARRAY_SHADOW:
case SAMPLER_2D_ARRAY_SHADOW:
case SAMPLER_2D_MULTISAMPLE:
case SAMPLER_2D_MULTISAMPLE_ARRAY:
case SAMPLER_CUBE_SHADOW:
case SAMPLER_CUBE_MAP_ARRAY_SHADOW:
case SAMPLER_BUFFER:
case SAMPLER_2D_RECT:
case SAMPLER_2D_RECT_SHADOW:
case INT_SAMPLER_1D:
case INT_SAMPLER_2D:
case INT_SAMPLER_3D:
case INT_SAMPLER_CUBE:
case INT_SAMPLER_1D_ARRAY:
case INT_SAMPLER_2D_ARRAY:
case INT_SAMPLER_CUBE_MAP_ARRAY:
case INT_SAMPLER_2D_MULTISAMPLE:
case INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
case INT_SAMPLER_BUFFER:
case INT_SAMPLER_2D_RECT:
case UNSIGNED_INT_SAMPLER_1D:
case UNSIGNED_INT_SAMPLER_2D:
case UNSIGNED_INT_SAMPLER_3D:
case UNSIGNED_INT_SAMPLER_CUBE:
case UNSIGNED_INT_SAMPLER_1D_ARRAY:
case UNSIGNED_INT_SAMPLER_2D_ARRAY:
case UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
case UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
case UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
case UNSIGNED_INT_SAMPLER_BUFFER:
case UNSIGNED_INT_SAMPLER_2D_RECT:
case IMAGE_1D:
case IMAGE_2D:
case IMAGE_3D:
case IMAGE_2D_RECT:
case IMAGE_CUBE:
case IMAGE_BUFFER:
case IMAGE_1D_ARRAY:
case IMAGE_2D_ARRAY:
case IMAGE_CUBE_MAP_ARRAY:
case IMAGE_2D_MULTISAMPLE:
case IMAGE_2D_MULTISAMPLE_ARRAY:
case INT_IMAGE_1D:
case INT_IMAGE_2D:
case INT_IMAGE_3D:
case INT_IMAGE_2D_RECT:
case INT_IMAGE_CUBE:
case INT_IMAGE_BUFFER:
case INT_IMAGE_1D_ARRAY:
case INT_IMAGE_2D_ARRAY:
case INT_IMAGE_CUBE_MAP_ARRAY:
case INT_IMAGE_2D_MULTISAMPLE:
case INT_IMAGE_2D_MULTISAMPLE_ARRAY:
case UNSIGNED_INT_IMAGE_1D:
case UNSIGNED_INT_IMAGE_2D:
case UNSIGNED_INT_IMAGE_3D:
case UNSIGNED_INT_IMAGE_2D_RECT:
case UNSIGNED_INT_IMAGE_CUBE:
case UNSIGNED_INT_IMAGE_BUFFER:
case UNSIGNED_INT_IMAGE_1D_ARRAY:
case UNSIGNED_INT_IMAGE_2D_ARRAY:
case UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
case UNSIGNED_INT_IMAGE_2D_MULTISAMPLE:
case UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
return GL_INT;
case UNSIGNED_INT:
case UNSIGNED_INT_VEC2:
case UNSIGNED_INT_VEC3:
case UNSIGNED_INT_VEC4:
return GL_UNSIGNED_INT;
default:
return 0;
}
}
unsigned int Uniform::getNameID(const std::string& name)
{
typedef std::map<std::string, unsigned int> UniformNameIDMap;
static OpenThreads::Mutex s_mutex_uniformNameIDMap;
static UniformNameIDMap s_uniformNameIDMap;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_uniformNameIDMap);
UniformNameIDMap::iterator it = s_uniformNameIDMap.find(name);
if (it != s_uniformNameIDMap.end())
{
return it->second;
}
unsigned int id = s_uniformNameIDMap.size();
s_uniformNameIDMap.insert(UniformNameIDMap::value_type(name, id));
return id;
}
// Use a proxy to force the initialization of the static variables in the Unifrom::getNameID() method during static initialization
OSG_INIT_SINGLETON_PROXY(UniformNameIDStaticInitializationProxy, Uniform::getNameID(std::string()))
///////////////////////////////////////////////////////////////////////////
// value constructors for single-element (ie: non-array) uniforms
Uniform::Uniform( const char* name, float f ) :
_type(FLOAT), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( f );
}
Uniform::Uniform( const char* name, const osg::Vec2& v2 ) :
_type(FLOAT_VEC2), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( v2 );
}
Uniform::Uniform( const char* name, const osg::Vec3& v3 ) :
_type(FLOAT_VEC3), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( v3 );
}
Uniform::Uniform( const char* name, const osg::Vec4& v4 ) :
_type(FLOAT_VEC4), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( v4 );
}
Uniform::Uniform( const char* name, const osg::Matrix2& m2 ) :
_type(FLOAT_MAT2), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( m2 );
}
Uniform::Uniform( const char* name, const osg::Matrix3& m3 ) :
_type(FLOAT_MAT3), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( m3 );
}
Uniform::Uniform( const char* name, const osg::Matrixf& m4 ) :
_type(FLOAT_MAT4), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( m4 );
}
Uniform::Uniform( const char* name, const osg::Matrix2x3& m2x3 ) :
_type(FLOAT_MAT2x3), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( m2x3 );
}
Uniform::Uniform( const char* name, const osg::Matrix2x4& m2x4 ) :
_type(FLOAT_MAT2x4), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( m2x4 );
}
Uniform::Uniform( const char* name, const osg::Matrix3x2& m3x2 ) :
_type(FLOAT_MAT3x2), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( m3x2 );
}
Uniform::Uniform( const char* name, const osg::Matrix3x4& m3x4 ) :
_type(FLOAT_MAT3x4), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( m3x4 );
}
Uniform::Uniform( const char* name, const osg::Matrix4x2& m4x2 ) :
_type(FLOAT_MAT4x2), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( m4x2 );
}
Uniform::Uniform( const char* name, const osg::Matrix4x3& m4x3 ) :
_type(FLOAT_MAT4x3), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( m4x3 );
}
Uniform::Uniform( const char* name, double d ) :
_type(DOUBLE), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( d );
}
Uniform::Uniform( const char* name, const osg::Vec2d& v2 ) :
_type(DOUBLE_VEC2), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( v2 );
}
Uniform::Uniform( const char* name, const osg::Vec3d& v3 ) :
_type(DOUBLE_VEC3), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( v3 );
}
Uniform::Uniform( const char* name, const osg::Vec4d& v4 ) :
_type(DOUBLE_VEC4), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( v4 );
}
Uniform::Uniform( const char* name, const osg::Matrix2d& m2 ) :
_type(DOUBLE_MAT2), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( m2 );
}
Uniform::Uniform( const char* name, const osg::Matrix3d& m3 ) :
_type(DOUBLE_MAT3), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( m3 );
}
Uniform::Uniform( const char* name, const osg::Matrixd& m4 ) :
_type(DOUBLE_MAT4), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( m4 );
}
Uniform::Uniform( const char* name, const osg::Matrix2x3d& m2x3 ) :
_type(DOUBLE_MAT2x3), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( m2x3 );
}
Uniform::Uniform( const char* name, const osg::Matrix2x4d& m2x4 ) :
_type(DOUBLE_MAT2x4), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( m2x4 );
}
Uniform::Uniform( const char* name, const osg::Matrix3x2d& m3x2 ) :
_type(DOUBLE_MAT3x2), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( m3x2 );
}
Uniform::Uniform( const char* name, const osg::Matrix3x4d& m3x4 ) :
_type(DOUBLE_MAT3x4), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( m3x4 );
}
Uniform::Uniform( const char* name, const osg::Matrix4x2d& m4x2 ) :
_type(DOUBLE_MAT4x2), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( m4x2 );
}
Uniform::Uniform( const char* name, const osg::Matrix4x3d& m4x3 ) :
_type(DOUBLE_MAT4x3), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( m4x3 );
}
Uniform::Uniform( const char* name, int i ) :
_type(INT), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( i );
}
Uniform::Uniform( const char* name, int i0, int i1 ) :
_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), _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), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( i0, i1, i2, i3 );
}
Uniform::Uniform( const char* name, unsigned int ui ) :
_type(UNSIGNED_INT), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( ui );
}
Uniform::Uniform( const char* name, unsigned int ui0, unsigned int ui1 ) :
_type(UNSIGNED_INT_VEC2), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( ui0, ui1 );
}
Uniform::Uniform( const char* name, unsigned int ui0, unsigned int ui1, unsigned int ui2 ) :
_type(UNSIGNED_INT_VEC3), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( ui0, ui1, ui2 );
}
Uniform::Uniform( const char* name, unsigned int ui0, unsigned int ui1, unsigned int ui2, unsigned int ui3 ) :
_type(UNSIGNED_INT_VEC4), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( ui0, ui1, ui2, ui3 );
}
Uniform::Uniform( const char* name, bool b ) :
_type(BOOL), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( b );
}
Uniform::Uniform( const char* name, bool b0, bool b1 ) :
_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), _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), _numElements(1), _modifiedCount(0)
{
setName(name);
allocateDataArray();
set( b0, b1, b2, b3 );
}
///////////////////////////////////////////////////////////////////////////
// Value assignment for single-element (ie: non-array) uniforms.
// (For backwards compatability, if not already configured, set the
// Uniform's _numElements=1)
bool Uniform::set( float f )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,f) : false;
}
bool Uniform::set( const osg::Vec2& v2 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,v2) : false;
}
bool Uniform::set( const osg::Vec3& v3 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,v3) : false;
}
bool Uniform::set( const osg::Vec4& v4 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,v4) : false;
}
bool Uniform::set( const osg::Matrix2& m2 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,m2) : false;
}
bool Uniform::set( const osg::Matrix3& m3 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,m3) : false;
}
bool Uniform::set( const osg::Matrixf& m4 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,m4) : false;
}
bool Uniform::set( const osg::Matrix2x3& m2x3 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,m2x3) : false;
}
bool Uniform::set( const osg::Matrix2x4& m2x4 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,m2x4) : false;
}
bool Uniform::set( const osg::Matrix3x2& m3x2 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,m3x2) : false;
}
bool Uniform::set( const osg::Matrix3x4& m3x4 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,m3x4) : false;
}
bool Uniform::set( const osg::Matrix4x2& m4x2 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,m4x2) : false;
}
bool Uniform::set( const osg::Matrix4x3& m4x3 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,m4x3) : false;
}
bool Uniform::set( double d )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,d) : false;
}
bool Uniform::set( const osg::Vec2d& v2 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,v2) : false;
}
bool Uniform::set( const osg::Vec3d& v3 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,v3) : false;
}
bool Uniform::set( const osg::Vec4d& v4 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,v4) : false;
}
bool Uniform::set( const osg::Matrix2d& m2 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,m2) : false;
}
bool Uniform::set( const osg::Matrix3d& m3 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,m3) : false;
}
bool Uniform::set( const osg::Matrixd& m4 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,m4) : false;
}
bool Uniform::set( const osg::Matrix2x3d& m2x3 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,m2x3) : false;
}
bool Uniform::set( const osg::Matrix2x4d& m2x4 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,m2x4) : false;
}
bool Uniform::set( const osg::Matrix3x2d& m3x2 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,m3x2) : false;
}
bool Uniform::set( const osg::Matrix3x4d& m3x4 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,m3x4) : false;
}
bool Uniform::set( const osg::Matrix4x2d& m4x2 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,m4x2) : false;
}
bool Uniform::set( const osg::Matrix4x3d& m4x3 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,m4x3) : false;
}
bool Uniform::set( int i )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,i) : false;
}
bool Uniform::set( int i0, int i1 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,i0,i1) : false;
}
bool Uniform::set( int i0, int i1, int i2 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,i0,i1,i2) : false;
}
bool Uniform::set( int i0, int i1, int i2, int i3 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,i0,i1,i2,i3) : false;
}
bool Uniform::set( unsigned int ui )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,ui) : false;
}
bool Uniform::set( unsigned int ui0, unsigned int ui1 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,ui0,ui1) : false;
}
bool Uniform::set( unsigned int ui0, unsigned int ui1, unsigned int ui2 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,ui0,ui1,ui2) : false;
}
bool Uniform::set( unsigned int ui0, unsigned int ui1, unsigned int ui2, unsigned int ui3 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,ui0,ui1,ui2,ui3) : false;
}
bool Uniform::set( bool b )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,b) : false;
}
bool Uniform::set( bool b0, bool b1 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,b0,b1) : false;
}
bool Uniform::set( bool b0, bool b1, bool b2 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,b0,b1,b2) : false;
}
bool Uniform::set( bool b0, bool b1, bool b2, bool b3 )
{
if( getNumElements() == 0 ) setNumElements(1);
return isScalar() ? setElement(0,b0,b1,b2,b3) : false;
}
///////////////////////////////////////////////////////////////////////////
// Value query for single-element (ie: non-array) uniforms.
bool Uniform::get( float& f ) const
{
return isScalar() ? getElement(0,f) : false;
}
bool Uniform::get( osg::Vec2& v2 ) const
{
return isScalar() ? getElement(0,v2) : false;
}
bool Uniform::get( osg::Vec3& v3 ) const
{
return isScalar() ? getElement(0,v3) : false;
}
bool Uniform::get( osg::Vec4& v4 ) const
{
return isScalar() ? getElement(0,v4) : false;
}
bool Uniform::get( osg::Matrix2& m2 ) const
{
return isScalar() ? getElement(0,m2) : false;
}
bool Uniform::get( osg::Matrix3& m3 ) const
{
return isScalar() ? getElement(0,m3) : false;
}
bool Uniform::get( osg::Matrixf& m4 ) const
{
return isScalar() ? getElement(0,m4) : false;
}
bool Uniform::get( osg::Matrix2x3& m2x3 ) const
{
return isScalar() ? getElement(0,m2x3) : false;
}
bool Uniform::get( osg::Matrix2x4& m2x4 ) const
{
return isScalar() ? getElement(0,m2x4) : false;
}
bool Uniform::get( osg::Matrix3x2& m3x2 ) const
{
return isScalar() ? getElement(0,m3x2) : false;
}
bool Uniform::get( osg::Matrix3x4& m3x4 ) const
{
return isScalar() ? getElement(0,m3x4) : false;
}
bool Uniform::get( osg::Matrix4x2& m4x2 ) const
{
return isScalar() ? getElement(0,m4x2) : false;
}
bool Uniform::get( osg::Matrix4x3& m4x3 ) const
{
return isScalar() ? getElement(0,m4x3) : false;
}
bool Uniform::get( double& d ) const
{
return isScalar() ? getElement(0,d) : false;
}
bool Uniform::get( osg::Vec2d& v2 ) const
{
return isScalar() ? getElement(0,v2) : false;
}
bool Uniform::get( osg::Vec3d& v3 ) const
{
return isScalar() ? getElement(0,v3) : false;
}
bool Uniform::get( osg::Vec4d& v4 ) const
{
return isScalar() ? getElement(0,v4) : false;
}
bool Uniform::get( osg::Matrix2d& m2 ) const
{
return isScalar() ? getElement(0,m2) : false;
}
bool Uniform::get( osg::Matrix3d& m3 ) const
{
return isScalar() ? getElement(0,m3) : false;
}
bool Uniform::get( osg::Matrixd& m4 ) const
{
return isScalar() ? getElement(0,m4) : false;
}
bool Uniform::get( osg::Matrix2x3d& m2x3 ) const
{
return isScalar() ? getElement(0,m2x3) : false;
}
bool Uniform::get( osg::Matrix2x4d& m2x4 ) const
{
return isScalar() ? getElement(0,m2x4) : false;
}
bool Uniform::get( osg::Matrix3x2d& m3x2 ) const
{
return isScalar() ? getElement(0,m3x2) : false;
}
bool Uniform::get( osg::Matrix3x4d& m3x4 ) const
{
return isScalar() ? getElement(0,m3x4) : false;
}
bool Uniform::get( osg::Matrix4x2d& m4x2 ) const
{
return isScalar() ? getElement(0,m4x2) : false;
}
bool Uniform::get( osg::Matrix4x3d& m4x3 ) const
{
return isScalar() ? getElement(0,m4x3) : false;
}
bool Uniform::get( int& i ) const
{
return isScalar() ? getElement(0,i) : false;
}
bool Uniform::get( int& i0, int& i1 ) const
{
return isScalar() ? getElement(0,i0,i1) : false;
}
bool Uniform::get( int& i0, int& i1, int& i2 ) const
{
return isScalar() ? getElement(0,i0,i1,i2) : false;
}
bool Uniform::get( int& i0, int& i1, int& i2, int& i3 ) const
{
return isScalar() ? getElement(0,i0,i1,i2,i3) : false;
}
bool Uniform::get( unsigned int& ui ) const
{
return isScalar() ? getElement(0,ui) : false;
}
bool Uniform::get( unsigned int& ui0, unsigned int& ui1 ) const
{
return isScalar() ? getElement(0,ui0,ui1) : false;
}
bool Uniform::get( unsigned int& ui0, unsigned int& ui1, unsigned int& ui2 ) const
{
return isScalar() ? getElement(0,ui0,ui1,ui2) : false;
}
bool Uniform::get( unsigned int& ui0, unsigned int& ui1, unsigned int& ui2, unsigned int& ui3 ) const
{
return isScalar() ? getElement(0,ui0,ui1,ui2,ui3) : false;
}
bool Uniform::get( bool& b ) const
{
return isScalar() ? getElement(0,b) : false;
}
bool Uniform::get( bool& b0, bool& b1 ) const
{
return isScalar() ? getElement(0,b0,b1) : false;
}
bool Uniform::get( bool& b0, bool& b1, bool& b2 ) const
{
return isScalar() ? getElement(0,b0,b1,b2) : false;
}
bool Uniform::get( bool& b0, bool& b1, bool& b2, bool& b3 ) const
{
return isScalar() ? getElement(0,b0,b1,b2,b3) : false;
}
///////////////////////////////////////////////////////////////////////////
// Value assignment for array uniforms.
bool Uniform::setElement( unsigned int index, float f )
{
if( index>=getNumElements() || !isCompatibleType(FLOAT) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
(*_floatArray)[j] = f;
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Vec2& v2 )
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_VEC2) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
(*_floatArray)[j] = v2.x();
(*_floatArray)[j+1] = v2.y();
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Vec3& v3 )
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_VEC3) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
(*_floatArray)[j] = v3.x();
(*_floatArray)[j+1] = v3.y();
(*_floatArray)[j+2] = v3.z();
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Vec4& v4 )
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_VEC4) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
(*_floatArray)[j] = v4.x();
(*_floatArray)[j+1] = v4.y();
(*_floatArray)[j+2] = v4.z();
(*_floatArray)[j+3] = v4.w();
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Matrix2& m2 )
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT2) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
for( int i = 0; i < 4; ++i ) (*_floatArray)[j+i] = m2[i];
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Matrix3& m3 )
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT3) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
for( int i = 0; i < 9; ++i ) (*_floatArray)[j+i] = m3[i];
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Matrixf& m4 )
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT4) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
const Matrixf::value_type* p = m4.ptr();
for( int i = 0; i < 16; ++i ) (*_floatArray)[j+i] = p[i];
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Matrix2x3& m2x3 )
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT2x3) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
for( int i = 0; i < 6; ++i ) (*_floatArray)[j+i] = m2x3[i];
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Matrix2x4& m2x4 )
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT2x4) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
for( int i = 0; i < 8; ++i ) (*_floatArray)[j+i] = m2x4[i];
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Matrix3x2& m3x2 )
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT3x2) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
for( int i = 0; i < 6; ++i ) (*_floatArray)[j+i] = m3x2[i];
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Matrix3x4& m3x4 )
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT3x4) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
for( int i = 0; i < 12; ++i ) (*_floatArray)[j+i] = m3x4[i];
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Matrix4x2& m4x2 )
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT4x2) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
for( int i = 0; i < 8; ++i ) (*_floatArray)[j+i] = m4x2[i];
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Matrix4x3& m4x3 )
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT4x3) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
for( int i = 0; i < 12; ++i ) (*_floatArray)[j+i] = m4x3[i];
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, double d )
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
(*_doubleArray)[j] = d;
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Vec2d& v2 )
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_VEC2) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
(*_doubleArray)[j] = v2.x();
(*_doubleArray)[j+1] = v2.y();
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Vec3d& v3 )
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_VEC3) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
(*_doubleArray)[j] = v3.x();
(*_doubleArray)[j+1] = v3.y();
(*_doubleArray)[j+2] = v3.z();
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Vec4d& v4 )
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_VEC4) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
(*_doubleArray)[j] = v4.x();
(*_doubleArray)[j+1] = v4.y();
(*_doubleArray)[j+2] = v4.z();
(*_doubleArray)[j+3] = v4.w();
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Matrix2d& m2 )
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_MAT2) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
for( int i = 0; i < 4; ++i ) (*_doubleArray)[j+i] = m2[i];
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Matrix3d& m3 )
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_MAT3) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
for( int i = 0; i < 9; ++i ) (*_doubleArray)[j+i] = m3[i];
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Matrixd& m4 )
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_MAT4, FLOAT_MAT4) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
if (_type == DOUBLE_MAT4)
{
const Matrixd::value_type* p = m4.ptr();
for( int i = 0; i < 16; ++i ) (*_doubleArray)[j+i] = p[i];
}
else //if (_type == FLOAT_MAT4) for backward compatibility only
{
const Matrixd::value_type* p = m4.ptr();
for( int i = 0; i < 16; ++i ) (*_floatArray)[j+i] = static_cast<float>(p[i]);
}
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Matrix2x3d& m2x3 )
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_MAT2x3) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
for( int i = 0; i < 6; ++i ) (*_doubleArray)[j+i] = m2x3[i];
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Matrix2x4d& m2x4 )
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_MAT2x4) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
for( int i = 0; i < 8; ++i ) (*_doubleArray)[j+i] = m2x4[i];
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Matrix3x2d& m3x2 )
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_MAT3x2) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
for( int i = 0; i < 6; ++i ) (*_doubleArray)[j+i] = m3x2[i];
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Matrix3x4d& m3x4 )
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_MAT3x4) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
for( int i = 0; i < 12; ++i ) (*_doubleArray)[j+i] = m3x4[i];
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Matrix4x2d& m4x2 )
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_MAT4x2) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
for( int i = 0; i < 8; ++i ) (*_doubleArray)[j+i] = m4x2[i];
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, const osg::Matrix4x3d& m4x3 )
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_MAT4x3) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
for( int i = 0; i < 12; ++i ) (*_doubleArray)[j+i] = m4x3[i];
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, int i )
{
if( index>=getNumElements() || !isCompatibleType(INT) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
(*_intArray)[j] = i;
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, int i0, int i1 )
{
if( index>=getNumElements() || !isCompatibleType(INT_VEC2) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
(*_intArray)[j] = i0;
(*_intArray)[j+1] = i1;
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, int i0, int i1, int i2 )
{
if( index>=getNumElements() || !isCompatibleType(INT_VEC3) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
(*_intArray)[j] = i0;
(*_intArray)[j+1] = i1;
(*_intArray)[j+2] = i2;
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, int i0, int i1, int i2, int i3 )
{
if( index>=getNumElements() || !isCompatibleType(INT_VEC4) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
(*_intArray)[j] = i0;
(*_intArray)[j+1] = i1;
(*_intArray)[j+2] = i2;
(*_intArray)[j+3] = i3;
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, unsigned int ui )
{
if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
(*_uintArray)[j] = ui;
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, unsigned int ui0, unsigned int ui1 )
{
if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT_VEC2) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
(*_uintArray)[j] = ui0;
(*_uintArray)[j+1] = ui1;
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, unsigned int ui0, unsigned int ui1, unsigned int ui2 )
{
if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT_VEC3) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
(*_uintArray)[j] = ui0;
(*_uintArray)[j+1] = ui1;
(*_uintArray)[j+2] = ui2;
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, unsigned int ui0, unsigned int ui1, unsigned int ui2, unsigned int ui3 )
{
if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT_VEC4) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
(*_uintArray)[j] = ui0;
(*_uintArray)[j+1] = ui1;
(*_uintArray)[j+2] = ui2;
(*_uintArray)[j+3] = ui3;
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, bool b )
{
if( index>=getNumElements() || !isCompatibleType(BOOL) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
(*_intArray)[j] = b;
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, bool b0, bool b1 )
{
if( index>=getNumElements() || !isCompatibleType(BOOL_VEC2) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
(*_intArray)[j] = b0;
(*_intArray)[j+1] = b1;
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, bool b0, bool b1, bool b2 )
{
if( index>=getNumElements() || !isCompatibleType(BOOL_VEC3) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
(*_intArray)[j] = b0;
(*_intArray)[j+1] = b1;
(*_intArray)[j+2] = b2;
dirty();
return true;
}
bool Uniform::setElement( unsigned int index, bool b0, bool b1, bool b2, bool b3 )
{
if( index>=getNumElements() || !isCompatibleType(BOOL_VEC4) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
(*_intArray)[j] = b0;
(*_intArray)[j+1] = b1;
(*_intArray)[j+2] = b2;
(*_intArray)[j+3] = b3;
dirty();
return true;
}
///////////////////////////////////////////////////////////////////////////
// Value query for array uniforms.
bool Uniform::getElement( unsigned int index, float& f ) const
{
if( index>=getNumElements() || !isCompatibleType(FLOAT) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
f = (*_floatArray)[j];
return true;
}
bool Uniform::getElement( unsigned int index, osg::Vec2& v2 ) const
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_VEC2) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
v2.x() = (*_floatArray)[j];
v2.y() = (*_floatArray)[j+1];
return true;
}
bool Uniform::getElement( unsigned int index, osg::Vec3& v3 ) const
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_VEC3) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
v3.x() = (*_floatArray)[j];
v3.y() = (*_floatArray)[j+1];
v3.z() = (*_floatArray)[j+2];
return true;
}
bool Uniform::getElement( unsigned int index, osg::Vec4& v4 ) const
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_VEC4) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
v4.x() = (*_floatArray)[j];
v4.y() = (*_floatArray)[j+1];
v4.z() = (*_floatArray)[j+2];
v4.w() = (*_floatArray)[j+3];
return true;
}
bool Uniform::getElement( unsigned int index, osg::Matrix2& m2 ) const
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT2) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
m2.Matrix2::base_class::set( &((*_floatArray)[j]) );
return true;
}
bool Uniform::getElement( unsigned int index, osg::Matrix3& m3 ) const
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT3) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
m3.Matrix3::base_class::set( &((*_floatArray)[j]) );
return true;
}
bool Uniform::getElement( unsigned int index, osg::Matrixf& m4 ) const
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT4) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
m4.set( &((*_floatArray)[j]) );
return true;
}
bool Uniform::getElement( unsigned int index, osg::Matrix2x3& m2x3 ) const
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT2x3) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
m2x3.Matrix2x3::base_class::set( &((*_floatArray)[j]) );
return true;
}
bool Uniform::getElement( unsigned int index, osg::Matrix2x4& m2x4 ) const
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT2x4) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
m2x4.Matrix2x4::base_class::set( &((*_floatArray)[j]) );
return true;
}
bool Uniform::getElement( unsigned int index, osg::Matrix3x2& m3x2 ) const
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT3x2) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
m3x2.Matrix3x2::base_class::set( &((*_floatArray)[j]) );
return true;
}
bool Uniform::getElement( unsigned int index, osg::Matrix3x4& m3x4 ) const
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT3x4) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
m3x4.Matrix3x4::base_class::set( &((*_floatArray)[j]) );
return true;
}
bool Uniform::getElement( unsigned int index, osg::Matrix4x2& m4x2 ) const
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT4x2) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
m4x2.Matrix4x2::base_class::set( &((*_floatArray)[j]) );
return true;
}
bool Uniform::getElement( unsigned int index, osg::Matrix4x3& m4x3 ) const
{
if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT4x3) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
m4x3.Matrix4x3::base_class::set( &((*_floatArray)[j]) );
return true;
}
bool Uniform::getElement( unsigned int index, double& d ) const
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
d = (*_doubleArray)[j];
return true;
}
bool Uniform::getElement( unsigned int index, osg::Vec2d& v2 ) const
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_VEC2) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
v2.x() = (*_doubleArray)[j];
v2.y() = (*_doubleArray)[j+1];
return true;
}
bool Uniform::getElement( unsigned int index, osg::Vec3d& v3 ) const
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_VEC3) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
v3.x() = (*_doubleArray)[j];
v3.y() = (*_doubleArray)[j+1];
v3.z() = (*_doubleArray)[j+2];
return true;
}
bool Uniform::getElement( unsigned int index, osg::Vec4d& v4 ) const
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_VEC4) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
v4.x() = (*_doubleArray)[j];
v4.y() = (*_doubleArray)[j+1];
v4.z() = (*_doubleArray)[j+2];
v4.w() = (*_doubleArray)[j+3];
return true;
}
bool Uniform::getElement( unsigned int index, osg::Matrix2d& m2 ) const
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_MAT2) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
m2.Matrix2d::base_class::set( &((*_doubleArray)[j]) );
return true;
}
bool Uniform::getElement( unsigned int index, osg::Matrix3d& m3 ) const
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_MAT3) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
m3.Matrix3d::base_class::set( &((*_doubleArray)[j]) );
return true;
}
bool Uniform::getElement( unsigned int index, osg::Matrixd& m4 ) const
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_MAT4, FLOAT_MAT4) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
if (_type == DOUBLE_MAT4)
m4.set( &((*_doubleArray)[j]) );
else // if (_type == FLOAT_MAT4) for backward compatibility only
m4.set( &((*_floatArray)[j]) );
return true;
}
bool Uniform::getElement( unsigned int index, osg::Matrix2x3d& m2x3 ) const
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_MAT2x3) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
m2x3.Matrix2x3d::base_class::set( &((*_doubleArray)[j]) );
return true;
}
bool Uniform::getElement( unsigned int index, osg::Matrix2x4d& m2x4 ) const
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_MAT2x4) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
m2x4.Matrix2x4d::base_class::set( &((*_doubleArray)[j]) );
return true;
}
bool Uniform::getElement( unsigned int index, osg::Matrix3x2d& m3x2 ) const
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_MAT3x2) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
m3x2.Matrix3x2d::base_class::set( &((*_doubleArray)[j]) );
return true;
}
bool Uniform::getElement( unsigned int index, osg::Matrix3x4d& m3x4 ) const
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_MAT3x4) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
m3x4.Matrix3x4d::base_class::set( &((*_doubleArray)[j]) );
return true;
}
bool Uniform::getElement( unsigned int index, osg::Matrix4x2d& m4x2 ) const
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_MAT4x2) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
m4x2.Matrix4x2d::base_class::set( &((*_doubleArray)[j]) );
return true;
}
bool Uniform::getElement( unsigned int index, osg::Matrix4x3d& m4x3 ) const
{
if( index>=getNumElements() || !isCompatibleType(DOUBLE_MAT4x3) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
m4x3.Matrix4x3d::base_class::set( &((*_doubleArray)[j]) );
return true;
}
bool Uniform::getElement( unsigned int index, int& i ) const
{
if( index>=getNumElements() || !isCompatibleType(INT) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
i = (*_intArray)[j];
return true;
}
bool Uniform::getElement( unsigned int index, int& i0, int& i1 ) const
{
if( index>=getNumElements() || !isCompatibleType(INT_VEC2) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
i0 = (*_intArray)[j];
i1 = (*_intArray)[j+1];
return true;
}
bool Uniform::getElement( unsigned int index, int& i0, int& i1, int& i2 ) const
{
if( index>=getNumElements() || !isCompatibleType(INT_VEC3) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
i0 = (*_intArray)[j];
i1 = (*_intArray)[j+1];
i2 = (*_intArray)[j+2];
return true;
}
bool Uniform::getElement( unsigned int index, int& i0, int& i1, int& i2, int& i3 ) const
{
if( index>=getNumElements() || !isCompatibleType(INT_VEC4) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
i0 = (*_intArray)[j];
i1 = (*_intArray)[j+1];
i2 = (*_intArray)[j+2];
i3 = (*_intArray)[j+3];
return true;
}
bool Uniform::getElement( unsigned int index, unsigned int& ui ) const
{
if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
ui = (*_uintArray)[j];
return true;
}
bool Uniform::getElement( unsigned int index, unsigned int& ui0, unsigned int& ui1 ) const
{
if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT_VEC2) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
ui0 = (*_uintArray)[j];
ui1 = (*_uintArray)[j+1];
return true;
}
bool Uniform::getElement( unsigned int index, unsigned int& ui0, unsigned int& ui1, unsigned int& ui2 ) const
{
if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT_VEC3) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
ui0 = (*_uintArray)[j];
ui1 = (*_uintArray)[j+1];
ui2 = (*_uintArray)[j+2];
return true;
}
bool Uniform::getElement( unsigned int index, unsigned int& ui0, unsigned int& ui1, unsigned int& ui2, unsigned int& ui3 ) const
{
if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT_VEC4) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
ui0 = (*_uintArray)[j];
ui1 = (*_uintArray)[j+1];
ui2 = (*_uintArray)[j+2];
ui3 = (*_uintArray)[j+3];
return true;
}
bool Uniform::getElement( unsigned int index, bool& b ) const
{
if( index>=getNumElements() || !isCompatibleType(BOOL) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
b = ((*_intArray)[j] != 0);
return true;
}
bool Uniform::getElement( unsigned int index, bool& b0, bool& b1 ) const
{
if( index>=getNumElements() || !isCompatibleType(BOOL_VEC2) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
b0 = ((*_intArray)[j] != 0);
b1 = ((*_intArray)[j+1] != 0);
return true;
}
bool Uniform::getElement( unsigned int index, bool& b0, bool& b1, bool& b2 ) const
{
if( index>=getNumElements() || !isCompatibleType(BOOL_VEC3) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
b0 = ((*_intArray)[j] != 0);
b1 = ((*_intArray)[j+1] != 0);
b2 = ((*_intArray)[j+2] != 0);
return true;
}
bool Uniform::getElement( unsigned int index, bool& b0, bool& b1, bool& b2, bool& b3 ) const
{
if( index>=getNumElements() || !isCompatibleType(BOOL_VEC4) ) return false;
unsigned int j = index * getTypeNumComponents(getType());
b0 = ((*_intArray)[j] != 0);
b1 = ((*_intArray)[j+1] != 0);
b2 = ((*_intArray)[j+2] != 0);
b3 = ((*_intArray)[j+3] != 0);
return true;
}
unsigned int Uniform::getNameID() const
{
return _nameID;
}
///////////////////////////////////////////////////////////////////////////
void Uniform::apply(const GL2Extensions* ext, GLint location) const
{
// OSG_NOTICE << "uniform at "<<location<<" "<<_name<< std::endl;
GLsizei num = getNumElements();
if( num < 1 ) return;
switch( getGlApiType(getType()) )
{
case FLOAT:
if( _floatArray.valid() ) ext->glUniform1fv( location, num, &_floatArray->front() );
break;
case FLOAT_VEC2:
if( _floatArray.valid() ) ext->glUniform2fv( location, num, &_floatArray->front() );
break;
case FLOAT_VEC3:
if( _floatArray.valid() ) ext->glUniform3fv( location, num, &_floatArray->front() );
break;
case FLOAT_VEC4:
if( _floatArray.valid() ) ext->glUniform4fv( location, num, &_floatArray->front() );
break;
case FLOAT_MAT2:
if( _floatArray.valid() ) ext->glUniformMatrix2fv( location, num, GL_FALSE, &_floatArray->front() );
break;
case FLOAT_MAT3:
if( _floatArray.valid() ) ext->glUniformMatrix3fv( location, num, GL_FALSE, &_floatArray->front() );
break;
case FLOAT_MAT4:
if( _floatArray.valid() ) ext->glUniformMatrix4fv( location, num, GL_FALSE, &_floatArray->front() );
break;
case FLOAT_MAT2x3:
if( _floatArray.valid() ) ext->glUniformMatrix2x3fv( location, num, GL_FALSE, &_floatArray->front() );
break;
case FLOAT_MAT2x4:
if( _floatArray.valid() ) ext->glUniformMatrix2x4fv( location, num, GL_FALSE, &_floatArray->front() );
break;
case FLOAT_MAT3x2:
if( _floatArray.valid() ) ext->glUniformMatrix3x2fv( location, num, GL_FALSE, &_floatArray->front() );
break;
case FLOAT_MAT3x4:
if( _floatArray.valid() ) ext->glUniformMatrix3x4fv( location, num, GL_FALSE, &_floatArray->front() );
break;
case FLOAT_MAT4x2:
if( _floatArray.valid() ) ext->glUniformMatrix4x2fv( location, num, GL_FALSE, &_floatArray->front() );
break;
case FLOAT_MAT4x3:
if( _floatArray.valid() ) ext->glUniformMatrix4x3fv( location, num, GL_FALSE, &_floatArray->front() );
break;
case DOUBLE:
if( _doubleArray.valid() ) ext->glUniform1dv( location, num, &_doubleArray->front() );
break;
case DOUBLE_VEC2:
if( _doubleArray.valid() ) ext->glUniform2dv( location, num, &_doubleArray->front() );
break;
case DOUBLE_VEC3:
if( _doubleArray.valid() ) ext->glUniform3dv( location, num, &_doubleArray->front() );
break;
case DOUBLE_VEC4:
if( _doubleArray.valid() ) ext->glUniform4dv( location, num, &_doubleArray->front() );
break;
case DOUBLE_MAT2:
if( _doubleArray.valid() ) ext->glUniformMatrix2dv( location, num, GL_FALSE, &_doubleArray->front() );
break;
case DOUBLE_MAT3:
if( _doubleArray.valid() ) ext->glUniformMatrix3dv( location, num, GL_FALSE, &_doubleArray->front() );
break;
case DOUBLE_MAT4:
if( _doubleArray.valid() ) ext->glUniformMatrix4dv( location, num, GL_FALSE, &_doubleArray->front() );
break;
case DOUBLE_MAT2x3:
if( _doubleArray.valid() ) ext->glUniformMatrix2x3dv( location, num, GL_FALSE, &_doubleArray->front() );
break;
case DOUBLE_MAT2x4:
if( _doubleArray.valid() ) ext->glUniformMatrix2x4dv( location, num, GL_FALSE, &_doubleArray->front() );
break;
case DOUBLE_MAT3x2:
if( _doubleArray.valid() ) ext->glUniformMatrix3x2dv( location, num, GL_FALSE, &_doubleArray->front() );
break;
case DOUBLE_MAT3x4:
if( _doubleArray.valid() ) ext->glUniformMatrix3x4dv( location, num, GL_FALSE, &_doubleArray->front() );
break;
case DOUBLE_MAT4x2:
if( _doubleArray.valid() ) ext->glUniformMatrix4x2dv( location, num, GL_FALSE, &_doubleArray->front() );
break;
case DOUBLE_MAT4x3:
if( _doubleArray.valid() ) ext->glUniformMatrix4x3dv( location, num, GL_FALSE, &_doubleArray->front() );
break;
case INT:
if( _intArray.valid() ) ext->glUniform1iv( location, num, &_intArray->front() );
break;
case INT_VEC2:
if( _intArray.valid() ) ext->glUniform2iv( location, num, &_intArray->front() );
break;
case INT_VEC3:
if( _intArray.valid() ) ext->glUniform3iv( location, num, &_intArray->front() );
break;
case INT_VEC4:
if( _intArray.valid() ) ext->glUniform4iv( location, num, &_intArray->front() );
break;
case UNSIGNED_INT:
if( _uintArray.valid() ) ext->glUniform1uiv( location, num, &_uintArray->front() );
break;
case UNSIGNED_INT_VEC2:
if( _uintArray.valid() ) ext->glUniform2uiv( location, num, &_uintArray->front() );
break;
case UNSIGNED_INT_VEC3:
if( _uintArray.valid() ) ext->glUniform3uiv( location, num, &_uintArray->front() );
break;
case UNSIGNED_INT_VEC4:
if( _uintArray.valid() ) ext->glUniform4uiv( location, num, &_uintArray->front() );
break;
default:
OSG_FATAL << "how got here? " __FILE__ ":" << __LINE__ << std::endl;
break;
}
}
void Uniform::setUpdateCallback(Callback* uc)
{
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_INFO<<"Going to set Uniform parents"<<std::endl;
for(ParentList::iterator itr=_parents.begin();
itr!=_parents.end();
++itr)
{
OSG_INFO<<" setting Uniform parent"<<std::endl;
(*itr)->setNumChildrenRequiringUpdateTraversal((*itr)->getNumChildrenRequiringUpdateTraversal()+delta);
}
}
}
void Uniform::setEventCallback(Callback* ec)
{
OSG_INFO<<"Uniform::Setting Event callbacks"<<std::endl;
if (_eventCallback==ec) return;
int delta = 0;
if (_eventCallback.valid()) --delta;
if (ec) ++delta;
_eventCallback = ec;
if (delta!=0)
{
for(ParentList::iterator itr=_parents.begin();
itr!=_parents.end();
++itr)
{
(*itr)->setNumChildrenRequiringEventTraversal((*itr)->getNumChildrenRequiringEventTraversal()+delta);
}
}
}