/* -*-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 #include #include #include #include #include #include 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& uniform, const CopyOp& copyop) : Object(uniform, copyop), _type(uniform._type), _updateCallback(copyop(uniform._updateCallback.get())), _eventCallback(copyop(uniform._eventCallback.get())) { copyData(uniform); } Uniform::~Uniform() { } void Uniform::addParent(osg::StateSet* object) { OSG_DEBUG_FP<<"Uniform Adding parent"< lock(getRefMutex()); _parents.push_back(object); } void Uniform::removeParent(osg::StateSet* object) { OpenThreads::ScopedPointerLock 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() || _int64Array.valid() || _uint64Array.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; case GL_INT64_ARB: _int64Array = new Int64Array(arrayNumElements); return; case GL_UNSIGNED_INT64_ARB: _uint64Array = new UInt64Array(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; _int64Array = 0; _uint64Array = 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; _int64Array = 0; _uint64Array = 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; _int64Array = 0; _uint64Array = 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; _int64Array = 0; _uint64Array = 0; dirty(); return true; } bool Uniform::setArray( UInt64Array* array ) { if( !array ) return false; // incoming array must match configuration of the Uniform if( getInternalArrayType(getType())!=GL_UNSIGNED_INT64_ARB || getInternalArrayNumElements()!=array->getNumElements() ) { OSG_WARN << "Uniform::setArray : incompatible array" << std::endl; return false; } _uint64Array = array; _floatArray = 0; _doubleArray = 0; _intArray = 0; _uintArray = 0; _int64Array =0; dirty(); return true; } bool Uniform::setArray( Int64Array* array ) { if( !array ) return false; // incoming array must match configuration of the Uniform if( getInternalArrayType(getType())!=GL_UNSIGNED_INT64_ARB || getInternalArrayNumElements()!=array->getNumElements() ) { OSG_WARN << "Uniform::setArray : incompatible array" << std::endl; return false; } _int64Array = array; _floatArray = 0; _doubleArray = 0; _intArray = 0; _uintArray = 0; _uint64Array =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() ); } else if( _uint64Array.valid() ) { if( ! rhs._uint64Array ) return 1; if( _uint64Array == rhs._uint64Array ) return 0; return memcmp( _uint64Array->getDataPointer(), rhs._uint64Array->getDataPointer(), _uint64Array->getTotalDataSize() ); } else if( _int64Array.valid() ) { if( ! rhs._int64Array ) return 1; if( _int64Array == rhs._int64Array ) return 0; return memcmp( _int64Array->getDataPointer(), rhs._int64Array->getDataPointer(), _int64Array->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; if( _int64Array.valid() && rhs._int64Array.valid() ) *_int64Array = *rhs._int64Array; if( _uint64Array.valid() && rhs._uint64Array.valid() ) *_uint64Array = *rhs._uint64Array; 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 INT64: return "int64_t"; case UNSIGNED_INT64: return "uint64_t"; 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 "usampler1D"; case UNSIGNED_INT_SAMPLER_2D: return "usampler2D"; case UNSIGNED_INT_SAMPLER_3D: return "usampler3D"; case UNSIGNED_INT_SAMPLER_CUBE: return "usamplerCube"; case UNSIGNED_INT_SAMPLER_1D_ARRAY: return "usampler1DArray"; case UNSIGNED_INT_SAMPLER_2D_ARRAY: return "usampler2DArray"; case UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY: return "usamplerCubeMapArray"; case UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: return "usampler2DMS"; case UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: return "usampler2DMSArray"; case UNSIGNED_INT_SAMPLER_BUFFER: return "usamplerBuffer"; case UNSIGNED_INT_SAMPLER_2D_RECT: return "usampler2DRect"; 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 UNSIGNED_INT64: case INT64: 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 == "uint64_t" ) return UNSIGNED_INT64; if( tname == "int64_t" ) return INT64; 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; case UNSIGNED_INT64: return UNSIGNED_INT64; case INT64: return INT64; 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; case UNSIGNED_INT64: return GL_UNSIGNED_INT64_ARB; case INT64: return GL_INT64_ARB; default: return 0; } } unsigned int Uniform::getNameID(const std::string& name) { typedef std::map UniformNameIDMap; static OpenThreads::Mutex s_mutex_uniformNameIDMap; static UniformNameIDMap s_uniformNameIDMap; OpenThreads::ScopedLock 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 Uniform::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 ); } Uniform::Uniform( const char* name, unsigned long long ull) : _type(UNSIGNED_INT64), _numElements(1), _modifiedCount(0) { setName(name); allocateDataArray(); set( ull ); } Uniform::Uniform( const char* name, long long ll) : _type(INT64), _numElements(1), _modifiedCount(0) { setName(name); allocateDataArray(); set( ll ); } //////////////////////////////////////////////////////////////////////// // Value assignment for single-element (ie: non-array) uniforms. // (For backwards compatibility, 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; } bool Uniform::set( unsigned long long ull ) { if( getNumElements() == 0 ) setNumElements(1); return isScalar() ? setElement(0,ull) : false; } bool Uniform::set( long long ll ) { if( getNumElements() == 0 ) setNumElements(1); return isScalar() ? setElement(0,ll) : 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; } bool Uniform::get( unsigned long long& ull ) const { return isScalar() ? getElement(0,ull) : false; } bool Uniform::get( long long& ll ) const { return isScalar() ? getElement(0,ll) : 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(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; } bool Uniform::setElement( unsigned int index, unsigned long long ull ) { if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT64) ) return false; unsigned int j = index * getTypeNumComponents(getType()); (*_uint64Array)[j] = ull; dirty(); return true; } bool Uniform::setElement( unsigned int index, long long ll ) { if( index>=getNumElements() || !isCompatibleType(INT64) ) return false; unsigned int j = index * getTypeNumComponents(getType()); (*_int64Array)[j] = ll; 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, unsigned long long& ull ) const { if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT64) ) return false; unsigned int j = index * getTypeNumComponents(getType()); ull = ((*_uint64Array)[j] != 0); return true; } bool Uniform::getElement( unsigned int index, long long& ll ) const { if( index>=getNumElements() || !isCompatibleType(INT64) ) return false; unsigned int j = index * getTypeNumComponents(getType()); ll = ((*_int64Array)[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 GLExtensions* ext, GLint location) const { // OSG_NOTICE << "uniform at "<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; case UNSIGNED_INT64: if( _uint64Array.valid() ){ if (ext->glUniform1ui64v) ext->glUniform1ui64v( location, num, &_uint64Array->front() ); else OSG_WARN << "how got here? " __FILE__ ":" << __LINE__ << std::endl; } break; case INT64: if( _int64Array.valid() ) ext->glUniform1i64v( location, num, &_int64Array->front() ); break; default: OSG_FATAL << "how got here? " __FILE__ ":" << __LINE__ << std::endl; break; } } void Uniform::setUpdateCallback(UniformCallback* uc) { OSG_INFO<<"Uniform::Setting Update callbacks"<setNumChildrenRequiringUpdateTraversal((*itr)->getNumChildrenRequiringUpdateTraversal()+delta); } } } void Uniform::setEventCallback(UniformCallback* ec) { OSG_INFO<<"Uniform::Setting Event callbacks"<setNumChildrenRequiringEventTraversal((*itr)->getNumChildrenRequiringEventTraversal()+delta); } } }