1543 lines
44 KiB
C++
1543 lines
44 KiB
C++
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
|
* Copyright (C) 2003-2005 3Dlabs Inc. Ltd.
|
|
* Copyright (C) 2008 Zebra Imaging
|
|
*
|
|
* 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;
|
|
|
|
_parents.push_back(object);
|
|
}
|
|
|
|
void Uniform::removeParent(osg::StateSet* object)
|
|
{
|
|
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() || _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);
|
|
_intArray = 0;
|
|
_uintArray = 0;
|
|
return;
|
|
|
|
case GL_INT:
|
|
_intArray = new IntArray(arrayNumElements);
|
|
_floatArray = 0;
|
|
_uintArray = 0;
|
|
return;
|
|
|
|
case GL_UNSIGNED_INT:
|
|
_uintArray = new UIntArray(arrayNumElements);
|
|
_floatArray = 0;
|
|
_intArray = 0;
|
|
return;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
_floatArray = 0;
|
|
_intArray = 0;
|
|
_uintArray = 0;
|
|
}
|
|
|
|
bool Uniform::setArray( FloatArray* array )
|
|
{
|
|
if( !array ) return false;
|
|
|
|
// incoming array must match configuration of the Uniform
|
|
if( getInternalArrayType(getType())!=GL_FLOAT || getInternalArrayNumElements()!=array->getNumElements() )
|
|
{
|
|
OSG_WARN << "Uniform::setArray : incompatible array" << std::endl;
|
|
return false;
|
|
}
|
|
|
|
_floatArray = array;
|
|
_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;
|
|
_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;
|
|
_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() );
|
|
}
|
|
|
|
if( _intArray.valid() )
|
|
{
|
|
if( ! rhs._intArray ) return 1;
|
|
if( _intArray == rhs._intArray ) return 0;
|
|
return memcmp( _intArray->getDataPointer(), rhs._intArray->getDataPointer(),
|
|
_intArray->getTotalDataSize() );
|
|
}
|
|
|
|
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._intArray.valid() || rhs._uintArray.valid()) allocateDataArray();
|
|
if( _floatArray.valid() && rhs._floatArray.valid() ) *_floatArray = *rhs._floatArray;
|
|
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;
|
|
}
|
|
|
|
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 INT: return "int";
|
|
case INT_VEC2: return "ivec2";
|
|
case INT_VEC3: return "ivec3";
|
|
case INT_VEC4: return "ivec4";
|
|
case BOOL: return "bool";
|
|
case BOOL_VEC2: return "bvec2";
|
|
case BOOL_VEC3: return "bvec3";
|
|
case BOOL_VEC4: return "bvec4";
|
|
case FLOAT_MAT2: return "mat2";
|
|
case FLOAT_MAT3: return "mat3";
|
|
case FLOAT_MAT4: return "mat4";
|
|
case SAMPLER_1D: return "sampler1D";
|
|
case SAMPLER_2D: return "sampler2D";
|
|
case SAMPLER_1D_ARRAY: return "sampler1DArray";
|
|
case SAMPLER_2D_ARRAY: return "sampler2DArray";
|
|
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_SHADOW: return "sampler1DArrayShadow";
|
|
case SAMPLER_2D_ARRAY_SHADOW: return "sampler2DArrayShadow";
|
|
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 SAMPLER_BUFFER: return "samplerBuffer";
|
|
case SAMPLER_CUBE_SHADOW: return "samplerCubeShadow";
|
|
case UNSIGNED_INT: return "unsigned int";
|
|
case UNSIGNED_INT_VEC2: return "uvec2";
|
|
case UNSIGNED_INT_VEC3: return "uvec3";
|
|
case UNSIGNED_INT_VEC4: return "uvec4";
|
|
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_2D_RECT: return "isampler2DRect";
|
|
case INT_SAMPLER_1D_ARRAY: return "isampler1DArray";
|
|
case INT_SAMPLER_2D_ARRAY: return "isampler2DArray";
|
|
case INT_SAMPLER_BUFFER: return "isamplerBuffer";
|
|
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_2D_RECT: return "usampler2DRect";
|
|
case UNSIGNED_INT_SAMPLER_1D_ARRAY: return "usampler1DArray";
|
|
case UNSIGNED_INT_SAMPLER_2D_ARRAY: return "usampler2DArray";
|
|
case UNSIGNED_INT_SAMPLER_BUFFER: return "usamplerBuffer";
|
|
default: return "UNDEFINED";
|
|
}
|
|
}
|
|
|
|
int Uniform::getTypeNumComponents( Type t )
|
|
{
|
|
switch( t )
|
|
{
|
|
case FLOAT:
|
|
case INT:
|
|
case UNSIGNED_INT:
|
|
case BOOL:
|
|
case SAMPLER_1D:
|
|
case SAMPLER_2D:
|
|
case SAMPLER_1D_ARRAY:
|
|
case SAMPLER_2D_ARRAY:
|
|
case SAMPLER_3D:
|
|
case SAMPLER_CUBE:
|
|
case SAMPLER_1D_SHADOW:
|
|
case SAMPLER_2D_SHADOW:
|
|
case SAMPLER_1D_ARRAY_SHADOW:
|
|
case SAMPLER_2D_ARRAY_SHADOW:
|
|
case SAMPLER_BUFFER:
|
|
case SAMPLER_CUBE_SHADOW:
|
|
case INT_SAMPLER_1D:
|
|
case INT_SAMPLER_2D:
|
|
case INT_SAMPLER_3D:
|
|
case INT_SAMPLER_CUBE:
|
|
case INT_SAMPLER_2D_RECT:
|
|
case INT_SAMPLER_1D_ARRAY:
|
|
case INT_SAMPLER_2D_ARRAY:
|
|
case INT_SAMPLER_BUFFER:
|
|
case UNSIGNED_INT_SAMPLER_1D:
|
|
case UNSIGNED_INT_SAMPLER_2D:
|
|
case UNSIGNED_INT_SAMPLER_3D:
|
|
case UNSIGNED_INT_SAMPLER_CUBE:
|
|
case UNSIGNED_INT_SAMPLER_2D_RECT:
|
|
case UNSIGNED_INT_SAMPLER_1D_ARRAY:
|
|
case UNSIGNED_INT_SAMPLER_2D_ARRAY:
|
|
case UNSIGNED_INT_SAMPLER_BUFFER:
|
|
return 1;
|
|
|
|
case FLOAT_VEC2:
|
|
case INT_VEC2:
|
|
case BOOL_VEC2:
|
|
case UNSIGNED_INT_VEC2:
|
|
return 2;
|
|
|
|
case FLOAT_VEC3:
|
|
case INT_VEC3:
|
|
case BOOL_VEC3:
|
|
case UNSIGNED_INT_VEC3:
|
|
return 3;
|
|
|
|
case FLOAT_VEC4:
|
|
case FLOAT_MAT2:
|
|
case INT_VEC4:
|
|
case BOOL_VEC4:
|
|
case UNSIGNED_INT_VEC4:
|
|
return 4;
|
|
|
|
case FLOAT_MAT2x3:
|
|
case FLOAT_MAT3x2:
|
|
return 6;
|
|
|
|
case FLOAT_MAT2x4:
|
|
case FLOAT_MAT4x2:
|
|
return 8;
|
|
|
|
case FLOAT_MAT3:
|
|
return 9;
|
|
|
|
case FLOAT_MAT3x4:
|
|
case FLOAT_MAT4x3:
|
|
return 12;
|
|
|
|
case FLOAT_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 == "int" ) return INT;
|
|
if( tname == "ivec2" ) return INT_VEC2;
|
|
if( tname == "ivec3" ) return INT_VEC3;
|
|
if( tname == "ivec4" ) return INT_VEC4;
|
|
if( tname == "bool" ) return BOOL;
|
|
if( tname == "bvec2" ) return BOOL_VEC2;
|
|
if( tname == "bvec3" ) return BOOL_VEC3;
|
|
if( tname == "bvec4" ) return BOOL_VEC4;
|
|
if( tname == "mat2" || tname == "mat2x2" ) return FLOAT_MAT2;
|
|
if( tname == "mat3" || tname == "mat3x3" ) return FLOAT_MAT3;
|
|
if( tname == "mat4" || tname == "mat4x4" ) return FLOAT_MAT4;
|
|
if( tname == "sampler1D" ) return SAMPLER_1D;
|
|
if( tname == "sampler2D" ) return SAMPLER_2D;
|
|
if( tname == "sampler1DArray" ) return SAMPLER_1D_ARRAY;
|
|
if( tname == "sampler2DArray" ) return SAMPLER_2D_ARRAY;
|
|
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 == "sampler1DArrayShadow" ) return SAMPLER_1D_ARRAY_SHADOW;
|
|
if( tname == "sampler2DArrayShadow" ) return SAMPLER_2D_ARRAY_SHADOW;
|
|
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 == "samplerBuffer" ) return SAMPLER_BUFFER;
|
|
if( tname == "samplerCubeShadow" ) return SAMPLER_CUBE_SHADOW;
|
|
if( tname == "unsigned int" ) 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 == "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 == "isampler2DRect" ) return INT_SAMPLER_2D_RECT;
|
|
if( tname == "isampler1DArray" ) return INT_SAMPLER_1D_ARRAY;
|
|
if( tname == "isampler2DArray" ) return INT_SAMPLER_2D_ARRAY;
|
|
if( tname == "isamplerBuffer" ) return INT_SAMPLER_BUFFER;
|
|
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 == "usampler2DRect" ) return UNSIGNED_INT_SAMPLER_2D_RECT;
|
|
if( tname == "usampler1DArray" ) return UNSIGNED_INT_SAMPLER_1D_ARRAY;
|
|
if( tname == "usampler2DArray" ) return UNSIGNED_INT_SAMPLER_2D_ARRAY;
|
|
if( tname == "usamplerBuffer" ) return UNSIGNED_INT_SAMPLER_BUFFER;
|
|
|
|
return UNDEFINED;
|
|
}
|
|
|
|
Uniform::Type Uniform::getGlApiType( Type t )
|
|
{
|
|
switch( t )
|
|
{
|
|
case BOOL:
|
|
case SAMPLER_1D:
|
|
case SAMPLER_2D:
|
|
case SAMPLER_1D_ARRAY:
|
|
case SAMPLER_2D_ARRAY:
|
|
case SAMPLER_3D:
|
|
case SAMPLER_CUBE:
|
|
case SAMPLER_1D_SHADOW:
|
|
case SAMPLER_2D_SHADOW:
|
|
case SAMPLER_1D_ARRAY_SHADOW:
|
|
case SAMPLER_2D_ARRAY_SHADOW:
|
|
case SAMPLER_BUFFER:
|
|
case SAMPLER_CUBE_SHADOW:
|
|
case INT_SAMPLER_1D:
|
|
case INT_SAMPLER_2D:
|
|
case INT_SAMPLER_3D:
|
|
case INT_SAMPLER_CUBE:
|
|
case INT_SAMPLER_2D_RECT:
|
|
case INT_SAMPLER_1D_ARRAY:
|
|
case INT_SAMPLER_2D_ARRAY:
|
|
case INT_SAMPLER_BUFFER:
|
|
case UNSIGNED_INT_SAMPLER_1D:
|
|
case UNSIGNED_INT_SAMPLER_2D:
|
|
case UNSIGNED_INT_SAMPLER_3D:
|
|
case UNSIGNED_INT_SAMPLER_CUBE:
|
|
case UNSIGNED_INT_SAMPLER_2D_RECT:
|
|
case UNSIGNED_INT_SAMPLER_1D_ARRAY:
|
|
case UNSIGNED_INT_SAMPLER_2D_ARRAY:
|
|
case UNSIGNED_INT_SAMPLER_BUFFER:
|
|
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 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_1D_ARRAY:
|
|
case SAMPLER_2D_ARRAY:
|
|
case SAMPLER_3D:
|
|
case SAMPLER_CUBE:
|
|
case SAMPLER_1D_SHADOW:
|
|
case SAMPLER_2D_SHADOW:
|
|
case SAMPLER_1D_ARRAY_SHADOW:
|
|
case SAMPLER_2D_ARRAY_SHADOW:
|
|
case SAMPLER_BUFFER:
|
|
case SAMPLER_CUBE_SHADOW:
|
|
case INT_SAMPLER_1D:
|
|
case INT_SAMPLER_2D:
|
|
case INT_SAMPLER_3D:
|
|
case INT_SAMPLER_CUBE:
|
|
case INT_SAMPLER_2D_RECT:
|
|
case INT_SAMPLER_1D_ARRAY:
|
|
case INT_SAMPLER_2D_ARRAY:
|
|
case INT_SAMPLER_BUFFER:
|
|
case UNSIGNED_INT_SAMPLER_1D:
|
|
case UNSIGNED_INT_SAMPLER_2D:
|
|
case UNSIGNED_INT_SAMPLER_3D:
|
|
case UNSIGNED_INT_SAMPLER_CUBE:
|
|
case UNSIGNED_INT_SAMPLER_2D_RECT:
|
|
case UNSIGNED_INT_SAMPLER_1D_ARRAY:
|
|
case UNSIGNED_INT_SAMPLER_2D_ARRAY:
|
|
case UNSIGNED_INT_SAMPLER_BUFFER:
|
|
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;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// 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::Matrixd& m4 ) :
|
|
_type(FLOAT_MAT4), _numElements(1), _modifiedCount(0)
|
|
{
|
|
setName(name);
|
|
allocateDataArray();
|
|
set( m4 );
|
|
}
|
|
|
|
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 i ) :
|
|
_type(UNSIGNED_INT), _numElements(1), _modifiedCount(0)
|
|
{
|
|
setName(name);
|
|
allocateDataArray();
|
|
set( i );
|
|
}
|
|
|
|
Uniform::Uniform( const char* name, unsigned int i0, unsigned int i1 ) :
|
|
_type(UNSIGNED_INT_VEC2), _numElements(1), _modifiedCount(0)
|
|
{
|
|
setName(name);
|
|
allocateDataArray();
|
|
set( i0, i1 );
|
|
}
|
|
|
|
Uniform::Uniform( const char* name, unsigned int i0, unsigned int i1, unsigned int i2 ) :
|
|
_type(UNSIGNED_INT_VEC3), _numElements(1), _modifiedCount(0)
|
|
{
|
|
setName(name);
|
|
allocateDataArray();
|
|
set( i0, i1, i2 );
|
|
}
|
|
|
|
Uniform::Uniform( const char* name, unsigned int i0, unsigned int i1, unsigned int i2, unsigned int i3 ) :
|
|
_type(UNSIGNED_INT_VEC4), _numElements(1), _modifiedCount(0)
|
|
{
|
|
setName(name);
|
|
allocateDataArray();
|
|
set( i0, i1, i2, i3 );
|
|
}
|
|
|
|
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::Matrixd& m4 )
|
|
{
|
|
if( getNumElements() == 0 ) setNumElements(1);
|
|
return isScalar() ? setElement(0,m4) : 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 i )
|
|
{
|
|
if( getNumElements() == 0 ) setNumElements(1);
|
|
return isScalar() ? setElement(0,i) : false;
|
|
}
|
|
|
|
bool Uniform::set( unsigned int i0, unsigned int i1 )
|
|
{
|
|
if( getNumElements() == 0 ) setNumElements(1);
|
|
return isScalar() ? setElement(0,i0,i1) : false;
|
|
}
|
|
|
|
bool Uniform::set( unsigned int i0, unsigned int i1, unsigned int i2 )
|
|
{
|
|
if( getNumElements() == 0 ) setNumElements(1);
|
|
return isScalar() ? setElement(0,i0,i1,i2) : false;
|
|
}
|
|
|
|
bool Uniform::set( unsigned int i0, unsigned int i1, unsigned int i2, unsigned int i3 )
|
|
{
|
|
if( getNumElements() == 0 ) setNumElements(1);
|
|
return isScalar() ? setElement(0,i0,i1,i2,i3) : 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::Matrixd& m4 ) const
|
|
{
|
|
return isScalar() ? getElement(0,m4) : 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& i ) const
|
|
{
|
|
return isScalar() ? getElement(0,i) : false;
|
|
}
|
|
|
|
bool Uniform::get( unsigned int& i0, unsigned int& i1 ) const
|
|
{
|
|
return isScalar() ? getElement(0,i0,i1) : false;
|
|
}
|
|
|
|
bool Uniform::get( unsigned int& i0, unsigned int& i1, unsigned int& i2 ) const
|
|
{
|
|
return isScalar() ? getElement(0,i0,i1,i2) : false;
|
|
}
|
|
|
|
bool Uniform::get( unsigned int& i0, unsigned int& i1, unsigned int& i2, unsigned int& i3 ) const
|
|
{
|
|
return isScalar() ? getElement(0,i0,i1,i2,i3) : 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::Matrixd& m4 )
|
|
{
|
|
if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT4) ) return false;
|
|
unsigned int j = index * getTypeNumComponents(getType());
|
|
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, 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 i )
|
|
{
|
|
if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT) ) return false;
|
|
unsigned int j = index * getTypeNumComponents(getType());
|
|
(*_uintArray)[j] = i;
|
|
dirty();
|
|
return true;
|
|
}
|
|
|
|
bool Uniform::setElement( unsigned int index, unsigned int i0, unsigned int i1 )
|
|
{
|
|
if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT_VEC2) ) return false;
|
|
unsigned int j = index * getTypeNumComponents(getType());
|
|
(*_uintArray)[j] = i0;
|
|
(*_uintArray)[j+1] = i1;
|
|
dirty();
|
|
return true;
|
|
}
|
|
|
|
bool Uniform::setElement( unsigned int index, unsigned int i0, unsigned int i1, unsigned int i2 )
|
|
{
|
|
if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT_VEC3) ) return false;
|
|
unsigned int j = index * getTypeNumComponents(getType());
|
|
(*_uintArray)[j] = i0;
|
|
(*_uintArray)[j+1] = i1;
|
|
(*_uintArray)[j+2] = i2;
|
|
dirty();
|
|
return true;
|
|
}
|
|
|
|
bool Uniform::setElement( unsigned int index, unsigned int i0, unsigned int i1, unsigned int i2, unsigned int i3 )
|
|
{
|
|
if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT_VEC4) ) return false;
|
|
unsigned int j = index * getTypeNumComponents(getType());
|
|
(*_uintArray)[j] = i0;
|
|
(*_uintArray)[j+1] = i1;
|
|
(*_uintArray)[j+2] = i2;
|
|
(*_uintArray)[j+3] = i3;
|
|
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.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.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::Matrixd& 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, 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& i ) const
|
|
{
|
|
if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT) ) return false;
|
|
unsigned int j = index * getTypeNumComponents(getType());
|
|
i = (*_uintArray)[j];
|
|
return true;
|
|
}
|
|
|
|
bool Uniform::getElement( unsigned int index, unsigned int& i0, unsigned int& i1 ) const
|
|
{
|
|
if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT_VEC2) ) return false;
|
|
unsigned int j = index * getTypeNumComponents(getType());
|
|
i0 = (*_uintArray)[j];
|
|
i1 = (*_uintArray)[j+1];
|
|
return true;
|
|
}
|
|
|
|
bool Uniform::getElement( unsigned int index, unsigned int& i0, unsigned int& i1, unsigned int& i2 ) const
|
|
{
|
|
if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT_VEC3) ) return false;
|
|
unsigned int j = index * getTypeNumComponents(getType());
|
|
i0 = (*_uintArray)[j];
|
|
i1 = (*_uintArray)[j+1];
|
|
i2 = (*_uintArray)[j+2];
|
|
return true;
|
|
}
|
|
|
|
bool Uniform::getElement( unsigned int index, unsigned int& i0, unsigned int& i1, unsigned int& i2, unsigned int& i3 ) const
|
|
{
|
|
if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT_VEC4) ) return false;
|
|
unsigned int j = index * getTypeNumComponents(getType());
|
|
i0 = (*_uintArray)[j];
|
|
i1 = (*_uintArray)[j+1];
|
|
i2 = (*_uintArray)[j+2];
|
|
i3 = (*_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 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);
|
|
}
|
|
}
|
|
}
|
|
|