1 #include "vtkOpenGLUniforms.h"
2 #include "vtkObjectFactory.h"
3 #include "vtkShaderProgram.h"
4 #include "vtkMatrix3x3.h"
5 #include "vtkMatrix4x4.h"
6 #include <vector>
7 #include <cstring>
8 
9 vtkStandardNewMacro(vtkOpenGLUniforms)
10 
11 // temporary patch: Some Android builds don't have std::to_string
12 #include <sstream>
13 namespace patch
14 {
15     template < typename T >
to_string(const T & n)16     std::string to_string( const T& n )
17     {
18         std::ostringstream stm ;
19         stm << n ;
20         return stm.str() ;
21     }
22 }
23 
24 class vtkCustomUniform
25 {
26 public:
~vtkCustomUniform()27     virtual ~vtkCustomUniform() {}
GetGlslDec(const std::string &)28     virtual std::string GetGlslDec( const std::string & ) { return std::string(); }
SetUniform(const char *,vtkShaderProgram *)29     virtual bool SetUniform( const char *, vtkShaderProgram * ) { return false; }
PrintSelf(const char *,ostream &,vtkIndent)30     virtual void PrintSelf( const char *, ostream&, vtkIndent ) {}
31 };
32 
33 class vtkCustomUniformi : public vtkCustomUniform
34 {
35 public:
vtkCustomUniformi(int val)36     vtkCustomUniformi( int val ) { value = val; }
SetValue(int val)37     void SetValue( int val ) { value = val; }
GetGlslDec(const std::string & name)38     std::string GetGlslDec( const std::string & name ) override { return std::string("uniform int ") + name + ";\n"; }
SetUniform(const char * name,vtkShaderProgram * p)39     bool SetUniform( const char * name, vtkShaderProgram * p ) override { return p->SetUniformi( name, value ); }
PrintSelf(const char * name,ostream & os,vtkIndent indent)40     void PrintSelf( const char * name, ostream& os, vtkIndent indent ) override
41     { os << indent << name << ": " << value << endl;}
42 protected:
43     int value;
44 };
45 
46 class vtkCustomUniformf : public vtkCustomUniform
47 {
48 public:
vtkCustomUniformf(float val)49     vtkCustomUniformf( float val ) { value = val; }
SetValue(float val)50     void SetValue( float val ) { value = val; }
GetGlslDec(const std::string & name)51     std::string GetGlslDec( const std::string & name ) override { return std::string("uniform float ") + name + ";\n"; }
SetUniform(const char * name,vtkShaderProgram * p)52     bool SetUniform( const char * name, vtkShaderProgram * p ) override { return p->SetUniformf( name, value ); }
PrintSelf(const char * name,ostream & os,vtkIndent indent)53     void PrintSelf( const char * name, ostream& os, vtkIndent indent ) override
54     { os << indent << name << ": " << value << endl;}
55 protected:
56     float value;
57 };
58 
59 class vtkCustomUniform2i : public vtkCustomUniform
60 {
61 public:
vtkCustomUniform2i(const int val[2])62     vtkCustomUniform2i( const int val[2] ) { value[0] = val[0]; value[1] = val[1]; }
SetValue(const int val[2])63     void SetValue( const int val[2] ) { value[0] = val[0]; value[1] = val[1]; }
GetGlslDec(const std::string & name)64     std::string GetGlslDec( const std::string & name ) override { return std::string("uniform ivec2 ") + name + ";\n"; }
SetUniform(const char * name,vtkShaderProgram * p)65     bool SetUniform( const char * name, vtkShaderProgram * p ) override { return p->SetUniform2i( name, value ); }
PrintSelf(const char * name,ostream & os,vtkIndent indent)66     void PrintSelf( const char * name, ostream& os, vtkIndent indent ) override
67     { os << indent << name << ": ( " << value[0] << ", " << value[1] << " )" << endl;}
68 protected:
69     int value[2];
70 };
71 
72 class vtkCustomUniform2f : public vtkCustomUniform
73 {
74 public:
vtkCustomUniform2f(const float val[2])75     vtkCustomUniform2f( const float val[2] ) { value[0] = val[0]; value[1] = val[1]; }
SetValue(const float val[2])76     void SetValue( const float val[2] ) { value[0] = val[0]; value[1] = val[1]; }
GetGlslDec(const std::string & name)77     std::string GetGlslDec( const std::string & name ) override { return std::string("uniform vec2 ") + name + ";\n"; }
SetUniform(const char * name,vtkShaderProgram * p)78     bool SetUniform( const char * name, vtkShaderProgram * p ) override { return p->SetUniform2f( name, value ); }
PrintSelf(const char * name,ostream & os,vtkIndent indent)79     void PrintSelf( const char * name, ostream& os, vtkIndent indent ) override
80     { os << indent << name << ": ( " << value[0] << ", " << value[1] << " )" << endl;}
81 protected:
82     float value[2];
83 };
84 
85 class vtkCustomUniform3f : public vtkCustomUniform
86 {
87 public:
vtkCustomUniform3f(const float val[3])88     vtkCustomUniform3f( const float val[3] ) { value[0] = val[0]; value[1] = val[1]; value[2] = val[2]; }
SetValue(const float val[3])89     void SetValue( const float val[3] ) { value[0] = val[0]; value[1] = val[1]; value[2] = val[2]; }
GetGlslDec(const std::string & name)90     std::string GetGlslDec( const std::string & name ) override { return std::string("uniform vec3 ") + name + ";\n"; }
SetUniform(const char * name,vtkShaderProgram * p)91     bool SetUniform( const char * name, vtkShaderProgram * p ) override { return p->SetUniform3f( name, value ); }
PrintSelf(const char * name,ostream & os,vtkIndent indent)92     void PrintSelf( const char * name, ostream& os, vtkIndent indent ) override
93     { os << indent << name << ": ( " << value[0] << ", " << value[1] << ", " << value[2] << " )" << endl;}
94 protected:
95     float value[3];
96 };
97 
98 class vtkCustomUniform3d : public vtkCustomUniform
99 {
100 public:
vtkCustomUniform3d(const double val[3])101     vtkCustomUniform3d( const double val[3] ) { value[0] = val[0]; value[1] = val[1]; value[2] = val[2]; }
SetValue(const double val[3])102     void SetValue( const double val[3] ) { value[0] = val[0]; value[1] = val[1]; value[2] = val[2]; }
GetGlslDec(const std::string & name)103     std::string GetGlslDec( const std::string & name ) override { return std::string("uniform vec3 ") + name + ";\n"; }
SetUniform(const char * name,vtkShaderProgram * p)104     bool SetUniform( const char * name, vtkShaderProgram * p ) override { return p->SetUniform3f( name, value ); }
PrintSelf(const char * name,ostream & os,vtkIndent indent)105     void PrintSelf( const char * name, ostream& os, vtkIndent indent ) override
106     { os << indent << name << ": ( " << value[0] << ", " << value[1] << ", " << value[2] << " )" << endl;}
107 protected:
108     double value[3];
109 };
110 
111 class vtkCustomUniform4f : public vtkCustomUniform
112 {
113 public:
vtkCustomUniform4f(const float val[4])114     vtkCustomUniform4f( const float val[4] ) { value[0] = val[0]; value[1] = val[1]; value[2] = val[2]; value[3] = val[3]; }
SetValue(const float val[4])115     void SetValue( const float val[4] ) { value[0] = val[0]; value[1] = val[1]; value[2] = val[2]; value[3] = val[3]; }
GetGlslDec(const std::string & name)116     std::string GetGlslDec( const std::string & name ) override { return std::string("uniform vec4 ") + name + ";\n"; }
SetUniform(const char * name,vtkShaderProgram * p)117     bool SetUniform( const char * name, vtkShaderProgram * p ) override { return p->SetUniform4f( name, value ); }
PrintSelf(const char * name,ostream & os,vtkIndent indent)118     void PrintSelf( const char * name, ostream& os, vtkIndent indent ) override
119     { os << indent << name << ": ( " << value[0] << ", " << value[1] << ", " << value[2] << ", " << value[3] << " )" << endl;}
120 protected:
121     float value[4];
122 };
123 
124 class vtkCustomUniform3uc : public vtkCustomUniform
125 {
126 public:
vtkCustomUniform3uc(const unsigned char v[3])127     vtkCustomUniform3uc( const unsigned char v[3] ) { value[0] = v[0]; value[1] = v[1]; value[2] = v[2]; }
SetValue(const unsigned char v[3])128     void SetValue( const unsigned char v[3] ) { value[0] = v[0]; value[1] = v[1]; value[2] = v[2]; }
GetGlslDec(const std::string & name)129     std::string GetGlslDec( const std::string & name ) override { return std::string("uniform vec3 ") + name + ";\n"; }
SetUniform(const char * name,vtkShaderProgram * p)130     bool SetUniform( const char * name, vtkShaderProgram * p ) override { return p->SetUniform3uc( name, value ); }
PrintSelf(const char * name,ostream & os,vtkIndent indent)131     void PrintSelf( const char * name, ostream& os, vtkIndent indent ) override
132     { os << indent << name << ": ( " << value[0] << ", " << value[1] << ", " << value[2] << " )" << endl;}
133 protected:
134     unsigned char value[3];
135 };
136 
137 class vtkCustomUniform4uc : public vtkCustomUniform
138 {
139 public:
vtkCustomUniform4uc(const unsigned char v[4])140     vtkCustomUniform4uc( const unsigned char v[4] ) { value[0] = v[0]; value[1] = v[1]; value[2] = v[2]; value[3] = v[3]; }
SetValue(const unsigned char v[4])141     void SetValue( const unsigned char v[4] ) { value[0] = v[0]; value[1] = v[1]; value[2] = v[2]; value[3] = v[3]; }
GetGlslDec(const std::string & name)142     std::string GetGlslDec( const std::string & name ) override { return std::string("uniform vec4 ") + name + ";\n"; }
SetUniform(const char * name,vtkShaderProgram * p)143     bool SetUniform( const char * name, vtkShaderProgram * p ) override { return p->SetUniform4uc( name, value ); }
PrintSelf(const char * name,ostream & os,vtkIndent indent)144     void PrintSelf( const char * name, ostream& os, vtkIndent indent ) override
145     { os << indent << name << ": ( " << value[0] << ", " << value[1] << ", " << value[2] << ", " << value[3] << " )" << endl;}
146 protected:
147     unsigned char value[4];
148 };
149 
150 class vtkCustomUniformVtkMatrix3x3 : public vtkCustomUniform
151 {
152 public:
vtkCustomUniformVtkMatrix3x3(vtkMatrix3x3 * v)153     vtkCustomUniformVtkMatrix3x3( vtkMatrix3x3 * v ) { value = vtkMatrix3x3::New(); value->DeepCopy( v ); }
SetValue(vtkMatrix3x3 * v)154     void SetValue( vtkMatrix3x3 * v ) { value = vtkMatrix3x3::New(); value->DeepCopy( v ); }
~vtkCustomUniformVtkMatrix3x3()155     virtual ~vtkCustomUniformVtkMatrix3x3() override { value->Delete(); }
GetGlslDec(const std::string & name)156     std::string GetGlslDec( const std::string & name ) override { return std::string("uniform mat3 ") + name + ";\n"; }
SetUniform(const char * name,vtkShaderProgram * p)157     bool SetUniform( const char * name, vtkShaderProgram * p ) override { return p->SetUniformMatrix( name, value ); }
PrintSelf(const char * name,ostream & os,vtkIndent indent)158     void PrintSelf( const char * name, ostream& os, vtkIndent indent ) override
159     { os << indent << name << endl; value->PrintSelf(os,indent); os << endl;}
160 protected:
161     vtkMatrix3x3 *value;
162 };
163 
164 class vtkCustomUniformVtkMatrix4x4 : public vtkCustomUniform
165 {
166 public:
vtkCustomUniformVtkMatrix4x4(vtkMatrix4x4 * v)167     vtkCustomUniformVtkMatrix4x4( vtkMatrix4x4 * v ) { value = vtkMatrix4x4::New(); value->DeepCopy( v ); }
SetValue(vtkMatrix4x4 * v)168     void SetValue( vtkMatrix4x4 * v ) { value = vtkMatrix4x4::New(); value->DeepCopy( v ); }
~vtkCustomUniformVtkMatrix4x4()169     virtual ~vtkCustomUniformVtkMatrix4x4() override { value->Delete(); }
GetGlslDec(const std::string & name)170     std::string GetGlslDec( const std::string & name ) override { return std::string("uniform mat4 ") + name + ";\n"; }
SetUniform(const char * name,vtkShaderProgram * p)171     bool SetUniform( const char * name, vtkShaderProgram * p ) override { return p->SetUniformMatrix( name, value ); }
PrintSelf(const char * name,ostream & os,vtkIndent indent)172     void PrintSelf( const char * name, ostream& os, vtkIndent indent ) override
173     { os << indent << name << endl; value->PrintSelf(os,indent); os << endl;}
174 protected:
175     vtkMatrix4x4 *value;
176 };
177 
178 class vtkCustomUniformMatrix3x3 : public vtkCustomUniform
179 {
180 public:
vtkCustomUniformMatrix3x3(float * v)181     vtkCustomUniformMatrix3x3( float * v ) { std::memcpy( value, v, sizeof value ); }
SetValue(float * v)182     void SetValue( float * v ) { std::memcpy( value, v, sizeof value ); }
GetGlslDec(const std::string & name)183     std::string GetGlslDec( const std::string & name ) override { return std::string("uniform mat3 ") + name + ";\n"; }
SetUniform(const char * name,vtkShaderProgram * p)184     bool SetUniform( const char * name, vtkShaderProgram * p ) override { return p->SetUniformMatrix3x3( name, value ); }
PrintSelf(const char * name,ostream & os,vtkIndent indent)185     void PrintSelf( const char * name, ostream& os, vtkIndent indent ) override
186     {
187         os << indent << name << ": " << endl;
188         for( int i = 0; i < 3; ++i )
189         {
190             os << indent << "( ";
191             for( int j = 0; j < 3; ++j )
192             {
193                 os << value[i*3+j];
194                 if( j < 2 ) os << ", ";
195             }
196             os << " )" << endl;
197         }
198         os << endl;
199     }
200 protected:
201     float value[9];
202 };
203 
204 class vtkCustomUniformMatrix4x4 : public vtkCustomUniform
205 {
206 public:
vtkCustomUniformMatrix4x4(float * v)207     vtkCustomUniformMatrix4x4( float * v ) { std::memcpy( value, v, sizeof value ); }
SetValue(float * v)208     void SetValue( float * v ) { std::memcpy( value, v, sizeof value ); }
GetGlslDec(const std::string & name)209     std::string GetGlslDec( const std::string & name ) override { return std::string("uniform mat4 ") + name + ";\n"; }
SetUniform(const char * name,vtkShaderProgram * p)210     bool SetUniform( const char * name, vtkShaderProgram * p ) override { return p->SetUniformMatrix4x4( name, value ); }
PrintSelf(const char * name,ostream & os,vtkIndent indent)211     void PrintSelf( const char * name, ostream& os, vtkIndent indent ) override
212     {
213         os << indent << name << ": " << endl;
214         for( int i = 0; i < 4; ++i )
215         {
216             os << indent << "( ";
217             for( int j = 0; j < 4; ++j )
218             {
219                 os << value[i*4+j];
220                 if( j < 3 ) os << ", ";
221             }
222             os << " )" << endl;
223         }
224         os << endl;
225     }
226 protected:
227     float value[16];
228 };
229 
230 class vtkCustomUniform1iv : public vtkCustomUniform
231 {
232 public:
vtkCustomUniform1iv(const int count,const int * v)233     vtkCustomUniform1iv( const int count, const int *v ) { SetValue(count,v); }
SetValue(const int count,const int * v)234     void SetValue( const int count, const int *v ) { value.assign( v, v + count ); }
GetGlslDec(const std::string & name)235     std::string GetGlslDec( const std::string & name ) override
236     { return std::string("uniform int ") + name + "[" + patch::to_string(value.size()) + "];\n"; }
SetUniform(const char * name,vtkShaderProgram * p)237     bool SetUniform( const char * name, vtkShaderProgram * p ) override
238     { return p->SetUniform1iv( name, static_cast<int>(value.size()), value.data() ); }
PrintSelf(const char * name,ostream & os,vtkIndent indent)239     void PrintSelf( const char * name, ostream& os, vtkIndent indent ) override
240     { os << indent << name << ": "; for( auto & v : value ) os << v << " "; os << endl; }
241 protected:
242     std::vector<int> value;
243 };
244 
245 class vtkCustomUniform1fv : public vtkCustomUniform
246 {
247 public:
vtkCustomUniform1fv(const int count,const float * v)248     vtkCustomUniform1fv( const int count, const float *v ) { SetValue(count,v); }
SetValue(const int count,const float * v)249     void SetValue( const int count, const float *v ) { value.assign( v, v + count ); }
GetGlslDec(const std::string & name)250     std::string GetGlslDec( const std::string & name ) override
251     { return std::string("uniform float ") + name + "[" + patch::to_string(value.size()) + "];\n"; }
SetUniform(const char * name,vtkShaderProgram * p)252     bool SetUniform( const char * name, vtkShaderProgram * p ) override
253     { return p->SetUniform1fv( name, static_cast<int>(value.size()), value.data() ); }
PrintSelf(const char * name,ostream & os,vtkIndent indent)254     void PrintSelf( const char * name, ostream& os, vtkIndent indent ) override
255     { os << indent << name << ": "; for( auto & v : value ) os << v << " "; os << endl; }
256 protected:
257     std::vector<float> value;
258 };
259 
260 class vtkCustomUniform2fv : public vtkCustomUniform
261 {
262 public:
vtkCustomUniform2fv(const int count,const float (* v)[2])263     vtkCustomUniform2fv( const int count, const float (*v)[2] ) { SetValue(count,v); }
SetValue(const int count,const float (* v)[2])264     void SetValue( const int count, const float (*v)[2] )
265     { value.assign( reinterpret_cast<const float*>(v), reinterpret_cast<const float*>(v + 2*count ) ); }
GetGlslDec(const std::string & name)266     std::string GetGlslDec( const std::string & name ) override
267     { return std::string("uniform vec2 ") + name + "[" + patch::to_string(value.size()/2) + "];\n"; }
SetUniform(const char * name,vtkShaderProgram * p)268     bool SetUniform( const char * name, vtkShaderProgram * p ) override
269     { return p->SetUniform2fv( name, static_cast<int>(value.size()/2), reinterpret_cast<const float(*)[2]>(value.data()) ); }
PrintSelf(const char * name,ostream & os,vtkIndent indent)270     void PrintSelf( const char * name, ostream& os, vtkIndent indent ) override
271     {
272         os << indent << name << ": ";
273         for( std::vector<float>::size_type i = 0; i < value.size()/2; ++i )
274             os << "( " << value[2*i] << ", " << value[2*i+1] << " ) ";
275         os << endl;
276     }
277 protected:
278     std::vector<float> value;
279 };
280 
281 class vtkCustomUniform3fv : public vtkCustomUniform
282 {
283 public:
vtkCustomUniform3fv(const int count,const float (* v)[3])284     vtkCustomUniform3fv( const int count, const float (*v)[3] ) { SetValue(count,v); }
SetValue(const int count,const float (* v)[3])285     void SetValue( const int count, const float (*v)[3] ) { value.assign( reinterpret_cast<const float*>(v), reinterpret_cast<const float*>(v + 3*count) ); }
GetGlslDec(const std::string & name)286     std::string GetGlslDec( const std::string & name ) override
287     { return std::string("uniform vec3 ") + name + "[" + patch::to_string(value.size()/3) + "];\n"; }
SetUniform(const char * name,vtkShaderProgram * p)288     bool SetUniform( const char * name, vtkShaderProgram * p ) override
289     { return p->SetUniform3fv( name, static_cast<int>(value.size()/3), reinterpret_cast<const float(*)[3]>(value.data()) ); }
PrintSelf(const char * name,ostream & os,vtkIndent indent)290     void PrintSelf( const char * name, ostream& os, vtkIndent indent ) override
291     {
292         os << indent << name << ": ";
293         for( std::vector<float>::size_type i = 0; i < value.size()/3; ++i )
294             os << "( " << value[3*i] << ", " << value[3*i+1] << ", " << value[3*i+2] << " ) ";
295         os << endl;
296     }
297 protected:
298     std::vector<float> value;
299 };
300 
301 class vtkCustomUniform4fv : public vtkCustomUniform
302 {
303 public:
vtkCustomUniform4fv(const int count,const float (* v)[4])304     vtkCustomUniform4fv( const int count, const float (*v)[4] ) { SetValue(count,v); }
SetValue(const int count,const float (* v)[4])305     void SetValue( const int count, const float (*v)[4] ) { value.assign( reinterpret_cast<const float*>(v), reinterpret_cast<const float*>(v + 4*count) ); }
GetGlslDec(const std::string & name)306     std::string GetGlslDec( const std::string & name ) override
307     { return std::string("uniform vec4 ") + name + "[" + patch::to_string(value.size()/4) + "];\n"; }
SetUniform(const char * name,vtkShaderProgram * p)308     bool SetUniform( const char * name, vtkShaderProgram * p ) override
309     { return p->SetUniform4fv( name, static_cast<int>(value.size()/4), reinterpret_cast<const float(*)[4]>(value.data()) ); }
PrintSelf(const char * name,ostream & os,vtkIndent indent)310     void PrintSelf( const char * name, ostream& os, vtkIndent indent ) override
311     {
312         os << indent << name << ": ";
313         for( std::vector<float>::size_type i = 0; i < value.size()/4; ++i )
314             os << "( " << value[4*i] << ", " << value[4*i+1] << ", " << value[4*i+2] << ", " << value[4*i+3] << " ) ";
315         os << endl;
316     }
317 protected:
318     std::vector<float> value;
319 };
320 
321 class vtkCustomUniformMatrix4x4v : public vtkCustomUniform
322 {
323 public:
vtkCustomUniformMatrix4x4v(const int count,const float * v)324     vtkCustomUniformMatrix4x4v( const int count, const float *v ) { SetValue(count,v); }
SetValue(const int count,const float * v)325     void SetValue( const int count, const float *v ) { value.assign( v, v + 16*count ); }
GetGlslDec(const std::string & name)326     std::string GetGlslDec( const std::string & name ) override
327     { return std::string("uniform mat4 ") + name + "[" + patch::to_string(value.size()/16) + "];\n"; }
SetUniform(const char * name,vtkShaderProgram * p)328     bool SetUniform( const char * name, vtkShaderProgram * p ) override
329     { return p->SetUniformMatrix4x4v( name, static_cast<int>(value.size()/16), value.data() ); }
PrintSelf(const char * name,ostream & os,vtkIndent indent)330     void PrintSelf( const char * name, ostream& os, vtkIndent indent ) override
331     {
332         os << indent << name << ": " << endl;
333         for( std::vector<float>::size_type mat = 0; mat < value.size()/16; ++mat )
334         {
335             for( std::vector<float>::size_type i = 0; i < 4; ++i )
336             {
337                 os << indent << "( ";
338                 for( std::vector<float>::size_type j = 0; j < 4; ++j )
339                 {
340                     os << value[mat*16+i*4+j];
341                     if( j < 3 ) os << ", ";
342                 }
343                 os << " )" << endl;
344             }
345             os << endl << endl;
346         }
347     }
348 protected:
349     std::vector<float> value;
350 };
351 
352 class vtkUniformInternals : public vtkObject
353 {
354 
355 public:
356 
357     static vtkUniformInternals *New();
358     vtkTypeMacro(vtkUniformInternals, vtkObject);
PrintSelf(ostream & os,vtkIndent indent)359     void PrintSelf(ostream& os, vtkIndent indent) override
360     {
361         for( auto & uni : Uniforms )
362         {
363             uni.second->PrintSelf( uni.first.c_str(), os, indent );
364         }
365     }
366 
367     template< class dataT, class uniformT >
AddUniform(const char * name,dataT defaultValue)368     void AddUniform( const char * name, dataT defaultValue )
369     {
370         UniformMapT::iterator it = Uniforms.find( name );
371         if( it != Uniforms.end() )
372         {
373             vtkErrorMacro( << "vtkOpenGLUniform: overwriting existing uniform variable: " << name << endl );
374             delete (*it).second;
375             Uniforms.erase( it );
376         }
377         Uniforms[std::string(name)] = new uniformT(defaultValue);
378         Modified();
379     }
380 
381     template< class dataT, class uniformT >
AddUniform(const char * name,int count,dataT defaultValue)382     void AddUniform( const char * name, int count, dataT defaultValue )
383     {
384         UniformMapT::iterator it = Uniforms.find( name );
385         if( it != Uniforms.end() )
386         {
387             vtkErrorMacro( << "vtkOpenGLUniform: overwriting existing uniform variable: " << name << endl );
388             delete (*it).second;
389             Uniforms.erase( it );
390         }
391         Uniforms[std::string(name)] = new uniformT(count, defaultValue);
392         Modified();
393     }
394 
RemoveUniform(const char * name)395     void RemoveUniform(const char *name)
396     {
397         UniformMapT::iterator it = Uniforms.find( name );
398         if( it != Uniforms.end() )
399         {
400             delete (*it).second;
401             Uniforms.erase( it );
402         }
403         Modified();
404     }
405 
RemoveAllUniforms()406     void RemoveAllUniforms()
407     {
408         for( auto & uni : Uniforms )
409         {
410             delete uni.second;
411         }
412         Uniforms.clear();
413         Modified();
414     }
415 
416     template< class dataT, class uniformT >
SetUniform(const char * name,const dataT value)417     void SetUniform( const char *name, const dataT value )
418     {
419         UniformMapT::iterator it = Uniforms.find( name );
420         if( it != Uniforms.end() )
421         {
422             uniformT * uni = dynamic_cast<uniformT*>(it->second);
423             uni->SetValue( value );
424         }
425         else
426         {
427             vtkErrorMacro( << "Trying to set the value of undefined uniform variable: " << name << endl );
428         }
429     }
430 
431     template< class dataT, class uniformT >
SetUniform(const char * name,int count,const dataT value)432     void SetUniform( const char *name, int count, const dataT value )
433     {
434         UniformMapT::iterator it = Uniforms.find( name );
435         if( it != Uniforms.end() )
436         {
437             uniformT * uni = dynamic_cast<uniformT*>(it->second);
438             uni->SetValue( count, value );
439         }
440         else
441         {
442             vtkErrorMacro( << "Trying to set the value of undefined uniform variable: " << name << endl );
443         }
444     }
445 
GetDeclarations()446     std::string GetDeclarations()
447     {
448         std::string res;
449         for( auto & uni : Uniforms )
450         {
451             res += uni.second->GetGlslDec( uni.first );
452         }
453         return res;
454     }
455 
SetUniforms(vtkShaderProgram * p)456     bool SetUniforms( vtkShaderProgram * p )
457     {
458         bool res = true;
459         for( auto & uni : Uniforms )
460         {
461             bool r = uni.second->SetUniform( uni.first.c_str(), p );
462             if( !r )
463                 vtkErrorMacro( << "vtkOpenGLUniform: couldn't set custom uniform variable " << uni.first << endl );
464             res &= r;
465         }
466         return res;
467     }
468 
469 protected:
470 
vtkUniformInternals()471     vtkUniformInternals() {}
~vtkUniformInternals()472     ~vtkUniformInternals() override
473     {
474         RemoveAllUniforms();
475     }
476 
477 private:
478     vtkUniformInternals(const vtkUniformInternals&) = delete;
479     void operator=(const vtkUniformInternals&) = delete;
480 
481     typedef std::map<std::string,vtkCustomUniform*> UniformMapT;
482     UniformMapT Uniforms;
483 };
484 
485 vtkStandardNewMacro(vtkUniformInternals);
486 
vtkOpenGLUniforms()487 vtkOpenGLUniforms::vtkOpenGLUniforms()
488 {
489     this->Internals = vtkUniformInternals::New();
490 }
491 
~vtkOpenGLUniforms()492 vtkOpenGLUniforms::~vtkOpenGLUniforms()
493 {
494     this->Internals->Delete();
495 }
496 
AddUniformi(const char * name,int defaultValue)497 void vtkOpenGLUniforms::AddUniformi (const char *name, int defaultValue)
498 { this->Internals->AddUniform<int,vtkCustomUniformi>( name, defaultValue ); }
AddUniformf(const char * name,float defaultValue)499 void vtkOpenGLUniforms::AddUniformf(const char *name, float defaultValue)
500 { this->Internals->AddUniform<float,vtkCustomUniformf>( name, defaultValue ); }
AddUniform2i(const char * name,const int defaultValue[2])501 void vtkOpenGLUniforms::AddUniform2i(const char *name, const int defaultValue[2])
502 { this->Internals->AddUniform<const int[2],vtkCustomUniform2i>( name, defaultValue ); }
AddUniform2f(const char * name,const float defaultValue[2])503 void vtkOpenGLUniforms::AddUniform2f(const char *name, const float defaultValue[2])
504 { this->Internals->AddUniform<const float[2],vtkCustomUniform2f>( name, defaultValue ); }
AddUniform3f(const char * name,const float defaultValue[3])505 void vtkOpenGLUniforms::AddUniform3f(const char *name, const float defaultValue[3])
506 { this->Internals->AddUniform<const float[3],vtkCustomUniform3f>( name, defaultValue ); }
AddUniform3f(const char * name,const double defaultValue[3])507 void vtkOpenGLUniforms::AddUniform3f(const char *name, const double defaultValue[3])
508 { this->Internals->AddUniform<const double[3],vtkCustomUniform3d>( name, defaultValue ); }
AddUniform4f(const char * name,const float defaultValue[4])509 void vtkOpenGLUniforms::AddUniform4f(const char *name, const float defaultValue[4])
510 { this->Internals->AddUniform<const float[4],vtkCustomUniform4f>( name, defaultValue ); }
AddUniform3uc(const char * name,const unsigned char defaultValue[3])511 void vtkOpenGLUniforms::AddUniform3uc(const char *name, const unsigned char defaultValue[3]) // maybe remove
512 { this->Internals->AddUniform<const unsigned char[3],vtkCustomUniform3uc>( name, defaultValue ); }
AddUniform4uc(const char * name,const unsigned char defaultValue[4])513 void vtkOpenGLUniforms::AddUniform4uc(const char *name, const unsigned char defaultValue[4]) // maybe remove
514 { this->Internals->AddUniform<const unsigned char[4],vtkCustomUniform4uc>( name, defaultValue ); }
AddUniformMatrix(const char * name,vtkMatrix3x3 * defaultValue)515 void vtkOpenGLUniforms::AddUniformMatrix(const char *name, vtkMatrix3x3 *defaultValue)
516 { this->Internals->AddUniform<vtkMatrix3x3*,vtkCustomUniformVtkMatrix3x3>( name, defaultValue ); }
AddUniformMatrix(const char * name,vtkMatrix4x4 * defaultValue)517 void vtkOpenGLUniforms::AddUniformMatrix(const char *name, vtkMatrix4x4 *defaultValue)
518 { this->Internals->AddUniform<vtkMatrix4x4*,vtkCustomUniformVtkMatrix4x4>( name, defaultValue ); }
AddUniformMatrix3x3(const char * name,float * defaultValue)519 void vtkOpenGLUniforms::AddUniformMatrix3x3(const char *name, float *defaultValue)
520 { this->Internals->AddUniform<float*,vtkCustomUniformMatrix3x3>( name, defaultValue ); }
AddUniformMatrix4x4(const char * name,float * defaultValue)521 void vtkOpenGLUniforms::AddUniformMatrix4x4(const char *name, float *defaultValue)
522 { this->Internals->AddUniform<float*,vtkCustomUniformMatrix4x4>( name, defaultValue ); }
AddUniform1iv(const char * name,const int count,const int * f)523 void vtkOpenGLUniforms::AddUniform1iv(const char *name, const int count, const int *f)
524 { this->Internals->AddUniform<const int *,vtkCustomUniform1iv>(name,count,f); }
AddUniform1fv(const char * name,const int count,const float * f)525 void vtkOpenGLUniforms::AddUniform1fv (const char *name, const int count, const float *f)
526 { this->Internals->AddUniform<const float *,vtkCustomUniform1fv>(name,count,f); }
AddUniform2fv(const char * name,const int count,const float (* f)[2])527 void vtkOpenGLUniforms::AddUniform2fv (const char *name, const int count, const float(*f)[2])
528 { this->Internals->AddUniform<const float(*)[2],vtkCustomUniform2fv>(name,count,f); }
AddUniform3fv(const char * name,const int count,const float (* f)[3])529 void vtkOpenGLUniforms::AddUniform3fv (const char *name, const int count, const float(*f)[3])
530 { this->Internals->AddUniform<const float(*)[3],vtkCustomUniform3fv>(name,count,f); }
AddUniform4fv(const char * name,const int count,const float (* f)[4])531 void vtkOpenGLUniforms::AddUniform4fv (const char *name, const int count, const float(*f)[4])
532 { this->Internals->AddUniform<const float(*)[4],vtkCustomUniform4fv>(name,count,f); }
AddUniformMatrix4x4v(const char * name,const int count,float * v)533 void vtkOpenGLUniforms::AddUniformMatrix4x4v (const char *name, const int count, float *v)
534 { this->Internals->AddUniform<float *,vtkCustomUniformMatrix4x4v>(name,count,v); }
535 
RemoveUniform(const char * name)536 void vtkOpenGLUniforms::RemoveUniform(const char *name) { this->Internals->RemoveUniform(name); }
RemoveAllUniforms()537 void vtkOpenGLUniforms::RemoveAllUniforms() { this->Internals->RemoveAllUniforms(); }
538 
SetUniformi(const char * name,int v)539 void vtkOpenGLUniforms::SetUniformi (const char *name, int v)
540 { this->Internals->SetUniform<int,vtkCustomUniformi>(name, v); }
SetUniformf(const char * name,float v)541 void vtkOpenGLUniforms::SetUniformf (const char *name, float v)
542 { this->Internals->SetUniform<float,vtkCustomUniformf>(name,v); }
SetUniform2i(const char * name,const int v[2])543 void vtkOpenGLUniforms::SetUniform2i (const char *name, const int v[2])
544 { this->Internals->SetUniform<const int[2],vtkCustomUniform2i>(name,v); }
SetUniform2f(const char * name,const float v[2])545 void vtkOpenGLUniforms::SetUniform2f (const char *name, const float v[2])
546 { this->Internals->SetUniform<const float[2],vtkCustomUniform2f>(name,v); }
SetUniform3f(const char * name,const float v[3])547 void vtkOpenGLUniforms::SetUniform3f (const char *name, const float v[3])
548 { this->Internals->SetUniform<const float[3],vtkCustomUniform3f>(name,v); }
SetUniform3f(const char * name,const double v[3])549 void vtkOpenGLUniforms::SetUniform3f (const char *name, const double v[3])
550 { this->Internals->SetUniform<const double[3],vtkCustomUniform3d>(name,v); }
SetUniform4f(const char * name,const float v[4])551 void vtkOpenGLUniforms::SetUniform4f (const char *name, const float v[4])
552 { this->Internals->SetUniform<const float[4],vtkCustomUniform4f>(name,v); }
SetUniform3uc(const char * name,const unsigned char v[3])553 void vtkOpenGLUniforms::SetUniform3uc (const char *name, const unsigned char v[3])
554 { this->Internals->SetUniform<const unsigned char[3],vtkCustomUniform3uc>(name,v); }
SetUniform4uc(const char * name,const unsigned char v[4])555 void vtkOpenGLUniforms::SetUniform4uc (const char *name, const unsigned char v[4])
556 { this->Internals->SetUniform<const unsigned char[4],vtkCustomUniform4uc>(name,v); }
SetUniformMatrix(const char * name,vtkMatrix3x3 * v)557 void vtkOpenGLUniforms::SetUniformMatrix (const char *name, vtkMatrix3x3 *v)
558 { this->Internals->SetUniform<vtkMatrix3x3*,vtkCustomUniformVtkMatrix3x3>(name,v); }
SetUniformMatrix(const char * name,vtkMatrix4x4 * v)559 void vtkOpenGLUniforms::SetUniformMatrix (const char *name, vtkMatrix4x4 *v)
560 { this->Internals->SetUniform<vtkMatrix4x4*,vtkCustomUniformVtkMatrix4x4>(name,v); }
SetUniformMatrix3x3(const char * name,float * v)561 void vtkOpenGLUniforms::SetUniformMatrix3x3 (const char *name, float *v)
562 { this->Internals->SetUniform<float*,vtkCustomUniformMatrix3x3>(name,v); }
SetUniformMatrix4x4(const char * name,float * v)563 void vtkOpenGLUniforms::SetUniformMatrix4x4 (const char *name, float *v)
564 { this->Internals->SetUniform<float*,vtkCustomUniformMatrix4x4>(name,v); }
SetUniform1iv(const char * name,const int count,const int * f)565 void vtkOpenGLUniforms::SetUniform1iv (const char *name, const int count, const int *f)
566 { this->Internals->SetUniform<const int *,vtkCustomUniform1iv>(name,count,f); }
SetUniform1fv(const char * name,const int count,const float * f)567 void vtkOpenGLUniforms::SetUniform1fv (const char *name, const int count, const float *f)
568 { this->Internals->SetUniform<const float*,vtkCustomUniform1fv>(name,count,f); }
SetUniform2fv(const char * name,const int count,const float (* f)[2])569 void vtkOpenGLUniforms::SetUniform2fv (const char *name, const int count, const float(*f)[2])
570 { this->Internals->SetUniform<const float(*)[2],vtkCustomUniform2fv>(name,count,f); }
SetUniform3fv(const char * name,const int count,const float (* f)[3])571 void vtkOpenGLUniforms::SetUniform3fv (const char *name, const int count, const float(*f)[3])
572 { this->Internals->SetUniform<const float(*)[3],vtkCustomUniform3fv>(name,count,f); }
SetUniform4fv(const char * name,const int count,const float (* f)[4])573 void vtkOpenGLUniforms::SetUniform4fv (const char *name, const int count, const float(*f)[4])
574 { this->Internals->SetUniform<const float(*)[4],vtkCustomUniform4fv>(name,count,f); }
SetUniformMatrix4x4v(const char * name,const int count,float * v)575 void vtkOpenGLUniforms::SetUniformMatrix4x4v (const char *name, const int count, float *v)
576 { this->Internals->SetUniform<float*,vtkCustomUniformMatrix4x4v>(name,count,v); }
577 
GetDeclarations()578 std::string vtkOpenGLUniforms::GetDeclarations()
579 { return this->Internals->GetDeclarations(); }
580 
SetUniforms(vtkShaderProgram * p)581 bool vtkOpenGLUniforms::SetUniforms( vtkShaderProgram * p )
582 { return this->Internals->SetUniforms(p); }
583 
GetUniformListMTime()584 vtkMTimeType vtkOpenGLUniforms::GetUniformListMTime()
585 {
586     return this->Internals->GetMTime();
587 }
588 
PrintSelf(ostream & os,vtkIndent indent)589 void vtkOpenGLUniforms::PrintSelf(ostream& os, vtkIndent indent)
590 {
591     this->Superclass::PrintSelf(os,indent);
592     this->Internals->PrintSelf(os,indent);
593 }
594