root/OpenSceneGraph/trunk/src/osg/Uniform.cpp @ 13041

Revision 13041, 44.0 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 * Copyright (C) 2003-2005 3Dlabs Inc. Ltd.
3 * Copyright (C) 2008 Zebra Imaging
4 *
5 * This application is open source and may be redistributed and/or modified
6 * freely and without restriction, both in commercial and non commercial
7 * applications, as long as this copyright notice is maintained.
8 *
9 * This application is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12*/
13
14/* file:   src/osg/Uniform.cpp
15 * author: Mike Weiblen 2008-01-02
16*/
17#include <string.h>
18
19#include <osg/Notify>
20#include <osg/Uniform>
21#include <osg/Program>
22#include <osg/StateSet>
23
24#include <limits.h>
25#include <algorithm>
26
27using namespace osg;
28
29///////////////////////////////////////////////////////////////////////////
30// osg::Uniform
31///////////////////////////////////////////////////////////////////////////
32
33Uniform::Uniform() :
34    _type(UNDEFINED), _numElements(0), _nameID(UINT_MAX), _modifiedCount(0)
35{
36}
37
38
39Uniform::Uniform( Type type, const std::string& name, int numElements ) :
40    _type(type), _numElements(0), _nameID(UINT_MAX), _modifiedCount(0)
41{
42    setName(name);
43    setNumElements(numElements);
44    allocateDataArray();
45}
46
47Uniform::Uniform( const Uniform& rhs, const CopyOp& copyop ) :
48    Object(rhs,copyop), _type(rhs._type)
49{
50    copyData( rhs );
51}
52
53Uniform::~Uniform()
54{
55}
56
57void Uniform::addParent(osg::StateSet* object)
58{
59    OSG_DEBUG_FP<<"Uniform Adding parent"<<std::endl;
60
61    _parents.push_back(object);
62}
63
64void Uniform::removeParent(osg::StateSet* object)
65{
66    ParentList::iterator pitr = std::find(_parents.begin(),_parents.end(),object);
67    if (pitr!=_parents.end()) _parents.erase(pitr);
68}
69
70bool Uniform::setType( Type t )
71{
72    if (_type==t) return true;
73
74    if( _type != UNDEFINED )
75    {
76        OSG_WARN << "cannot change Uniform type" << std::endl;
77        return false;
78    }
79    _type = t;
80    allocateDataArray();
81    return true;
82}
83
84void Uniform::setName( const std::string& name )
85{
86    if( _name != "" )
87    {
88        OSG_WARN << "cannot change Uniform name" << std::endl;
89        return;
90    }
91    Object::setName(name);
92    _nameID = getNameID(_name);
93}
94
95void Uniform::setNumElements( unsigned int numElements )
96{
97    if( numElements < 1 )
98    {
99        OSG_WARN << "Uniform numElements < 1 is invalid" << std::endl;
100        return;
101    }
102
103    if (numElements == _numElements) return;
104
105    if( _numElements>0 )
106    {
107        OSG_WARN << "Warning: Uniform::setNumElements() cannot change Uniform numElements, size already fixed." << std::endl;
108        return;
109    }
110
111    _numElements = numElements;
112    allocateDataArray();
113}
114
115void Uniform::allocateDataArray()
116{
117    // if one array is already allocated, the job is done.
118    if( _floatArray.valid() || _intArray.valid() || _uintArray.valid() ) return;
119
120    // array cannot be created until _type and _numElements are specified
121    int arrayNumElements = getInternalArrayNumElements();
122    if( arrayNumElements )
123    {
124        switch( getInternalArrayType(getType()) )
125        {
126            case GL_FLOAT:
127                _floatArray = new FloatArray(arrayNumElements);
128                _intArray = 0;
129                _uintArray = 0;
130                return;
131
132            case GL_INT:
133                _intArray = new IntArray(arrayNumElements);
134                _floatArray = 0;
135                _uintArray = 0;
136                return;
137
138            case GL_UNSIGNED_INT:
139                _uintArray = new UIntArray(arrayNumElements);
140                _floatArray = 0;
141                _intArray = 0;
142                return;
143
144            default:
145                break;
146        }
147    }
148    _floatArray = 0;
149    _intArray = 0;
150    _uintArray = 0;
151}
152
153bool Uniform::setArray( FloatArray* array )
154{
155    if( !array ) return false;
156
157    // incoming array must match configuration of the Uniform
158    if( getInternalArrayType(getType())!=GL_FLOAT || getInternalArrayNumElements()!=array->getNumElements() )
159    {
160        OSG_WARN << "Uniform::setArray : incompatible array" << std::endl;
161        return false;
162    }
163
164    _floatArray = array;
165    _intArray = 0;
166    _uintArray = 0;
167    dirty();
168    return true;
169}
170
171bool Uniform::setArray( IntArray* array )
172{
173    if( !array ) return false;
174
175    // incoming array must match configuration of the Uniform
176    if( getInternalArrayType(getType())!=GL_INT || getInternalArrayNumElements()!=array->getNumElements() )
177    {
178        OSG_WARN << "Uniform::setArray : incompatible array" << std::endl;
179        return false;
180    }
181
182    _intArray = array;
183    _floatArray = 0;
184    _uintArray = 0;
185    dirty();
186    return true;
187}
188
189bool Uniform::setArray( UIntArray* array )
190{
191    if( !array ) return false;
192
193    // incoming array must match configuration of the Uniform
194    if( getInternalArrayType(getType())!=GL_UNSIGNED_INT || getInternalArrayNumElements()!=array->getNumElements() )
195    {
196        OSG_WARN << "Uniform::setArray : incompatible array" << std::endl;
197        return false;
198    }
199
200    _uintArray = array;
201    _floatArray = 0;
202    _intArray = 0;
203    dirty();
204    return true;
205}
206
207///////////////////////////////////////////////////////////////////////////
208
209int Uniform::compare(const Uniform& rhs) const
210{
211    if( this == &rhs ) return 0;
212
213    if( _type < rhs._type ) return -1;
214    if( rhs._type < _type ) return 1;
215
216    if( _numElements < rhs._numElements ) return -1;
217    if( rhs._numElements < _numElements ) return 1;
218
219    if( _name < rhs._name ) return -1;
220    if( rhs._name < _name ) return 1;
221
222    return compareData( rhs );
223}
224
225int Uniform::compareData(const Uniform& rhs) const
226{
227    // caller must ensure that _type==rhs._type
228
229    if( _floatArray.valid() )
230    {
231        if( ! rhs._floatArray ) return 1;
232        if( _floatArray == rhs._floatArray ) return 0;
233        return memcmp( _floatArray->getDataPointer(), rhs._floatArray->getDataPointer(),
234            _floatArray->getTotalDataSize() );
235    }
236
237    if( _intArray.valid() )
238    {
239        if( ! rhs._intArray ) return 1;
240        if( _intArray == rhs._intArray ) return 0;
241        return memcmp( _intArray->getDataPointer(), rhs._intArray->getDataPointer(),
242            _intArray->getTotalDataSize() );
243    }
244
245    if( _uintArray.valid() )
246    {
247        if( ! rhs._uintArray ) return 1;
248        if( _uintArray == rhs._uintArray ) return 0;
249        return memcmp( _uintArray->getDataPointer(), rhs._uintArray->getDataPointer(),
250            _uintArray->getTotalDataSize() );
251    }
252
253    return -1;  // how got here?
254}
255
256void Uniform::copyData(const Uniform& rhs)
257{
258    // caller must ensure that _type==rhs._type
259    _numElements = rhs._numElements;
260    _nameID = rhs._nameID;
261    if (rhs._floatArray.valid() || rhs._intArray.valid() || rhs._uintArray.valid()) allocateDataArray();
262    if( _floatArray.valid() && rhs._floatArray.valid() ) *_floatArray = *rhs._floatArray;
263    if( _intArray.valid() && rhs._intArray.valid() )     *_intArray = *rhs._intArray;
264    if( _uintArray.valid() && rhs._uintArray.valid() )     *_uintArray = *rhs._uintArray;
265    dirty();
266}
267
268bool Uniform::isCompatibleType( Type t ) const
269{
270    if( (t==UNDEFINED) || (getType()==UNDEFINED) ) return false;
271    if( t == getType() ) return true;
272    if( getGlApiType(t) == getGlApiType(getType()) ) return true;
273
274    OSG_WARN << "Cannot assign between Uniform types " << getTypename(t)
275             << " and " << getTypename(getType()) << std::endl;
276    return false;
277}
278
279unsigned int Uniform::getInternalArrayNumElements() const
280{
281    if( getNumElements()<1 || getType()==UNDEFINED ) return 0;
282    return getNumElements() * getTypeNumComponents(getType());
283}
284
285
286///////////////////////////////////////////////////////////////////////////
287// static methods
288
289const char* Uniform::getTypename( Type t )
290{
291    switch( t )
292    {
293    case FLOAT:             return "float";
294    case FLOAT_VEC2:        return "vec2";
295    case FLOAT_VEC3:        return "vec3";
296    case FLOAT_VEC4:        return "vec4";
297    case INT:               return "int";
298    case INT_VEC2:          return "ivec2";
299    case INT_VEC3:          return "ivec3";
300    case INT_VEC4:          return "ivec4";
301    case BOOL:              return "bool";
302    case BOOL_VEC2:         return "bvec2";
303    case BOOL_VEC3:         return "bvec3";
304    case BOOL_VEC4:         return "bvec4";
305    case FLOAT_MAT2:        return "mat2";
306    case FLOAT_MAT3:        return "mat3";
307    case FLOAT_MAT4:        return "mat4";
308    case SAMPLER_1D:        return "sampler1D";
309    case SAMPLER_2D:        return "sampler2D";
310    case SAMPLER_1D_ARRAYreturn "sampler1DArray";
311    case SAMPLER_2D_ARRAYreturn "sampler2DArray";
312    case SAMPLER_3D:        return "sampler3D";
313    case SAMPLER_CUBE:      return "samplerCube";
314    case SAMPLER_1D_SHADOW: return "sampler1DShadow";
315    case SAMPLER_2D_SHADOW: return "sampler2DShadow";
316    case SAMPLER_1D_ARRAY_SHADOW: return "sampler1DArrayShadow";
317    case SAMPLER_2D_ARRAY_SHADOW: return "sampler2DArrayShadow";
318    case FLOAT_MAT2x3return "mat2x3";
319    case FLOAT_MAT2x4return "mat2x4";
320    case FLOAT_MAT3x2return "mat3x2";
321    case FLOAT_MAT3x4return "mat3x4";
322    case FLOAT_MAT4x2return "mat4x2";
323    case FLOAT_MAT4x3return "mat4x3";
324    case SAMPLER_BUFFER:       return "samplerBuffer";
325    case SAMPLER_CUBE_SHADOWreturn "samplerCubeShadow";
326    case UNSIGNED_INT:         return "unsigned int";
327    case UNSIGNED_INT_VEC2:    return "uvec2";
328    case UNSIGNED_INT_VEC3:    return "uvec3";
329    case UNSIGNED_INT_VEC4:    return "uvec4";
330    case INT_SAMPLER_1D:       return "isampler1D";
331    case INT_SAMPLER_2D:       return "isampler2D";
332    case INT_SAMPLER_3D:       return "isampler3D";
333    case INT_SAMPLER_CUBE:     return "isamplerCube";
334    case INT_SAMPLER_2D_RECTreturn "isampler2DRect";
335    case INT_SAMPLER_1D_ARRAY: return "isampler1DArray";
336    case INT_SAMPLER_2D_ARRAY: return "isampler2DArray";
337    case INT_SAMPLER_BUFFER:   return "isamplerBuffer";
338    case UNSIGNED_INT_SAMPLER_1D:       return "usampler1D";
339    case UNSIGNED_INT_SAMPLER_2D:       return "usampler2D";
340    case UNSIGNED_INT_SAMPLER_3D:       return "usampler3D";
341    case UNSIGNED_INT_SAMPLER_CUBE:     return "usamplerCube";
342    case UNSIGNED_INT_SAMPLER_2D_RECTreturn "usampler2DRect";
343    case UNSIGNED_INT_SAMPLER_1D_ARRAY: return "usampler1DArray";
344    case UNSIGNED_INT_SAMPLER_2D_ARRAY: return "usampler2DArray";
345    case UNSIGNED_INT_SAMPLER_BUFFER:   return "usamplerBuffer";
346    default: return "UNDEFINED";
347    }
348}
349
350int Uniform::getTypeNumComponents( Type t )
351{
352    switch( t )
353    {
354    case FLOAT:
355    case INT:
356    case UNSIGNED_INT:
357    case BOOL:
358    case SAMPLER_1D:
359    case SAMPLER_2D:
360    case SAMPLER_1D_ARRAY:
361    case SAMPLER_2D_ARRAY:
362    case SAMPLER_3D:
363    case SAMPLER_CUBE:
364    case SAMPLER_1D_SHADOW:
365    case SAMPLER_2D_SHADOW:
366    case SAMPLER_1D_ARRAY_SHADOW:
367    case SAMPLER_2D_ARRAY_SHADOW:
368    case SAMPLER_BUFFER:
369    case SAMPLER_CUBE_SHADOW:
370    case INT_SAMPLER_1D:
371    case INT_SAMPLER_2D:
372    case INT_SAMPLER_3D:
373    case INT_SAMPLER_CUBE:
374    case INT_SAMPLER_2D_RECT:
375    case INT_SAMPLER_1D_ARRAY:
376    case INT_SAMPLER_2D_ARRAY:
377    case INT_SAMPLER_BUFFER:
378    case UNSIGNED_INT_SAMPLER_1D:
379    case UNSIGNED_INT_SAMPLER_2D:
380    case UNSIGNED_INT_SAMPLER_3D:
381    case UNSIGNED_INT_SAMPLER_CUBE:
382    case UNSIGNED_INT_SAMPLER_2D_RECT:
383    case UNSIGNED_INT_SAMPLER_1D_ARRAY:
384    case UNSIGNED_INT_SAMPLER_2D_ARRAY:
385    case UNSIGNED_INT_SAMPLER_BUFFER:
386        return 1;
387
388    case FLOAT_VEC2:
389    case INT_VEC2:
390    case BOOL_VEC2:
391    case UNSIGNED_INT_VEC2:
392        return 2;
393
394    case FLOAT_VEC3:
395    case INT_VEC3:
396    case BOOL_VEC3:
397    case UNSIGNED_INT_VEC3:
398        return 3;
399
400    case FLOAT_VEC4:
401    case FLOAT_MAT2:
402    case INT_VEC4:
403    case BOOL_VEC4:
404    case UNSIGNED_INT_VEC4:
405        return 4;
406
407    case FLOAT_MAT2x3:
408    case FLOAT_MAT3x2:
409        return 6;
410
411    case FLOAT_MAT2x4:
412    case FLOAT_MAT4x2:
413        return 8;
414
415    case FLOAT_MAT3:
416        return 9;
417
418    case FLOAT_MAT3x4:
419    case FLOAT_MAT4x3:
420        return 12;
421
422    case FLOAT_MAT4:
423        return 16;
424
425    default:
426        return 0;
427    }
428}
429
430Uniform::Type Uniform::getTypeId( const std::string& tname )
431{
432    if( tname == "float" )           return FLOAT;
433    if( tname == "vec2" )            return FLOAT_VEC2;
434    if( tname == "vec3" )            return FLOAT_VEC3;
435    if( tname == "vec4" )            return FLOAT_VEC4;
436    if( tname == "int" )             return INT;
437    if( tname == "ivec2" )           return INT_VEC2;
438    if( tname == "ivec3" )           return INT_VEC3;
439    if( tname == "ivec4" )           return INT_VEC4;
440    if( tname == "bool" )            return BOOL;
441    if( tname == "bvec2" )           return BOOL_VEC2;
442    if( tname == "bvec3" )           return BOOL_VEC3;
443    if( tname == "bvec4" )           return BOOL_VEC4;
444    if( tname == "mat2" || tname == "mat2x2" ) return FLOAT_MAT2;
445    if( tname == "mat3" || tname == "mat3x3" ) return FLOAT_MAT3;
446    if( tname == "mat4" || tname == "mat4x4" ) return FLOAT_MAT4;
447    if( tname == "sampler1D" )       return SAMPLER_1D;
448    if( tname == "sampler2D" )       return SAMPLER_2D;
449    if( tname == "sampler1DArray" )  return SAMPLER_1D_ARRAY;
450    if( tname == "sampler2DArray" )  return SAMPLER_2D_ARRAY;
451    if( tname == "sampler3D" )       return SAMPLER_3D;
452    if( tname == "samplerCube" )     return SAMPLER_CUBE;
453    if( tname == "sampler1DShadow" ) return SAMPLER_1D_SHADOW;
454    if( tname == "sampler2DShadow" ) return SAMPLER_2D_SHADOW;
455    if( tname == "sampler1DArrayShadow" ) return SAMPLER_1D_ARRAY_SHADOW;
456    if( tname == "sampler2DArrayShadow" ) return SAMPLER_2D_ARRAY_SHADOW;
457    if( tname == "mat2x3" )          return FLOAT_MAT2x3;
458    if( tname == "mat2x4" )          return FLOAT_MAT2x4;
459    if( tname == "mat3x2" )          return FLOAT_MAT3x2;
460    if( tname == "mat3x4" )          return FLOAT_MAT3x4;
461    if( tname == "mat4x2" )          return FLOAT_MAT4x2;
462    if( tname == "mat4x3" )          return FLOAT_MAT4x3;
463    if( tname == "samplerBuffer" )     return SAMPLER_BUFFER;
464    if( tname == "samplerCubeShadow" ) return SAMPLER_CUBE_SHADOW;
465    if( tname == "unsigned int" )    return UNSIGNED_INT;
466    if( tname == "uvec2" )           return UNSIGNED_INT_VEC2;
467    if( tname == "uvec3" )           return UNSIGNED_INT_VEC3;
468    if( tname == "uvec4" )           return UNSIGNED_INT_VEC4;
469    if( tname == "isampler1D" )      return INT_SAMPLER_1D;
470    if( tname == "isampler2D" )      return INT_SAMPLER_2D;
471    if( tname == "isampler3D" )      return INT_SAMPLER_3D;
472    if( tname == "isamplerCube" )    return INT_SAMPLER_CUBE;
473    if( tname == "isampler2DRect" )  return INT_SAMPLER_2D_RECT;
474    if( tname == "isampler1DArray" ) return INT_SAMPLER_1D_ARRAY;
475    if( tname == "isampler2DArray" ) return INT_SAMPLER_2D_ARRAY;
476    if( tname == "isamplerBuffer" )  return INT_SAMPLER_BUFFER;
477    if( tname == "usampler1D" )      return UNSIGNED_INT_SAMPLER_1D;
478    if( tname == "usampler2D" )      return UNSIGNED_INT_SAMPLER_2D;
479    if( tname == "usampler3D" )      return UNSIGNED_INT_SAMPLER_3D;
480    if( tname == "usamplerCube" )    return UNSIGNED_INT_SAMPLER_CUBE;
481    if( tname == "usampler2DRect" )  return UNSIGNED_INT_SAMPLER_2D_RECT;
482    if( tname == "usampler1DArray" ) return UNSIGNED_INT_SAMPLER_1D_ARRAY;
483    if( tname == "usampler2DArray" ) return UNSIGNED_INT_SAMPLER_2D_ARRAY;
484    if( tname == "usamplerBuffer" )  return UNSIGNED_INT_SAMPLER_BUFFER;
485
486    return UNDEFINED;
487}
488
489Uniform::Type Uniform::getGlApiType( Type t )
490{
491    switch( t )
492    {
493    case BOOL:
494    case SAMPLER_1D:
495    case SAMPLER_2D:
496    case SAMPLER_1D_ARRAY:
497    case SAMPLER_2D_ARRAY:
498    case SAMPLER_3D:
499    case SAMPLER_CUBE:
500    case SAMPLER_1D_SHADOW:
501    case SAMPLER_2D_SHADOW:
502    case SAMPLER_1D_ARRAY_SHADOW:
503    case SAMPLER_2D_ARRAY_SHADOW:
504    case SAMPLER_BUFFER:
505    case SAMPLER_CUBE_SHADOW:
506    case INT_SAMPLER_1D:
507    case INT_SAMPLER_2D:
508    case INT_SAMPLER_3D:
509    case INT_SAMPLER_CUBE:
510    case INT_SAMPLER_2D_RECT:
511    case INT_SAMPLER_1D_ARRAY:
512    case INT_SAMPLER_2D_ARRAY:
513    case INT_SAMPLER_BUFFER:
514    case UNSIGNED_INT_SAMPLER_1D:
515    case UNSIGNED_INT_SAMPLER_2D:
516    case UNSIGNED_INT_SAMPLER_3D:
517    case UNSIGNED_INT_SAMPLER_CUBE:
518    case UNSIGNED_INT_SAMPLER_2D_RECT:
519    case UNSIGNED_INT_SAMPLER_1D_ARRAY:
520    case UNSIGNED_INT_SAMPLER_2D_ARRAY:
521    case UNSIGNED_INT_SAMPLER_BUFFER:
522        return INT;
523
524    case BOOL_VEC2:
525        return INT_VEC2;
526
527    case BOOL_VEC3:
528        return INT_VEC3;
529
530    case BOOL_VEC4:
531        return INT_VEC4;
532
533    default:
534        return t;
535    }
536}
537
538GLenum Uniform::getInternalArrayType( Type t )
539{
540    switch( t )
541    {
542    case FLOAT:
543    case FLOAT_VEC2:
544    case FLOAT_VEC3:
545    case FLOAT_VEC4:
546    case FLOAT_MAT2:
547    case FLOAT_MAT3:
548    case FLOAT_MAT4:
549    case FLOAT_MAT2x3:
550    case FLOAT_MAT2x4:
551    case FLOAT_MAT3x2:
552    case FLOAT_MAT3x4:
553    case FLOAT_MAT4x2:
554    case FLOAT_MAT4x3:
555        return GL_FLOAT;
556
557    case INT:
558    case INT_VEC2:
559    case INT_VEC3:
560    case INT_VEC4:
561    case BOOL:
562    case BOOL_VEC2:
563    case BOOL_VEC3:
564    case BOOL_VEC4:
565    case SAMPLER_1D:
566    case SAMPLER_2D:
567    case SAMPLER_1D_ARRAY:
568    case SAMPLER_2D_ARRAY:
569    case SAMPLER_3D:
570    case SAMPLER_CUBE:
571    case SAMPLER_1D_SHADOW:
572    case SAMPLER_2D_SHADOW:
573    case SAMPLER_1D_ARRAY_SHADOW:
574    case SAMPLER_2D_ARRAY_SHADOW:
575    case SAMPLER_BUFFER:
576    case SAMPLER_CUBE_SHADOW:
577    case INT_SAMPLER_1D:
578    case INT_SAMPLER_2D:
579    case INT_SAMPLER_3D:
580    case INT_SAMPLER_CUBE:
581    case INT_SAMPLER_2D_RECT:
582    case INT_SAMPLER_1D_ARRAY:
583    case INT_SAMPLER_2D_ARRAY:
584    case INT_SAMPLER_BUFFER:
585    case UNSIGNED_INT_SAMPLER_1D:
586    case UNSIGNED_INT_SAMPLER_2D:
587    case UNSIGNED_INT_SAMPLER_3D:
588    case UNSIGNED_INT_SAMPLER_CUBE:
589    case UNSIGNED_INT_SAMPLER_2D_RECT:
590    case UNSIGNED_INT_SAMPLER_1D_ARRAY:
591    case UNSIGNED_INT_SAMPLER_2D_ARRAY:
592    case UNSIGNED_INT_SAMPLER_BUFFER:
593        return GL_INT;
594
595    case UNSIGNED_INT:
596    case UNSIGNED_INT_VEC2:
597    case UNSIGNED_INT_VEC3:
598    case UNSIGNED_INT_VEC4:
599        return GL_UNSIGNED_INT;
600
601    default:
602        return 0;
603    }
604}
605
606
607unsigned int Uniform::getNameID(const std::string& name)
608{
609    typedef std::map<std::string, unsigned int> UniformNameIDMap;
610    static OpenThreads::Mutex s_mutex_uniformNameIDMap;
611    static UniformNameIDMap s_uniformNameIDMap;
612
613    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_uniformNameIDMap);
614    UniformNameIDMap::iterator it = s_uniformNameIDMap.find(name);
615    if (it != s_uniformNameIDMap.end())
616    {
617        return it->second;
618    }
619    unsigned int id = s_uniformNameIDMap.size();
620    s_uniformNameIDMap.insert(UniformNameIDMap::value_type(name, id));
621    return id;
622}
623
624
625///////////////////////////////////////////////////////////////////////////
626// value constructors for single-element (ie: non-array) uniforms
627
628Uniform::Uniform( const char* name, float f ) :
629    _type(FLOAT), _numElements(1), _modifiedCount(0)
630{
631    setName(name);
632    allocateDataArray();
633    set( f );
634}
635
636Uniform::Uniform( const char* name, const osg::Vec2& v2 ) :
637    _type(FLOAT_VEC2), _numElements(1), _modifiedCount(0)
638{
639    setName(name);
640    allocateDataArray();
641    set( v2 );
642}
643
644Uniform::Uniform( const char* name, const osg::Vec3& v3 ) :
645     _type(FLOAT_VEC3), _numElements(1), _modifiedCount(0)
646{
647    setName(name);
648    allocateDataArray();
649    set( v3 );
650}
651
652Uniform::Uniform( const char* name, const osg::Vec4& v4 ) :
653    _type(FLOAT_VEC4), _numElements(1), _modifiedCount(0)
654{
655    setName(name);
656    allocateDataArray();
657    set( v4 );
658}
659
660Uniform::Uniform( const char* name, const osg::Matrix2& m2 ) :
661    _type(FLOAT_MAT2), _numElements(1), _modifiedCount(0)
662{
663    setName(name);
664    allocateDataArray();
665    set( m2 );
666}
667
668Uniform::Uniform( const char* name, const osg::Matrix3& m3 ) :
669    _type(FLOAT_MAT3), _numElements(1), _modifiedCount(0)
670{
671    setName(name);
672    allocateDataArray();
673    set( m3 );
674}
675
676Uniform::Uniform( const char* name, const osg::Matrixf& m4 ) :
677    _type(FLOAT_MAT4), _numElements(1), _modifiedCount(0)
678{
679    setName(name);
680    allocateDataArray();
681    set( m4 );
682}
683
684Uniform::Uniform( const char* name, const osg::Matrixd& m4 ) :
685    _type(FLOAT_MAT4), _numElements(1), _modifiedCount(0)
686{
687    setName(name);
688    allocateDataArray();
689    set( m4 );
690}
691
692Uniform::Uniform( const char* name, int i ) :
693    _type(INT), _numElements(1), _modifiedCount(0)
694{
695    setName(name);
696    allocateDataArray();
697    set( i );
698}
699
700Uniform::Uniform( const char* name, int i0, int i1 ) :
701    _type(INT_VEC2), _numElements(1), _modifiedCount(0)
702{
703    setName(name);
704    allocateDataArray();
705    set( i0, i1 );
706}
707
708Uniform::Uniform( const char* name, int i0, int i1, int i2 ) :
709    _type(INT_VEC3), _numElements(1), _modifiedCount(0)
710{
711    setName(name);
712    allocateDataArray();
713    set( i0, i1, i2 );
714}
715
716Uniform::Uniform( const char* name, int i0, int i1, int i2, int i3 ) :
717    _type(INT_VEC4), _numElements(1), _modifiedCount(0)
718{
719    setName(name);
720    allocateDataArray();
721    set( i0, i1, i2, i3 );
722}
723
724Uniform::Uniform( const char* name, unsigned int i ) :
725    _type(UNSIGNED_INT), _numElements(1), _modifiedCount(0)
726{
727    setName(name);
728    allocateDataArray();
729    set( i );
730}
731
732Uniform::Uniform( const char* name, unsigned int i0, unsigned int i1 ) :
733    _type(UNSIGNED_INT_VEC2), _numElements(1), _modifiedCount(0)
734{
735    setName(name);
736    allocateDataArray();
737    set( i0, i1 );
738}
739
740Uniform::Uniform( const char* name, unsigned int i0, unsigned int i1, unsigned int i2 ) :
741    _type(UNSIGNED_INT_VEC3), _numElements(1), _modifiedCount(0)
742{
743    setName(name);
744    allocateDataArray();
745    set( i0, i1, i2 );
746}
747
748Uniform::Uniform( const char* name, unsigned int i0, unsigned int i1, unsigned int i2, unsigned int i3 ) :
749    _type(UNSIGNED_INT_VEC4), _numElements(1), _modifiedCount(0)
750{
751    setName(name);
752    allocateDataArray();
753    set( i0, i1, i2, i3 );
754}
755
756Uniform::Uniform( const char* name, bool b ) :
757    _type(BOOL), _numElements(1), _modifiedCount(0)
758{
759    setName(name);
760    allocateDataArray();
761    set( b );
762}
763
764Uniform::Uniform( const char* name, bool b0, bool b1 ) :
765     _type(BOOL_VEC2), _numElements(1), _modifiedCount(0)
766{
767    setName(name);
768    allocateDataArray();
769    set( b0, b1 );
770}
771
772Uniform::Uniform( const char* name, bool b0, bool b1, bool b2 ) :
773    _type(BOOL_VEC3), _numElements(1), _modifiedCount(0)
774{
775    setName(name);
776    allocateDataArray();
777    set( b0, b1, b2 );
778}
779
780Uniform::Uniform( const char* name, bool b0, bool b1, bool b2, bool b3 ) :
781    _type(BOOL_VEC4), _numElements(1), _modifiedCount(0)
782{
783    setName(name);
784    allocateDataArray();
785    set( b0, b1, b2, b3 );
786}
787
788///////////////////////////////////////////////////////////////////////////
789// Value assignment for single-element (ie: non-array) uniforms.
790// (For backwards compatability, if not already configured, set the
791// Uniform's _numElements=1)
792
793bool Uniform::set( float f )
794{
795    if( getNumElements() == 0 ) setNumElements(1);
796    return isScalar() ? setElement(0,f) : false;
797}
798
799bool Uniform::set( const osg::Vec2& v2 )
800{
801    if( getNumElements() == 0 ) setNumElements(1);
802    return isScalar() ? setElement(0,v2) : false;
803}
804
805bool Uniform::set( const osg::Vec3& v3 )
806{
807    if( getNumElements() == 0 ) setNumElements(1);
808    return isScalar() ? setElement(0,v3) : false;
809}
810
811bool Uniform::set( const osg::Vec4& v4 )
812{
813    if( getNumElements() == 0 ) setNumElements(1);
814    return isScalar() ? setElement(0,v4) : false;
815}
816
817bool Uniform::set( const osg::Matrix2& m2 )
818{
819    if( getNumElements() == 0 ) setNumElements(1);
820    return isScalar() ? setElement(0,m2) : false;
821}
822
823bool Uniform::set( const osg::Matrix3& m3 )
824{
825    if( getNumElements() == 0 ) setNumElements(1);
826    return isScalar() ? setElement(0,m3) : false;
827}
828
829bool Uniform::set( const osg::Matrixf& m4 )
830{
831    if( getNumElements() == 0 ) setNumElements(1);
832    return isScalar() ? setElement(0,m4) : false;
833}
834
835bool Uniform::set( const osg::Matrixd& m4 )
836{
837    if( getNumElements() == 0 ) setNumElements(1);
838    return isScalar() ? setElement(0,m4) : false;
839}
840
841bool Uniform::set( int i )
842{
843    if( getNumElements() == 0 ) setNumElements(1);
844    return isScalar() ? setElement(0,i) : false;
845}
846
847bool Uniform::set( int i0, int i1 )
848{
849    if( getNumElements() == 0 ) setNumElements(1);
850    return isScalar() ? setElement(0,i0,i1) : false;
851}
852
853bool Uniform::set( int i0, int i1, int i2 )
854{
855    if( getNumElements() == 0 ) setNumElements(1);
856    return isScalar() ? setElement(0,i0,i1,i2) : false;
857}
858
859bool Uniform::set( int i0, int i1, int i2, int i3 )
860{
861    if( getNumElements() == 0 ) setNumElements(1);
862    return isScalar() ? setElement(0,i0,i1,i2,i3) : false;
863}
864
865bool Uniform::set( unsigned int i )
866{
867    if( getNumElements() == 0 ) setNumElements(1);
868    return isScalar() ? setElement(0,i) : false;
869}
870
871bool Uniform::set( unsigned int i0, unsigned int i1 )
872{
873    if( getNumElements() == 0 ) setNumElements(1);
874    return isScalar() ? setElement(0,i0,i1) : false;
875}
876
877bool Uniform::set( unsigned int i0, unsigned int i1, unsigned int i2 )
878{
879    if( getNumElements() == 0 ) setNumElements(1);
880    return isScalar() ? setElement(0,i0,i1,i2) : false;
881}
882
883bool Uniform::set( unsigned int i0, unsigned int i1, unsigned int i2, unsigned int i3 )
884{
885    if( getNumElements() == 0 ) setNumElements(1);
886    return isScalar() ? setElement(0,i0,i1,i2,i3) : false;
887}
888
889bool Uniform::set( bool b )
890{
891    if( getNumElements() == 0 ) setNumElements(1);
892    return isScalar() ? setElement(0,b) : false;
893}
894
895bool Uniform::set( bool b0, bool b1 )
896{
897    if( getNumElements() == 0 ) setNumElements(1);
898    return isScalar() ? setElement(0,b0,b1) : false;
899}
900
901bool Uniform::set( bool b0, bool b1, bool b2 )
902{
903    if( getNumElements() == 0 ) setNumElements(1);
904    return isScalar() ? setElement(0,b0,b1,b2) : false;
905}
906
907bool Uniform::set( bool b0, bool b1, bool b2, bool b3 )
908{
909    if( getNumElements() == 0 ) setNumElements(1);
910    return isScalar() ? setElement(0,b0,b1,b2,b3) : false;
911}
912
913///////////////////////////////////////////////////////////////////////////
914// Value query for single-element (ie: non-array) uniforms.
915
916bool Uniform::get( float& f ) const
917{
918    return isScalar() ? getElement(0,f) : false;
919}
920
921bool Uniform::get( osg::Vec2& v2 ) const
922{
923    return isScalar() ? getElement(0,v2) : false;
924}
925
926bool Uniform::get( osg::Vec3& v3 ) const
927{
928    return isScalar() ? getElement(0,v3) : false;
929}
930
931bool Uniform::get( osg::Vec4& v4 ) const
932{
933    return isScalar() ? getElement(0,v4) : false;
934}
935
936bool Uniform::get( osg::Matrix2& m2 ) const
937{
938    return isScalar() ? getElement(0,m2) : false;
939}
940
941bool Uniform::get( osg::Matrix3& m3 ) const
942{
943    return isScalar() ? getElement(0,m3) : false;
944}
945
946bool Uniform::get( osg::Matrixf& m4 ) const
947{
948    return isScalar() ? getElement(0,m4) : false;
949}
950
951bool Uniform::get( osg::Matrixd& m4 ) const
952{
953    return isScalar() ? getElement(0,m4) : false;
954}
955
956bool Uniform::get( int& i ) const
957{
958    return isScalar() ? getElement(0,i) : false;
959}
960
961bool Uniform::get( int& i0, int& i1 ) const
962{
963    return isScalar() ? getElement(0,i0,i1) : false;
964}
965
966bool Uniform::get( int& i0, int& i1, int& i2 ) const
967{
968    return isScalar() ? getElement(0,i0,i1,i2) : false;
969}
970
971bool Uniform::get( int& i0, int& i1, int& i2, int& i3 ) const
972{
973    return isScalar() ? getElement(0,i0,i1,i2,i3) : false;
974}
975
976bool Uniform::get( unsigned int& i ) const
977{
978    return isScalar() ? getElement(0,i) : false;
979}
980
981bool Uniform::get( unsigned int& i0, unsigned int& i1 ) const
982{
983    return isScalar() ? getElement(0,i0,i1) : false;
984}
985
986bool Uniform::get( unsigned int& i0, unsigned int& i1, unsigned int& i2 ) const
987{
988    return isScalar() ? getElement(0,i0,i1,i2) : false;
989}
990
991bool Uniform::get( unsigned int& i0, unsigned int& i1, unsigned int& i2, unsigned int& i3 ) const
992{
993    return isScalar() ? getElement(0,i0,i1,i2,i3) : false;
994}
995
996bool Uniform::get( bool& b ) const
997{
998    return isScalar() ? getElement(0,b) : false;
999}
1000
1001bool Uniform::get( bool& b0, bool& b1 ) const
1002{
1003    return isScalar() ? getElement(0,b0,b1) : false;
1004}
1005
1006bool Uniform::get( bool& b0, bool& b1, bool& b2 ) const
1007{
1008    return isScalar() ? getElement(0,b0,b1,b2) : false;
1009}
1010
1011bool Uniform::get( bool& b0, bool& b1, bool& b2, bool& b3 ) const
1012{
1013    return isScalar() ? getElement(0,b0,b1,b2,b3) : false;
1014}
1015
1016///////////////////////////////////////////////////////////////////////////
1017// Value assignment for array uniforms.
1018
1019bool Uniform::setElement( unsigned int index, float f )
1020{
1021    if( index>=getNumElements() || !isCompatibleType(FLOAT) ) return false;
1022    unsigned int j = index * getTypeNumComponents(getType());
1023    (*_floatArray)[j] = f;
1024    dirty();
1025    return true;
1026}
1027
1028bool Uniform::setElement( unsigned int index, const osg::Vec2& v2 )
1029{
1030    if( index>=getNumElements() || !isCompatibleType(FLOAT_VEC2) ) return false;
1031    unsigned int j = index * getTypeNumComponents(getType());
1032    (*_floatArray)[j] = v2.x();
1033    (*_floatArray)[j+1] = v2.y();
1034    dirty();
1035    return true;
1036}
1037
1038bool Uniform::setElement( unsigned int index, const osg::Vec3& v3 )
1039{
1040    if( index>=getNumElements() || !isCompatibleType(FLOAT_VEC3) ) return false;
1041    unsigned int j = index * getTypeNumComponents(getType());
1042    (*_floatArray)[j] = v3.x();
1043    (*_floatArray)[j+1] = v3.y();
1044    (*_floatArray)[j+2] = v3.z();
1045    dirty();
1046    return true;
1047}
1048
1049bool Uniform::setElement( unsigned int index, const osg::Vec4& v4 )
1050{
1051    if( index>=getNumElements() || !isCompatibleType(FLOAT_VEC4) ) return false;
1052    unsigned int j = index * getTypeNumComponents(getType());
1053    (*_floatArray)[j] = v4.x();
1054    (*_floatArray)[j+1] = v4.y();
1055    (*_floatArray)[j+2] = v4.z();
1056    (*_floatArray)[j+3] = v4.w();
1057    dirty();
1058    return true;
1059}
1060
1061bool Uniform::setElement( unsigned int index, const osg::Matrix2& m2 )
1062{
1063    if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT2) ) return false;
1064    unsigned int j = index * getTypeNumComponents(getType());
1065    for( int i = 0; i < 4; ++i ) (*_floatArray)[j+i] = m2[i];
1066    dirty();
1067    return true;
1068}
1069
1070bool Uniform::setElement( unsigned int index, const osg::Matrix3& m3 )
1071{
1072    if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT3) ) return false;
1073    unsigned int j = index * getTypeNumComponents(getType());
1074    for( int i = 0; i < 9; ++i ) (*_floatArray)[j+i] = m3[i];
1075    dirty();
1076    return true;
1077}
1078
1079bool Uniform::setElement( unsigned int index, const osg::Matrixf& m4 )
1080{
1081    if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT4) ) return false;
1082    unsigned int j = index * getTypeNumComponents(getType());
1083    const Matrixf::value_type* p = m4.ptr();
1084    for( int i = 0; i < 16; ++i ) (*_floatArray)[j+i] = p[i];
1085    dirty();
1086    return true;
1087}
1088
1089bool Uniform::setElement( unsigned int index, const osg::Matrixd& m4 )
1090{
1091    if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT4) ) return false;
1092    unsigned int j = index * getTypeNumComponents(getType());
1093    const Matrixd::value_type* p = m4.ptr();
1094    for( int i = 0; i < 16; ++i ) (*_floatArray)[j+i] = static_cast<float>(p[i]);
1095    dirty();
1096    return true;
1097}
1098
1099bool Uniform::setElement( unsigned int index, int i )
1100{
1101    if( index>=getNumElements() || !isCompatibleType(INT) ) return false;
1102    unsigned int j = index * getTypeNumComponents(getType());
1103    (*_intArray)[j] = i;
1104    dirty();
1105    return true;
1106}
1107
1108bool Uniform::setElement( unsigned int index, int i0, int i1 )
1109{
1110    if( index>=getNumElements() || !isCompatibleType(INT_VEC2) ) return false;
1111    unsigned int j = index * getTypeNumComponents(getType());
1112    (*_intArray)[j] = i0;
1113    (*_intArray)[j+1] = i1;
1114    dirty();
1115    return true;
1116}
1117
1118bool Uniform::setElement( unsigned int index, int i0, int i1, int i2 )
1119{
1120    if( index>=getNumElements() || !isCompatibleType(INT_VEC3) ) return false;
1121    unsigned int j = index * getTypeNumComponents(getType());
1122    (*_intArray)[j] = i0;
1123    (*_intArray)[j+1] = i1;
1124    (*_intArray)[j+2] = i2;
1125    dirty();
1126    return true;
1127}
1128
1129bool Uniform::setElement( unsigned int index, int i0, int i1, int i2, int i3 )
1130{
1131    if( index>=getNumElements() || !isCompatibleType(INT_VEC4) ) return false;
1132    unsigned int j = index * getTypeNumComponents(getType());
1133    (*_intArray)[j] = i0;
1134    (*_intArray)[j+1] = i1;
1135    (*_intArray)[j+2] = i2;
1136    (*_intArray)[j+3] = i3;
1137    dirty();
1138    return true;
1139}
1140
1141bool Uniform::setElement( unsigned int index, unsigned int i )
1142{
1143    if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT) ) return false;
1144    unsigned int j = index * getTypeNumComponents(getType());
1145    (*_uintArray)[j] = i;
1146    dirty();
1147    return true;
1148}
1149
1150bool Uniform::setElement( unsigned int index, unsigned int i0, unsigned int i1 )
1151{
1152    if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT_VEC2) ) return false;
1153    unsigned int j = index * getTypeNumComponents(getType());
1154    (*_uintArray)[j] = i0;
1155    (*_uintArray)[j+1] = i1;
1156    dirty();
1157    return true;
1158}
1159
1160bool Uniform::setElement( unsigned int index, unsigned int i0, unsigned int i1, unsigned int i2 )
1161{
1162    if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT_VEC3) ) return false;
1163    unsigned int j = index * getTypeNumComponents(getType());
1164    (*_uintArray)[j] = i0;
1165    (*_uintArray)[j+1] = i1;
1166    (*_uintArray)[j+2] = i2;
1167    dirty();
1168    return true;
1169}
1170
1171bool Uniform::setElement( unsigned int index, unsigned int i0, unsigned int i1, unsigned int i2, unsigned int i3 )
1172{
1173    if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT_VEC4) ) return false;
1174    unsigned int j = index * getTypeNumComponents(getType());
1175    (*_uintArray)[j] = i0;
1176    (*_uintArray)[j+1] = i1;
1177    (*_uintArray)[j+2] = i2;
1178    (*_uintArray)[j+3] = i3;
1179    dirty();
1180    return true;
1181}
1182
1183bool Uniform::setElement( unsigned int index, bool b )
1184{
1185    if( index>=getNumElements() || !isCompatibleType(BOOL) ) return false;
1186    unsigned int j = index * getTypeNumComponents(getType());
1187    (*_intArray)[j] = b;
1188    dirty();
1189    return true;
1190}
1191
1192bool Uniform::setElement( unsigned int index, bool b0, bool b1 )
1193{
1194    if( index>=getNumElements() || !isCompatibleType(BOOL_VEC2) ) return false;
1195    unsigned int j = index * getTypeNumComponents(getType());
1196    (*_intArray)[j] = b0;
1197    (*_intArray)[j+1] = b1;
1198    dirty();
1199    return true;
1200}
1201
1202bool Uniform::setElement( unsigned int index, bool b0, bool b1, bool b2 )
1203{
1204    if( index>=getNumElements() || !isCompatibleType(BOOL_VEC3) ) return false;
1205    unsigned int j = index * getTypeNumComponents(getType());
1206    (*_intArray)[j] = b0;
1207    (*_intArray)[j+1] = b1;
1208    (*_intArray)[j+2] = b2;
1209    dirty();
1210    return true;
1211}
1212
1213bool Uniform::setElement( unsigned int index, bool b0, bool b1, bool b2, bool b3 )
1214{
1215    if( index>=getNumElements() || !isCompatibleType(BOOL_VEC4) ) return false;
1216    unsigned int j = index * getTypeNumComponents(getType());
1217    (*_intArray)[j] = b0;
1218    (*_intArray)[j+1] = b1;
1219    (*_intArray)[j+2] = b2;
1220    (*_intArray)[j+3] = b3;
1221    dirty();
1222    return true;
1223}
1224
1225///////////////////////////////////////////////////////////////////////////
1226// Value query for array uniforms.
1227
1228bool Uniform::getElement( unsigned int index, float& f ) const
1229{
1230    if( index>=getNumElements() || !isCompatibleType(FLOAT) ) return false;
1231    unsigned int j = index * getTypeNumComponents(getType());
1232    f = (*_floatArray)[j];
1233    return true;
1234}
1235
1236bool Uniform::getElement( unsigned int index, osg::Vec2& v2 ) const
1237{
1238    if( index>=getNumElements() || !isCompatibleType(FLOAT_VEC2) ) return false;
1239    unsigned int j = index * getTypeNumComponents(getType());
1240    v2.x() = (*_floatArray)[j];
1241    v2.y() = (*_floatArray)[j+1];
1242    return true;
1243}
1244
1245bool Uniform::getElement( unsigned int index, osg::Vec3& v3 ) const
1246{
1247    if( index>=getNumElements() || !isCompatibleType(FLOAT_VEC3) ) return false;
1248    unsigned int j = index * getTypeNumComponents(getType());
1249    v3.x() = (*_floatArray)[j];
1250    v3.y() = (*_floatArray)[j+1];
1251    v3.z() = (*_floatArray)[j+2];
1252    return true;
1253}
1254
1255bool Uniform::getElement( unsigned int index, osg::Vec4& v4 ) const
1256{
1257    if( index>=getNumElements() || !isCompatibleType(FLOAT_VEC4) ) return false;
1258    unsigned int j = index * getTypeNumComponents(getType());
1259    v4.x() = (*_floatArray)[j];
1260    v4.y() = (*_floatArray)[j+1];
1261    v4.z() = (*_floatArray)[j+2];
1262    v4.w() = (*_floatArray)[j+3];
1263    return true;
1264}
1265
1266bool Uniform::getElement( unsigned int index, osg::Matrix2& m2 ) const
1267{
1268    if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT2) ) return false;
1269    unsigned int j = index * getTypeNumComponents(getType());
1270    m2.set( &((*_floatArray)[j]) );
1271    return true;
1272}
1273
1274bool Uniform::getElement( unsigned int index, osg::Matrix3& m3 ) const
1275{
1276    if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT3) ) return false;
1277    unsigned int j = index * getTypeNumComponents(getType());
1278    m3.set( &((*_floatArray)[j]) );
1279    return true;
1280}
1281
1282bool Uniform::getElement( unsigned int index, osg::Matrixf& m4 ) const
1283{
1284    if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT4) ) return false;
1285    unsigned int j = index * getTypeNumComponents(getType());
1286    m4.set( &((*_floatArray)[j]) );
1287    return true;
1288}
1289
1290bool Uniform::getElement( unsigned int index, osg::Matrixd& m4 ) const
1291{
1292    if( index>=getNumElements() || !isCompatibleType(FLOAT_MAT4) ) return false;
1293    unsigned int j = index * getTypeNumComponents(getType());
1294    m4.set( &((*_floatArray)[j]) );
1295    return true;
1296}
1297
1298bool Uniform::getElement( unsigned int index, int& i ) const
1299{
1300    if( index>=getNumElements() || !isCompatibleType(INT) ) return false;
1301    unsigned int j = index * getTypeNumComponents(getType());
1302    i = (*_intArray)[j];
1303    return true;
1304}
1305
1306bool Uniform::getElement( unsigned int index, int& i0, int& i1 ) const
1307{
1308    if( index>=getNumElements() || !isCompatibleType(INT_VEC2) ) return false;
1309    unsigned int j = index * getTypeNumComponents(getType());
1310    i0 = (*_intArray)[j];
1311    i1 = (*_intArray)[j+1];
1312    return true;
1313}
1314
1315bool Uniform::getElement( unsigned int index, int& i0, int& i1, int& i2 ) const
1316{
1317    if( index>=getNumElements() || !isCompatibleType(INT_VEC3) ) return false;
1318    unsigned int j = index * getTypeNumComponents(getType());
1319    i0 = (*_intArray)[j];
1320    i1 = (*_intArray)[j+1];
1321    i2 = (*_intArray)[j+2];
1322    return true;
1323}
1324
1325bool Uniform::getElement( unsigned int index, int& i0, int& i1, int& i2, int& i3 ) const
1326{
1327    if( index>=getNumElements() || !isCompatibleType(INT_VEC4) ) return false;
1328    unsigned int j = index * getTypeNumComponents(getType());
1329    i0 = (*_intArray)[j];
1330    i1 = (*_intArray)[j+1];
1331    i2 = (*_intArray)[j+2];
1332    i3 = (*_intArray)[j+3];
1333    return true;
1334}
1335
1336bool Uniform::getElement( unsigned int index, unsigned int& i ) const
1337{
1338    if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT) ) return false;
1339    unsigned int j = index * getTypeNumComponents(getType());
1340    i = (*_uintArray)[j];
1341    return true;
1342}
1343
1344bool Uniform::getElement( unsigned int index, unsigned int& i0, unsigned int& i1 ) const
1345{
1346    if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT_VEC2) ) return false;
1347    unsigned int j = index * getTypeNumComponents(getType());
1348    i0 = (*_uintArray)[j];
1349    i1 = (*_uintArray)[j+1];
1350    return true;
1351}
1352
1353bool Uniform::getElement( unsigned int index, unsigned int& i0, unsigned int& i1, unsigned int& i2 ) const
1354{
1355    if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT_VEC3) ) return false;
1356    unsigned int j = index * getTypeNumComponents(getType());
1357    i0 = (*_uintArray)[j];
1358    i1 = (*_uintArray)[j+1];
1359    i2 = (*_uintArray)[j+2];
1360    return true;
1361}
1362
1363bool Uniform::getElement( unsigned int index, unsigned int& i0, unsigned int& i1, unsigned int& i2, unsigned int& i3 ) const
1364{
1365    if( index>=getNumElements() || !isCompatibleType(UNSIGNED_INT_VEC4) ) return false;
1366    unsigned int j = index * getTypeNumComponents(getType());
1367    i0 = (*_uintArray)[j];
1368    i1 = (*_uintArray)[j+1];
1369    i2 = (*_uintArray)[j+2];
1370    i3 = (*_uintArray)[j+3];
1371    return true;
1372}
1373
1374bool Uniform::getElement( unsigned int index, bool& b ) const
1375{
1376    if( index>=getNumElements() || !isCompatibleType(BOOL) ) return false;
1377    unsigned int j = index * getTypeNumComponents(getType());
1378    b = ((*_intArray)[j] != 0);
1379    return true;
1380}
1381
1382bool Uniform::getElement( unsigned int index, bool& b0, bool& b1 ) const
1383{
1384    if( index>=getNumElements() || !isCompatibleType(BOOL_VEC2) ) return false;
1385    unsigned int j = index * getTypeNumComponents(getType());
1386    b0 = ((*_intArray)[j] != 0);
1387    b1 = ((*_intArray)[j+1] != 0);
1388    return true;
1389}
1390
1391bool Uniform::getElement( unsigned int index, bool& b0, bool& b1, bool& b2 ) const
1392{
1393    if( index>=getNumElements() || !isCompatibleType(BOOL_VEC3) ) return false;
1394    unsigned int j = index * getTypeNumComponents(getType());
1395    b0 = ((*_intArray)[j] != 0);
1396    b1 = ((*_intArray)[j+1] != 0);
1397    b2 = ((*_intArray)[j+2] != 0);
1398    return true;
1399}
1400
1401bool Uniform::getElement( unsigned int index, bool& b0, bool& b1, bool& b2, bool& b3 ) const
1402{
1403    if( index>=getNumElements() || !isCompatibleType(BOOL_VEC4) ) return false;
1404    unsigned int j = index * getTypeNumComponents(getType());
1405    b0 = ((*_intArray)[j] != 0);
1406    b1 = ((*_intArray)[j+1] != 0);
1407    b2 = ((*_intArray)[j+2] != 0);
1408    b3 = ((*_intArray)[j+3] != 0);
1409    return true;
1410}
1411
1412unsigned int Uniform::getNameID() const
1413{
1414    return _nameID;
1415}
1416
1417///////////////////////////////////////////////////////////////////////////
1418
1419void Uniform::apply(const GL2Extensions* ext, GLint location) const
1420{
1421    // OSG_NOTICE << "uniform at "<<location<<" "<<_name<< std::endl;
1422
1423    GLsizei num = getNumElements();
1424    if( num < 1 ) return;
1425
1426    switch( getGlApiType(getType()) )
1427    {
1428    case FLOAT:
1429        if( _floatArray.valid() ) ext->glUniform1fv( location, num, &_floatArray->front() );
1430        break;
1431
1432    case FLOAT_VEC2:
1433        if( _floatArray.valid() ) ext->glUniform2fv( location, num, &_floatArray->front() );
1434        break;
1435
1436    case FLOAT_VEC3:
1437        if( _floatArray.valid() ) ext->glUniform3fv( location, num, &_floatArray->front() );
1438        break;
1439
1440    case FLOAT_VEC4:
1441        if( _floatArray.valid() ) ext->glUniform4fv( location, num, &_floatArray->front() );
1442        break;
1443
1444    case FLOAT_MAT2:
1445        if( _floatArray.valid() ) ext->glUniformMatrix2fv( location, num, GL_FALSE, &_floatArray->front() );
1446        break;
1447
1448    case FLOAT_MAT3:
1449        if( _floatArray.valid() ) ext->glUniformMatrix3fv( location, num, GL_FALSE, &_floatArray->front() );
1450        break;
1451
1452    case FLOAT_MAT4:
1453        if( _floatArray.valid() ) ext->glUniformMatrix4fv( location, num, GL_FALSE, &_floatArray->front() );
1454        break;
1455
1456    case INT:
1457        if( _intArray.valid() ) ext->glUniform1iv( location, num, &_intArray->front() );
1458        break;
1459
1460    case INT_VEC2:
1461        if( _intArray.valid() ) ext->glUniform2iv( location, num, &_intArray->front() );
1462        break;
1463
1464    case INT_VEC3:
1465        if( _intArray.valid() ) ext->glUniform3iv( location, num, &_intArray->front() );
1466        break;
1467
1468    case INT_VEC4:
1469        if( _intArray.valid() ) ext->glUniform4iv( location, num, &_intArray->front() );
1470        break;
1471
1472    case UNSIGNED_INT:
1473        if( _uintArray.valid() ) ext->glUniform1uiv( location, num, &_uintArray->front() );
1474        break;
1475
1476    case UNSIGNED_INT_VEC2:
1477        if( _uintArray.valid() ) ext->glUniform2uiv( location, num, &_uintArray->front() );
1478        break;
1479
1480    case UNSIGNED_INT_VEC3:
1481        if( _uintArray.valid() ) ext->glUniform3uiv( location, num, &_uintArray->front() );
1482        break;
1483
1484    case UNSIGNED_INT_VEC4:
1485        if( _uintArray.valid() ) ext->glUniform4uiv( location, num, &_uintArray->front() );
1486        break;
1487
1488    default:
1489        OSG_FATAL << "how got here? " __FILE__ ":" << __LINE__ << std::endl;
1490        break;
1491    }
1492}
1493
1494void Uniform::setUpdateCallback(Callback* uc)
1495{
1496    OSG_INFO<<"Uniform::Setting Update callbacks"<<std::endl;
1497
1498    if (_updateCallback==uc) return;
1499
1500    int delta = 0;
1501    if (_updateCallback.valid()) --delta;
1502    if (uc) ++delta;
1503
1504    _updateCallback = uc;
1505
1506    if (delta!=0)
1507    {
1508        OSG_INFO<<"Going to set Uniform parents"<<std::endl;
1509
1510        for(ParentList::iterator itr=_parents.begin();
1511            itr!=_parents.end();
1512            ++itr)
1513        {
1514            OSG_INFO<<"   setting Uniform parent"<<std::endl;
1515            (*itr)->setNumChildrenRequiringUpdateTraversal((*itr)->getNumChildrenRequiringUpdateTraversal()+delta);
1516        }
1517    }
1518}
1519
1520void Uniform::setEventCallback(Callback* ec)
1521{
1522    OSG_INFO<<"Uniform::Setting Event callbacks"<<std::endl;
1523
1524    if (_eventCallback==ec) return;
1525
1526    int delta = 0;
1527    if (_eventCallback.valid()) --delta;
1528    if (ec) ++delta;
1529
1530    _eventCallback = ec;
1531
1532    if (delta!=0)
1533    {
1534        for(ParentList::iterator itr=_parents.begin();
1535            itr!=_parents.end();
1536            ++itr)
1537        {
1538            (*itr)->setNumChildrenRequiringEventTraversal((*itr)->getNumChildrenRequiringEventTraversal()+delta);
1539        }
1540    }
1541}
Note: See TracBrowser for help on using the browser.