openscenegraph
Uniform
Go to the documentation of this file.
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 * Copyright (C) 2003-2005 3Dlabs Inc. Ltd.
3 * Copyright (C) 2008 Zebra Imaging
4 * Copyright (C) 2012 David Callu
5 *
6 * This application is open source and may be redistributed and/or modified
7 * freely and without restriction, both in commercial and non commercial
8 * applications, as long as this copyright notice is maintained.
9 *
10 * This application is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13*/
14
15/* file: include/osg/Uniform
16 * author: Mike Weiblen 2008-01-02
17*/
18
19#ifndef OSG_UNIFORM
20#define OSG_UNIFORM 1
21
22#include <osg/ref_ptr>
23#include <osg/Array>
24#include <osg/Callback>
25#include <osg/Vec2>
26#include <osg/Vec3>
27#include <osg/Vec4>
28#include <osg/Vec2d>
29#include <osg/Vec3d>
30#include <osg/Vec4d>
31#include <osg/Matrix>
32#include <osg/GLExtensions>
33
34#include <string.h> // for memset
35#include <string>
36#include <vector>
37
38
39namespace osg {
40
41// forward declare
42class NodeVisitor;
43
44///////////////////////////////////////////////////////////////////////////
45// C++ classes to represent the GLSL-specific types.
46//
47// Warning :
48// OSG is Row major
49// GLSL is Column Major
50//
51// If you define an Uniform with type Uniform::FLOAT_MAT4X2 and so use a Matrix4x2 to setup your Uniform,
52// like this :
53// 1 2
54// 3 4
55// 5 6
56// 7 8
57//
58// you will get in your shader a Column Major Matrix like this :
59// 1 3 5 7
60// 2 4 6 8
61//
62// In simple term, you matrix in OSG will be a transposed matrix in GLSL
63//
64//
65// You can avoid this behaviours starting GLSL version 1.40 with uniform layout :
66//
67// <GLSL code>
68// layout(row_major) uniform matrix4x2 myVariable;
69// <GLSL code>
70//
71//
72template <typename T, unsigned int RowN, unsigned int ColN>
73class MatrixTemplate
74{
75 public:
76 enum { col_count = ColN };
77 enum { row_count = RowN };
78 enum { value_count = ColN * RowN };
79
80 typedef T value_type;
81
82
83 public:
84 MatrixTemplate() {}
85 ~MatrixTemplate() {}
86
87 value_type& operator()(int row, int col) { return _mat[row][col]; }
88 value_type operator()(int row, int col) const { return _mat[row][col]; }
89
90 MatrixTemplate& operator = (const MatrixTemplate& rhs)
91 {
92 if( &rhs == this ) return *this;
93 set(rhs.ptr());
94 return *this;
95 }
96
97 void set(const MatrixTemplate& rhs) { set(rhs.ptr()); }
98
99 void set(value_type const * const ptr)
100 {
101 value_type* local_ptr = (value_type*)_mat;
102 for(int i=0;i<value_count;++i) local_ptr[i]=ptr[i];
103 }
104
105 value_type* ptr() { return (value_type*)_mat; }
106 const value_type* ptr() const { return (const value_type*)_mat; }
107
108 value_type& operator [] (int i) {return ptr()[i];}
109 value_type operator [] (int i) const {return ptr()[i];}
110
111 void reset() { memset(_mat, 0, sizeof( value_type ) * value_count); }
112
113 protected:
114 value_type _mat[row_count][col_count];
115};
116
117template <typename T>
118class Matrix2Template : public MatrixTemplate<T, 2, 2>
119{
120 public:
121 typedef MatrixTemplate<T, 2, 2> base_class;
122 typedef typename base_class::value_type value_type;
123
124
125 public:
126 Matrix2Template() { makeIdentity(); }
127 Matrix2Template( const Matrix2Template& mat ) { set(mat.ptr()); }
128 Matrix2Template( value_type a00, value_type a01,
129 value_type a10, value_type a11 )
130 {
131 set( a00, a01,
132 a10, a11 );
133 }
134 ~Matrix2Template() {}
135
136 using base_class::set;
137
138 void set(value_type a00, value_type a01,
139 value_type a10, value_type a11 )
140 {
141 base_class::_mat[0][0]=a00; base_class::_mat[0][1]=a01;
142 base_class::_mat[1][0]=a10; base_class::_mat[1][1]=a11;
143 }
144
145 void makeIdentity()
146 {
147 set( 1, 0,
148 0, 1 );
149 }
150};
151
152template <typename T>
153class Matrix2x3Template : public MatrixTemplate<T, 2, 3>
154{
155 public:
156 typedef MatrixTemplate<T, 2, 3> base_class;
157 typedef typename base_class::value_type value_type;
158
159
160 public:
161 Matrix2x3Template() { base_class::reset(); }
162 Matrix2x3Template( const Matrix2x3Template& mat ) { set(mat.ptr()); }
163 Matrix2x3Template( value_type a00, value_type a01, value_type a02,
164 value_type a10, value_type a11, value_type a12 )
165 {
166 set( a00, a01, a02,
167 a10, a11, a12 );
168 }
169 ~Matrix2x3Template() {}
170
171 using base_class::set;
172
173 void set( value_type a00, value_type a01, value_type a02,
174 value_type a10, value_type a11, value_type a12 )
175 {
176 base_class::_mat[0][0]=a00; base_class::_mat[0][1]=a01; base_class::_mat[0][2]=a02;
177 base_class::_mat[1][0]=a10; base_class::_mat[1][1]=a11; base_class::_mat[1][2]=a12;
178 }
179};
180
181template <typename T>
182class Matrix2x4Template : public MatrixTemplate<T, 2, 4>
183{
184 public:
185 typedef MatrixTemplate<T, 2, 4> base_class;
186 typedef typename base_class::value_type value_type;
187
188
189 public:
190 Matrix2x4Template() { base_class::reset(); }
191 Matrix2x4Template( const Matrix2x4Template& mat ) { set(mat.ptr()); }
192 Matrix2x4Template( value_type a00, value_type a01, value_type a02, value_type a03,
193 value_type a10, value_type a11, value_type a12, value_type a13 )
194 {
195 set( a00, a01, a02, a03,
196 a10, a11, a12, a13 );
197 }
198 ~Matrix2x4Template() {}
199
200 using base_class::set;
201
202 void set( value_type a00, value_type a01, value_type a02, value_type a03,
203 value_type a10, value_type a11, value_type a12, value_type a13 )
204 {
205 base_class::_mat[0][0]=a00; base_class::_mat[0][1]=a01; base_class::_mat[0][2]=a02; base_class::_mat[0][3]=a03;
206 base_class::_mat[1][0]=a10; base_class::_mat[1][1]=a11; base_class::_mat[1][2]=a12; base_class::_mat[1][3]=a13;
207 }
208};
209
210template <typename T>
211class Matrix3x2Template : public MatrixTemplate<T, 3, 2>
212{
213 public:
214 typedef MatrixTemplate<T, 3, 2> base_class;
215 typedef typename base_class::value_type value_type;
216
217 public:
218 Matrix3x2Template() { base_class::reset(); }
219 Matrix3x2Template( const Matrix3x2Template& mat ) { set(mat.ptr()); }
220 Matrix3x2Template( value_type a00, value_type a01,
221 value_type a10, value_type a11,
222 value_type a20, value_type a21 )
223 {
224 set( a00, a01,
225 a10, a11,
226 a20, a21 );
227 }
228 ~Matrix3x2Template() {}
229
230 using base_class::set;
231
232 void set( value_type a00, value_type a01,
233 value_type a10, value_type a11,
234 value_type a20, value_type a21 )
235 {
236 base_class::_mat[0][0]=a00; base_class::_mat[0][1]=a01;
237 base_class::_mat[1][0]=a10; base_class::_mat[1][1]=a11;
238 base_class::_mat[2][0]=a20; base_class::_mat[2][1]=a21;
239 }
240};
241
242template <typename T>
243class Matrix3Template : public MatrixTemplate<T, 3, 3>
244{
245 public:
246 typedef MatrixTemplate<T, 3, 3> base_class;
247 typedef typename base_class::value_type value_type;
248
249 public:
250 Matrix3Template() { base_class::reset(); }
251 Matrix3Template( const Matrix3Template& mat ) { set(mat.ptr()); }
252 Matrix3Template( value_type a00, value_type a01, value_type a02,
253 value_type a10, value_type a11, value_type a12,
254 value_type a20, value_type a21, value_type a22 )
255 {
256 set( a00, a01, a02,
257 a10, a11, a12,
258 a20, a21, a22 );
259 }
260 ~Matrix3Template() {}
261
262 using base_class::set;
263
264 void set( value_type a00, value_type a01, value_type a02,
265 value_type a10, value_type a11, value_type a12,
266 value_type a20, value_type a21, value_type a22 )
267 {
268 base_class::_mat[0][0]=a00; base_class::_mat[0][1]=a01; base_class::_mat[0][2]=a02;
269 base_class::_mat[1][0]=a10; base_class::_mat[1][1]=a11; base_class::_mat[1][2]=a12;
270 base_class::_mat[2][0]=a20; base_class::_mat[2][1]=a21; base_class::_mat[2][2]=a22;
271 }
272
273 void makeIdentity()
274 {
275 set( 1, 0, 0,
276 0, 1, 0,
277 0, 0, 1 );
278 }
279};
280
281template <typename T>
282class Matrix3x4Template : public MatrixTemplate<T, 3, 4>
283{
284 public:
285 typedef MatrixTemplate<T, 3, 4> base_class;
286 typedef typename base_class::value_type value_type;
287
288 public:
289 Matrix3x4Template() { base_class::reset(); }
290 Matrix3x4Template( const Matrix3x4Template& mat ) { set(mat.ptr()); }
291 Matrix3x4Template( value_type a00, value_type a01, value_type a02, value_type a03,
292 value_type a10, value_type a11, value_type a12, value_type a13,
293 value_type a20, value_type a21, value_type a22, value_type a23 )
294 {
295 set( a00, a01, a02, a03,
296 a10, a11, a12, a13,
297 a20, a21, a22, a23 );
298 }
299 ~Matrix3x4Template() {}
300
301 using base_class::set;
302
303 void set( value_type a00, value_type a01, value_type a02, value_type a03,
304 value_type a10, value_type a11, value_type a12, value_type a13,
305 value_type a20, value_type a21, value_type a22, value_type a23 )
306 {
307 base_class::_mat[0][0]=a00; base_class::_mat[0][1]=a01; base_class::_mat[0][2]=a02; base_class::_mat[0][3]=a03;
308 base_class::_mat[1][0]=a10; base_class::_mat[1][1]=a11; base_class::_mat[1][2]=a12; base_class::_mat[1][3]=a13;
309 base_class::_mat[2][0]=a20; base_class::_mat[2][1]=a21; base_class::_mat[2][2]=a22; base_class::_mat[2][3]=a23;
310 }
311};
312
313template <typename T>
314class Matrix4x2Template : public MatrixTemplate<T, 4, 2>
315{
316 public:
317 typedef MatrixTemplate<T, 4, 2> base_class;
318 typedef typename base_class::value_type value_type;
319
320 public:
321 Matrix4x2Template() { base_class::reset(); }
322 Matrix4x2Template( const Matrix4x2Template& mat ) { set(mat.ptr()); }
323 Matrix4x2Template( value_type a00, value_type a01,
324 value_type a10, value_type a11,
325 value_type a20, value_type a21,
326 value_type a30, value_type a31 )
327 {
328 set( a00, a01,
329 a10, a11,
330 a20, a21,
331 a30, a31 );
332 }
333 ~Matrix4x2Template() {}
334
335 using base_class::set;
336
337 void set( value_type a00, value_type a01,
338 value_type a10, value_type a11,
339 value_type a20, value_type a21,
340 value_type a30, value_type a31 )
341 {
342 base_class::_mat[0][0]=a00; base_class::_mat[0][1]=a01;
343 base_class::_mat[1][0]=a10; base_class::_mat[1][1]=a11;
344 base_class::_mat[2][0]=a20; base_class::_mat[2][1]=a21;
345 base_class::_mat[3][0]=a30; base_class::_mat[3][1]=a31;
346 }
347};
348
349template <typename T>
350class Matrix4x3Template : public MatrixTemplate<T, 4, 3>
351{
352 public:
353 typedef MatrixTemplate<T, 4, 3> base_class;
354 typedef typename base_class::value_type value_type;
355
356 public:
357 Matrix4x3Template() { base_class::reset(); }
358 Matrix4x3Template( const Matrix4x3Template& mat ) { set(mat.ptr()); }
359 Matrix4x3Template( value_type a00, value_type a01, value_type a02,
360 value_type a10, value_type a11, value_type a12,
361 value_type a20, value_type a21, value_type a22,
362 value_type a30, value_type a31, value_type a32 )
363 {
364 set( a00, a01, a02,
365 a10, a11, a12,
366 a20, a21, a22,
367 a30, a31, a32 );
368 }
369 ~Matrix4x3Template() {}
370
371 using base_class::set;
372
373 void set( value_type a00, value_type a01, value_type a02,
374 value_type a10, value_type a11, value_type a12,
375 value_type a20, value_type a21, value_type a22,
376 value_type a30, value_type a31, value_type a32 )
377 {
378 base_class::_mat[0][0]=a00; base_class::_mat[0][1]=a01; base_class::_mat[0][2]=a02;
379 base_class::_mat[1][0]=a10; base_class::_mat[1][1]=a11; base_class::_mat[1][2]=a12;
380 base_class::_mat[2][0]=a20; base_class::_mat[2][1]=a21; base_class::_mat[2][2]=a22;
381 base_class::_mat[3][0]=a30; base_class::_mat[3][1]=a31; base_class::_mat[3][2]=a32;
382 }
383};
384
385typedef Matrix2Template<float> Matrix2;
386typedef Matrix2x3Template<float> Matrix2x3;
387typedef Matrix2x4Template<float> Matrix2x4;
388
389typedef Matrix3x2Template<float> Matrix3x2;
390typedef Matrix3Template<float> Matrix3;
391typedef Matrix3x4Template<float> Matrix3x4;
392
393typedef Matrix4x2Template<float> Matrix4x2;
394typedef Matrix4x3Template<float> Matrix4x3;
395
396
397typedef Matrix2Template<double> Matrix2d;
398typedef Matrix2x3Template<double> Matrix2x3d;
399typedef Matrix2x4Template<double> Matrix2x4d;
400
401typedef Matrix3x2Template<double> Matrix3x2d;
402typedef Matrix3Template<double> Matrix3d;
403typedef Matrix3x4Template<double> Matrix3x4d;
404
405typedef Matrix4x2Template<double> Matrix4x2d;
406typedef Matrix4x3Template<double> Matrix4x3d;
407
408
409
410///////////////////////////////////////////////////////////////////////////
411
412/** Uniform encapsulates glUniform values */
413class OSG_EXPORT Uniform : public Object
414{
415 public:
416 enum Type {
417 FLOAT = GL_FLOAT,
418 FLOAT_VEC2 = GL_FLOAT_VEC2,
419 FLOAT_VEC3 = GL_FLOAT_VEC3,
420 FLOAT_VEC4 = GL_FLOAT_VEC4,
421
422 DOUBLE = GL_DOUBLE,
423 DOUBLE_VEC2 = GL_DOUBLE_VEC2,
424 DOUBLE_VEC3 = GL_DOUBLE_VEC3,
425 DOUBLE_VEC4 = GL_DOUBLE_VEC4,
426
427 INT = GL_INT,
428 INT_VEC2 = GL_INT_VEC2,
429 INT_VEC3 = GL_INT_VEC3,
430 INT_VEC4 = GL_INT_VEC4,
431
432 UNSIGNED_INT = GL_UNSIGNED_INT,
433 UNSIGNED_INT_VEC2 = GL_UNSIGNED_INT_VEC2_EXT,
434 UNSIGNED_INT_VEC3 = GL_UNSIGNED_INT_VEC3_EXT,
435 UNSIGNED_INT_VEC4 = GL_UNSIGNED_INT_VEC4_EXT,
436
437 BOOL = GL_BOOL,
438 BOOL_VEC2 = GL_BOOL_VEC2,
439 BOOL_VEC3 = GL_BOOL_VEC3,
440 BOOL_VEC4 = GL_BOOL_VEC4,
441
442 INT64 = GL_INT64_ARB,
443 UNSIGNED_INT64 = GL_UNSIGNED_INT64_ARB,
444
445 FLOAT_MAT2 = GL_FLOAT_MAT2,
446 FLOAT_MAT3 = GL_FLOAT_MAT3,
447 FLOAT_MAT4 = GL_FLOAT_MAT4,
448 FLOAT_MAT2x3 = GL_FLOAT_MAT2x3,
449 FLOAT_MAT2x4 = GL_FLOAT_MAT2x4,
450 FLOAT_MAT3x2 = GL_FLOAT_MAT3x2,
451 FLOAT_MAT3x4 = GL_FLOAT_MAT3x4,
452 FLOAT_MAT4x2 = GL_FLOAT_MAT4x2,
453 FLOAT_MAT4x3 = GL_FLOAT_MAT4x3,
454
455 DOUBLE_MAT2 = GL_DOUBLE_MAT2,
456 DOUBLE_MAT3 = GL_DOUBLE_MAT3,
457 DOUBLE_MAT4 = GL_DOUBLE_MAT4,
458 DOUBLE_MAT2x3 = GL_DOUBLE_MAT2x3,
459 DOUBLE_MAT2x4 = GL_DOUBLE_MAT2x4,
460 DOUBLE_MAT3x2 = GL_DOUBLE_MAT3x2,
461 DOUBLE_MAT3x4 = GL_DOUBLE_MAT3x4,
462 DOUBLE_MAT4x2 = GL_DOUBLE_MAT4x2,
463 DOUBLE_MAT4x3 = GL_DOUBLE_MAT4x3,
464
465 SAMPLER_1D = GL_SAMPLER_1D,
466 SAMPLER_2D = GL_SAMPLER_2D,
467 SAMPLER_3D = GL_SAMPLER_3D,
468 SAMPLER_CUBE = GL_SAMPLER_CUBE,
469 SAMPLER_1D_SHADOW = GL_SAMPLER_1D_SHADOW,
470 SAMPLER_2D_SHADOW = GL_SAMPLER_2D_SHADOW,
471 SAMPLER_1D_ARRAY = GL_SAMPLER_1D_ARRAY_EXT,
472 SAMPLER_2D_ARRAY = GL_SAMPLER_2D_ARRAY_EXT,
473 SAMPLER_CUBE_MAP_ARRAY = GL_SAMPLER_CUBE_MAP_ARRAY,
474 SAMPLER_1D_ARRAY_SHADOW = GL_SAMPLER_1D_ARRAY_SHADOW_EXT,
475 SAMPLER_2D_ARRAY_SHADOW = GL_SAMPLER_2D_ARRAY_SHADOW_EXT,
476 SAMPLER_2D_MULTISAMPLE = GL_SAMPLER_2D_MULTISAMPLE,
477 SAMPLER_2D_MULTISAMPLE_ARRAY = GL_SAMPLER_2D_MULTISAMPLE_ARRAY,
478 SAMPLER_CUBE_SHADOW = GL_SAMPLER_CUBE_SHADOW_EXT,
479 SAMPLER_CUBE_MAP_ARRAY_SHADOW = GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW,
480 SAMPLER_BUFFER = GL_SAMPLER_BUFFER_EXT,
481 SAMPLER_2D_RECT = GL_SAMPLER_2D_RECT,
482 SAMPLER_2D_RECT_SHADOW = GL_SAMPLER_2D_RECT_SHADOW,
483
484 INT_SAMPLER_1D = GL_INT_SAMPLER_1D_EXT,
485 INT_SAMPLER_2D = GL_INT_SAMPLER_2D_EXT,
486 INT_SAMPLER_3D = GL_INT_SAMPLER_3D_EXT,
487 INT_SAMPLER_CUBE = GL_INT_SAMPLER_CUBE_EXT,
488 INT_SAMPLER_1D_ARRAY = GL_INT_SAMPLER_1D_ARRAY_EXT,
489 INT_SAMPLER_2D_ARRAY = GL_INT_SAMPLER_2D_ARRAY_EXT,
490 INT_SAMPLER_CUBE_MAP_ARRAY = GL_INT_SAMPLER_CUBE_MAP_ARRAY,
491 INT_SAMPLER_2D_MULTISAMPLE = GL_INT_SAMPLER_2D_MULTISAMPLE,
492 INT_SAMPLER_2D_MULTISAMPLE_ARRAY = GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY,
493 INT_SAMPLER_BUFFER = GL_INT_SAMPLER_BUFFER_EXT,
494 INT_SAMPLER_2D_RECT = GL_INT_SAMPLER_2D_RECT_EXT,
495
496 UNSIGNED_INT_SAMPLER_1D = GL_UNSIGNED_INT_SAMPLER_1D_EXT,
497 UNSIGNED_INT_SAMPLER_2D = GL_UNSIGNED_INT_SAMPLER_2D_EXT,
498 UNSIGNED_INT_SAMPLER_3D = GL_UNSIGNED_INT_SAMPLER_3D_EXT,
499 UNSIGNED_INT_SAMPLER_CUBE = GL_UNSIGNED_INT_SAMPLER_CUBE_EXT,
500 UNSIGNED_INT_SAMPLER_1D_ARRAY = GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT,
501 UNSIGNED_INT_SAMPLER_2D_ARRAY = GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT,
502 UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY = GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY,
503 UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE = GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE,
504 UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY,
505 UNSIGNED_INT_SAMPLER_BUFFER = GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT,
506 UNSIGNED_INT_SAMPLER_2D_RECT = GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT,
507
508 IMAGE_1D = GL_IMAGE_1D,
509 IMAGE_2D = GL_IMAGE_2D,
510 IMAGE_3D = GL_IMAGE_3D,
511 IMAGE_2D_RECT = GL_IMAGE_2D_RECT,
512 IMAGE_CUBE = GL_IMAGE_CUBE,
513 IMAGE_BUFFER = GL_IMAGE_BUFFER,
514 IMAGE_1D_ARRAY = GL_IMAGE_1D_ARRAY,
515 IMAGE_2D_ARRAY = GL_IMAGE_2D_ARRAY,
516 IMAGE_CUBE_MAP_ARRAY = GL_IMAGE_CUBE_MAP_ARRAY,
517 IMAGE_2D_MULTISAMPLE = GL_IMAGE_2D_MULTISAMPLE,
518 IMAGE_2D_MULTISAMPLE_ARRAY = GL_IMAGE_2D_MULTISAMPLE_ARRAY,
519
520 INT_IMAGE_1D = GL_INT_IMAGE_1D,
521 INT_IMAGE_2D = GL_INT_IMAGE_2D,
522 INT_IMAGE_3D = GL_INT_IMAGE_3D,
523 INT_IMAGE_2D_RECT = GL_INT_IMAGE_2D_RECT,
524 INT_IMAGE_CUBE = GL_INT_IMAGE_CUBE,
525 INT_IMAGE_BUFFER = GL_INT_IMAGE_BUFFER,
526 INT_IMAGE_1D_ARRAY = GL_INT_IMAGE_1D_ARRAY,
527 INT_IMAGE_2D_ARRAY = GL_INT_IMAGE_2D_ARRAY,
528 INT_IMAGE_CUBE_MAP_ARRAY = GL_INT_IMAGE_CUBE_MAP_ARRAY,
529 INT_IMAGE_2D_MULTISAMPLE = GL_INT_IMAGE_2D_MULTISAMPLE,
530 INT_IMAGE_2D_MULTISAMPLE_ARRAY = GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY,
531
532 UNSIGNED_INT_IMAGE_1D = GL_UNSIGNED_INT_IMAGE_1D,
533 UNSIGNED_INT_IMAGE_2D = GL_UNSIGNED_INT_IMAGE_2D,
534 UNSIGNED_INT_IMAGE_3D = GL_UNSIGNED_INT_IMAGE_3D,
535 UNSIGNED_INT_IMAGE_2D_RECT = GL_UNSIGNED_INT_IMAGE_2D_RECT,
536 UNSIGNED_INT_IMAGE_CUBE = GL_UNSIGNED_INT_IMAGE_CUBE,
537 UNSIGNED_INT_IMAGE_BUFFER = GL_UNSIGNED_INT_IMAGE_BUFFER,
538 UNSIGNED_INT_IMAGE_1D_ARRAY = GL_UNSIGNED_INT_IMAGE_1D_ARRAY,
539 UNSIGNED_INT_IMAGE_2D_ARRAY = GL_UNSIGNED_INT_IMAGE_2D_ARRAY,
540 UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY = GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY,
541 UNSIGNED_INT_IMAGE_2D_MULTISAMPLE = GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE,
542 UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY = GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY,
543
544 UNDEFINED = 0x0
545 };
546
547 public:
548
549 Uniform();
550 Uniform( Type type, const std::string& name, int numElements=1 );
551
552 /** Copy constructor using CopyOp to manage deep vs shallow copy. */
553 Uniform(const Uniform& rhs, const CopyOp& copyop=CopyOp::SHALLOW_COPY);
554
555 META_Object(osg, Uniform);
556
557 /** Convert 'this' into a Uniform pointer if Object is a Uniform, otherwise return 0.
558 * Equivalent to dynamic_cast<Uniform*>(this).*/
559 virtual Uniform* asUniform() { return this; }
560
561 /** convert 'const this' into a const Uniform pointer if Object is a Uniform, otherwise return 0.
562 * Equivalent to dynamic_cast<const Uniform*>(this).*/
563 virtual const Uniform* asUniform() const { return this; }
564
565
566 /** Set the type of glUniform, ensuring it is only set once.*/
567 bool setType( Type t );
568
569 /** Get the type of glUniform as enum. */
570 Type getType() const { return _type; }
571
572 /** Set the name of the glUniform, ensuring it is only set once.*/
573 virtual void setName( const std::string& name );
574
575 /** Set the length of a uniform, ensuring it is only set once (1==scalar)*/
576 void setNumElements( unsigned int numElements );
577
578 /** Get the number of GLSL elements of the osg::Uniform (1==scalar) */
579 unsigned int getNumElements() const { return _numElements; }
580
581 /** Get the number of elements required for the internal data array.
582 * Returns 0 if the osg::Uniform is not properly configured. */
583 unsigned int getInternalArrayNumElements() const;
584
585 /** Return the name of a Type enum as string. */
586 static const char* getTypename( Type t );
587
588 /** Return the number of components for a GLSL type. */
589 static int getTypeNumComponents( Type t );
590
591 /** Return the Type enum of a Uniform typename string */
592 static Uniform::Type getTypeId( const std::string& tname );
593
594 /** Return the GL API type corresponding to a GLSL type */
595 static Type getGlApiType( Type t );
596
597 /** Return the internal data array type corresponding to a GLSL type */
598 static GLenum getInternalArrayType( Type t );
599
600 /** Return the number that the name maps to uniquely */
601 static unsigned int getNameID(const std::string& name);
602
603 /** convenient scalar (non-array) constructors w/ assignment */
604 explicit Uniform( const char* name, float f );
605 explicit Uniform( const char* name, double d );
606 explicit Uniform( const char* name, int i );
607 explicit Uniform( const char* name, unsigned int ui );
608 explicit Uniform( const char* name, bool b );
609 explicit Uniform( const char* name, unsigned long long ull);
610 explicit Uniform( const char* name, long long ll );
611 Uniform( const char* name, const osg::Vec2& v2 );
612 Uniform( const char* name, const osg::Vec3& v3 );
613 Uniform( const char* name, const osg::Vec4& v4 );
614 Uniform( const char* name, const osg::Vec2d& v2 );
615 Uniform( const char* name, const osg::Vec3d& v3 );
616 Uniform( const char* name, const osg::Vec4d& v4 );
617 Uniform( const char* name, const osg::Matrix2& m2 );
618 Uniform( const char* name, const osg::Matrix3& m3 );
619 Uniform( const char* name, const osg::Matrixf& m4 );
620 Uniform( const char* name, const osg::Matrix2x3& m2x3 );
621 Uniform( const char* name, const osg::Matrix2x4& m2x4 );
622 Uniform( const char* name, const osg::Matrix3x2& m3x2 );
623 Uniform( const char* name, const osg::Matrix3x4& m3x4 );
624 Uniform( const char* name, const osg::Matrix4x2& m4x2 );
625 Uniform( const char* name, const osg::Matrix4x3& m4x3 );
626 Uniform( const char* name, const osg::Matrix2d& m2 );
627 Uniform( const char* name, const osg::Matrix3d& m3 );
628 Uniform( const char* name, const osg::Matrixd& m4 );
629 Uniform( const char* name, const osg::Matrix2x3d& m2x3 );
630 Uniform( const char* name, const osg::Matrix2x4d& m2x4 );
631 Uniform( const char* name, const osg::Matrix3x2d& m3x2 );
632 Uniform( const char* name, const osg::Matrix3x4d& m3x4 );
633 Uniform( const char* name, const osg::Matrix4x2d& m4x2 );
634 Uniform( const char* name, const osg::Matrix4x3d& m4x3 );
635 Uniform( const char* name, int i0, int i1 );
636 Uniform( const char* name, int i0, int i1, int i2 );
637 Uniform( const char* name, int i0, int i1, int i2, int i3 );
638 Uniform( const char* name, unsigned int ui0, unsigned int ui1 );
639 Uniform( const char* name, unsigned int ui0, unsigned int ui1, unsigned int ui2 );
640 Uniform( const char* name, unsigned int ui0, unsigned int ui1, unsigned int ui2, unsigned int ui3 );
641 Uniform( const char* name, bool b0, bool b1 );
642 Uniform( const char* name, bool b0, bool b1, bool b2 );
643 Uniform( const char* name, bool b0, bool b1, bool b2, bool b3 );
644
645 /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs. */
646 virtual int compare(const Uniform& rhs) const;
647 virtual int compareData(const Uniform& rhs) const;
648
649 bool operator < (const Uniform& rhs) const { return compare(rhs)<0; }
650 bool operator == (const Uniform& rhs) const { return compare(rhs)==0; }
651 bool operator != (const Uniform& rhs) const { return compare(rhs)!=0; }
652
653 void copyData( const Uniform& rhs );
654
655
656 /** A vector of osg::StateSet pointers which is used to store the parent(s) of this Uniform, the parents could be osg::Node or osg::Drawable.*/
657 typedef std::vector<StateSet*> ParentList;
658
659 /** Get the parent list of this Uniform. */
660 inline const ParentList& getParents() const { return _parents; }
661
662 /** Get the a copy of parent list of node. A copy is returned to
663 * prevent modification of the parent list.*/
664 inline ParentList getParents() { return _parents; }
665
666 inline StateSet* getParent(unsigned int i) { return _parents[i]; }
667 /**
668 * Get a single const parent of this Uniform.
669 * @param i index of the parent to get.
670 * @return the parent i.
671 */
672 inline const StateSet* getParent(unsigned int i) const { return _parents[i]; }
673
674 /**
675 * Get the number of parents of this Uniform.
676 * @return the number of parents of this Uniform.
677 */
678 inline unsigned int getNumParents() const { return static_cast<unsigned int>(_parents.size()); }
679
680
681 /** convenient scalar (non-array) value assignment */
682 bool set( float f );
683 bool set( double d );
684 bool set( int i );
685 bool set( unsigned int ui );
686 bool set( bool b );
687 bool set( unsigned long long ull );
688 bool set( long long ll );
689 bool set( const osg::Vec2& v2 );
690 bool set( const osg::Vec3& v3 );
691 bool set( const osg::Vec4& v4 );
692 bool set( const osg::Vec2d& v2 );
693 bool set( const osg::Vec3d& v3 );
694 bool set( const osg::Vec4d& v4 );
695 bool set( const osg::Matrix2& m2 );
696 bool set( const osg::Matrix3& m3 );
697 bool set( const osg::Matrixf& m4 );
698 bool set( const osg::Matrix2x3& m2x3 );
699 bool set( const osg::Matrix2x4& m2x4 );
700 bool set( const osg::Matrix3x2& m3x2 );
701 bool set( const osg::Matrix3x4& m3x4 );
702 bool set( const osg::Matrix4x2& m4x2 );
703 bool set( const osg::Matrix4x3& m4x3 );
704 bool set( const osg::Matrix2d& m2 );
705 bool set( const osg::Matrix3d& m3 );
706 bool set( const osg::Matrixd& m4 );
707 bool set( const osg::Matrix2x3d& m2x3 );
708 bool set( const osg::Matrix2x4d& m2x4 );
709 bool set( const osg::Matrix3x2d& m3x2 );
710 bool set( const osg::Matrix3x4d& m3x4 );
711 bool set( const osg::Matrix4x2d& m4x2 );
712 bool set( const osg::Matrix4x3d& m4x3 );
713 bool set( int i0, int i1 );
714 bool set( int i0, int i1, int i2 );
715 bool set( int i0, int i1, int i2, int i3 );
716 bool set( unsigned int ui0, unsigned int ui1 );
717 bool set( unsigned int ui0, unsigned int ui1, unsigned int ui2 );
718 bool set( unsigned int ui0, unsigned int ui1, unsigned int ui2, unsigned int ui3 );
719 bool set( bool b0, bool b1 );
720 bool set( bool b0, bool b1, bool b2 );
721 bool set( bool b0, bool b1, bool b2, bool b3 );
722
723 /** convenient scalar (non-array) value query */
724 bool get( float& f ) const;
725 bool get( double& d ) const;
726 bool get( int& i ) const;
727 bool get( unsigned int& ui ) const;
728 bool get( bool& b ) const;
729 bool get( unsigned long long & ull ) const;
730 bool get( long long& ll ) const;
731 bool get( osg::Vec2& v2 ) const;
732 bool get( osg::Vec3& v3 ) const;
733 bool get( osg::Vec4& v4 ) const;
734 bool get( osg::Vec2d& v2 ) const;
735 bool get( osg::Vec3d& v3 ) const;
736 bool get( osg::Vec4d& v4 ) const;
737 bool get( osg::Matrix2& m2 ) const;
738 bool get( osg::Matrix3& m3 ) const;
739 bool get( osg::Matrixf& m4 ) const;
740 bool get( osg::Matrix2x3& m2x3 ) const;
741 bool get( osg::Matrix2x4& m2x4 ) const;
742 bool get( osg::Matrix3x2& m3x2 ) const;
743 bool get( osg::Matrix3x4& m3x4 ) const;
744 bool get( osg::Matrix4x2& m4x2 ) const;
745 bool get( osg::Matrix4x3& m4x3 ) const;
746 bool get( osg::Matrix2d& m2 ) const;
747 bool get( osg::Matrix3d& m3 ) const;
748 bool get( osg::Matrixd& m4 ) const;
749 bool get( osg::Matrix2x3d& m2x3 ) const;
750 bool get( osg::Matrix2x4d& m2x4 ) const;
751 bool get( osg::Matrix3x2d& m3x2 ) const;
752 bool get( osg::Matrix3x4d& m3x4 ) const;
753 bool get( osg::Matrix4x2d& m4x2 ) const;
754 bool get( osg::Matrix4x3d& m4x3 ) const;
755 bool get( int& i0, int& i1 ) const;
756 bool get( int& i0, int& i1, int& i2 ) const;
757 bool get( int& i0, int& i1, int& i2, int& i3 ) const;
758 bool get( unsigned int& ui0, unsigned int& ui1 ) const;
759 bool get( unsigned int& ui0, unsigned int& ui1, unsigned int& ui2 ) const;
760 bool get( unsigned int& ui0, unsigned int& ui1, unsigned int& ui2, unsigned int& ui3 ) const;
761 bool get( bool& b0, bool& b1 ) const;
762 bool get( bool& b0, bool& b1, bool& b2 ) const;
763 bool get( bool& b0, bool& b1, bool& b2, bool& b3 ) const;
764
765 /** value assignment for array uniforms */
766 bool setElement( unsigned int index, float f );
767 bool setElement( unsigned int index, double d );
768 bool setElement( unsigned int index, int i );
769 bool setElement( unsigned int index, unsigned int ui );
770 bool setElement( unsigned int index, bool b );
771 bool setElement( unsigned int index, unsigned long long ull );
772 bool setElement( unsigned int index, long long ll );
773 bool setElement( unsigned int index, const osg::Vec2& v2 );
774 bool setElement( unsigned int index, const osg::Vec3& v3 );
775 bool setElement( unsigned int index, const osg::Vec4& v4 );
776 bool setElement( unsigned int index, const osg::Vec2d& v2 );
777 bool setElement( unsigned int index, const osg::Vec3d& v3 );
778 bool setElement( unsigned int index, const osg::Vec4d& v4 );
779 bool setElement( unsigned int index, const osg::Matrix2& m2 );
780 bool setElement( unsigned int index, const osg::Matrix3& m3 );
781 bool setElement( unsigned int index, const osg::Matrixf& m4 );
782 bool setElement( unsigned int index, const osg::Matrix2x3& m2x3 );
783 bool setElement( unsigned int index, const osg::Matrix2x4& m2x4 );
784 bool setElement( unsigned int index, const osg::Matrix3x2& m3x2 );
785 bool setElement( unsigned int index, const osg::Matrix3x4& m3x4 );
786 bool setElement( unsigned int index, const osg::Matrix4x2& m4x2 );
787 bool setElement( unsigned int index, const osg::Matrix4x3& m4x3 );
788 bool setElement( unsigned int index, const osg::Matrix2d& m2 );
789 bool setElement( unsigned int index, const osg::Matrix3d& m3 );
790 bool setElement( unsigned int index, const osg::Matrixd& m4 );
791 bool setElement( unsigned int index, const osg::Matrix2x3d& m2x3 );
792 bool setElement( unsigned int index, const osg::Matrix2x4d& m2x4 );
793 bool setElement( unsigned int index, const osg::Matrix3x2d& m3x2 );
794 bool setElement( unsigned int index, const osg::Matrix3x4d& m3x4 );
795 bool setElement( unsigned int index, const osg::Matrix4x2d& m4x2 );
796 bool setElement( unsigned int index, const osg::Matrix4x3d& m4x3 );
797 bool setElement( unsigned int index, int i0, int i1 );
798 bool setElement( unsigned int index, int i0, int i1, int i2 );
799 bool setElement( unsigned int index, int i0, int i1, int i2, int i3 );
800 bool setElement( unsigned int index, unsigned int ui0, unsigned int ui1 );
801 bool setElement( unsigned int index, unsigned int ui0, unsigned int ui1, unsigned int ui2 );
802 bool setElement( unsigned int index, unsigned int ui0, unsigned int ui1, unsigned int ui2, unsigned int ui3 );
803 bool setElement( unsigned int index, bool b0, bool b1 );
804 bool setElement( unsigned int index, bool b0, bool b1, bool b2 );
805 bool setElement( unsigned int index, bool b0, bool b1, bool b2, bool b3 );
806
807 /** value query for array uniforms */
808 bool getElement( unsigned int index, float& f ) const;
809 bool getElement( unsigned int index, double& d ) const;
810 bool getElement( unsigned int index, int& i ) const;
811 bool getElement( unsigned int index, unsigned int& ui ) const;
812 bool getElement( unsigned int index, bool& b ) const;
813 bool getElement( unsigned int index, unsigned long long & ull ) const;
814 bool getElement( unsigned int index, long long& ll ) const;
815 bool getElement( unsigned int index, osg::Vec2& v2 ) const;
816 bool getElement( unsigned int index, osg::Vec3& v3 ) const;
817 bool getElement( unsigned int index, osg::Vec4& v4 ) const;
818 bool getElement( unsigned int index, osg::Vec2d& v2 ) const;
819 bool getElement( unsigned int index, osg::Vec3d& v3 ) const;
820 bool getElement( unsigned int index, osg::Vec4d& v4 ) const;
821 bool getElement( unsigned int index, osg::Matrix2& m2 ) const;
822 bool getElement( unsigned int index, osg::Matrix3& m3 ) const;
823 bool getElement( unsigned int index, osg::Matrixf& m4 ) const;
824 bool getElement( unsigned int index, osg::Matrix2x3& m2x3 ) const;
825 bool getElement( unsigned int index, osg::Matrix2x4& m2x4 ) const;
826 bool getElement( unsigned int index, osg::Matrix3x2& m3x2 ) const;
827 bool getElement( unsigned int index, osg::Matrix3x4& m3x4 ) const;
828 bool getElement( unsigned int index, osg::Matrix4x2& m4x2 ) const;
829 bool getElement( unsigned int index, osg::Matrix4x3& m4x3 ) const;
830 bool getElement( unsigned int index, osg::Matrix2d& m2 ) const;
831 bool getElement( unsigned int index, osg::Matrix3d& m3 ) const;
832 bool getElement( unsigned int index, osg::Matrixd& m4 ) const;
833 bool getElement( unsigned int index, osg::Matrix2x3d& m2x3 ) const;
834 bool getElement( unsigned int index, osg::Matrix2x4d& m2x4 ) const;
835 bool getElement( unsigned int index, osg::Matrix3x2d& m3x2 ) const;
836 bool getElement( unsigned int index, osg::Matrix3x4d& m3x4 ) const;
837 bool getElement( unsigned int index, osg::Matrix4x2d& m4x2 ) const;
838 bool getElement( unsigned int index, osg::Matrix4x3d& m4x3 ) const;
839 bool getElement( unsigned int index, int& i0, int& i1 ) const;
840 bool getElement( unsigned int index, int& i0, int& i1, int& i2 ) const;
841 bool getElement( unsigned int index, int& i0, int& i1, int& i2, int& i3 ) const;
842 bool getElement( unsigned int index, unsigned int& ui0, unsigned int& ui1 ) const;
843 bool getElement( unsigned int index, unsigned int& ui0, unsigned int& ui1, unsigned int& ui2 ) const;
844 bool getElement( unsigned int index, unsigned int& ui0, unsigned int& ui1, unsigned int& ui2, unsigned int& ui3 ) const;
845 bool getElement( unsigned int index, bool& b0, bool& b1 ) const;
846 bool getElement( unsigned int index, bool& b0, bool& b1, bool& b2 ) const;
847 bool getElement( unsigned int index, bool& b0, bool& b1, bool& b2, bool& b3 ) const;
848
849
850 /** provide typedef for backwards compatibility to OSG-3.2 and other previous versions. */
851 typedef UniformCallback Callback;
852
853
854 /** Set the UpdateCallback which allows users to attach customize the updating of an object during the update traversal.*/
855 void setUpdateCallback(UniformCallback* uc);
856
857 /** Get the non const UpdateCallback.*/
858 UniformCallback* getUpdateCallback() { return _updateCallback.get(); }
859
860 /** Get the const UpdateCallback.*/
861 const UniformCallback* getUpdateCallback() const { return _updateCallback.get(); }
862
863 /** Set the EventCallback which allows users to attach customize the updating of an object during the Event traversal.*/
864 void setEventCallback(UniformCallback* ec);
865
866 /** Get the non const EventCallback.*/
867 UniformCallback* getEventCallback() { return _eventCallback.get(); }
868
869 /** Get the const EventCallback.*/
870 const UniformCallback* getEventCallback() const { return _eventCallback.get(); }
871
872 /** Increment the modified count on the Uniform so Programs watching it know it update themselves.
873 * NOTE: automatically called during osg::Uniform::set*();
874 * you must call if modifying the internal data array directly. */
875 inline void dirty() { ++_modifiedCount; }
876
877 /** Set the internal data array for a osg::Uniform */
878 bool setArray( FloatArray* array );
879 bool setArray( DoubleArray* array );
880 bool setArray( IntArray* array );
881 bool setArray( UIntArray* array );
882 bool setArray( UInt64Array* array );
883 bool setArray( Int64Array* array );
884 /** Get the internal data array for a float osg::Uniform. */
885 FloatArray* getFloatArray() { return _floatArray.get(); }
886 const FloatArray* getFloatArray() const { return _floatArray.get(); }
887
888 /** Get the internal data array for a double osg::Uniform. */
889 DoubleArray* getDoubleArray() { return _doubleArray.get(); }
890 const DoubleArray* getDoubleArray() const { return _doubleArray.get(); }
891
892 /** Get the internal data array for an int osg::Uniform. */
893 IntArray* getIntArray() { return _intArray.get(); }
894 const IntArray* getIntArray() const { return _intArray.get(); }
895
896 /** Get the internal data array for an unsigned int osg::Uniform. */
897 UIntArray* getUIntArray() { return _uintArray.get(); }
898 const UIntArray* getUIntArray() const { return _uintArray.get(); }
899
900 /** Get the internal data array for an unsigned int osg::Uniform. */
901 UInt64Array* getUInt64Array() { return _uint64Array.get(); }
902 const UInt64Array* getUInt64Array() const { return _uint64Array.get(); }
903
904 /** Get the internal data array for an unsigned int osg::Uniform. */
905 Int64Array* getInt64Array() { return _int64Array.get(); }
906 const Int64Array* getInt64Array() const { return _int64Array.get(); }
907
908 inline void setModifiedCount(unsigned int mc) { _modifiedCount = mc; }
909 inline unsigned int getModifiedCount() const { return _modifiedCount; }
910
911 /** Get the number that the Uniform's name maps to uniquely */
912 unsigned int getNameID() const;
913
914 void apply(const GLExtensions* ext, GLint location) const;
915
916
917 protected:
918
919 virtual ~Uniform();
920 Uniform& operator=(const Uniform&) { return *this; }
921
922 bool isCompatibleType( Type t ) const;
923 // for backward compatibility only
924 // see getElement(index, osg::Matrixd &)
925 // see setElement(index, osg::Matrixd &)
926 bool isCompatibleType( Type t1, Type t2 ) const;
927 bool isScalar() const { return _numElements==1; }
928 void allocateDataArray();
929
930 void addParent(osg::StateSet* object);
931 void removeParent(osg::StateSet* object);
932
933 ParentList _parents;
934 friend class osg::StateSet;
935
936 Type _type;
937 unsigned int _numElements;
938 unsigned int _nameID;
939
940
941 // The internal data for osg::Uniforms are stored as an array of
942 // getInternalArrayType() of length getInternalArrayNumElements().
943 ref_ptr<FloatArray> _floatArray;
944 ref_ptr<DoubleArray> _doubleArray;
945 ref_ptr<IntArray> _intArray;
946 ref_ptr<UIntArray> _uintArray;
947 ref_ptr<Int64Array> _int64Array;
948 ref_ptr<UInt64Array> _uint64Array;
949
950 ref_ptr<UniformCallback> _updateCallback;
951 ref_ptr<UniformCallback> _eventCallback;
952
953 unsigned int _modifiedCount;
954};
955
956}
957
958#endif