Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
UniformPool.cc
1 /*===========================================================================*\
2  * *
3  * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40 \*===========================================================================*/
41 
42 /*===========================================================================*\
43  * *
44  * $Revision: 17546 $ *
45  * $Author: moebius $ *
46  * $Date: 2013-09-17 10:04:29 +0200 (Di, 17. Sep 2013) $ *
47  * *
48 \*===========================================================================*/
49 
50 #include <iostream>
51 
52 #include <ACG/GL/acg_glew.hh>
53 #include <ACG/GL/GLError.hh>
54 #include "UniformPool.hh"
55 
56 #ifdef WIN32
57  #ifndef __MINGW32__
58  #define snprintf sprintf_s
59  #endif
60 #endif
61 
62 //==============================================================================
63 
64 namespace GLSL {
65 
66  //--------------------------------------------------------------------------
67  // Uniform Pool
68  //--------------------------------------------------------------------------
69 
70 
72  }
73 
74 
76  addPool(_pool);
77  }
78 
79 
83  clear();
84  }
85 
87  // Delete the uniforms in that pool
88  for (UniformListIt it = pool_.begin(); it != pool_.end(); ++it)
89  delete (*it);
90 
91  // Clear the pool
92  pool_.clear();
93  }
94 
95  bool UniformPool::empty() const {
96  return pool_.empty();
97  }
98 
103  void UniformPool::bind( PtrProgram _prog ) const {
104  bind(_prog->getProgramId());
105  }
106 
111  void UniformPool::bind( GLuint _prog ) const {
112  for (UniformList::const_iterator it = pool_.begin(); it != pool_.end(); ++it) {
113  (*it)->bind(_prog);
114  }
115  }
116 
122  UniformPool::UniformListIt UniformPool::findEntry( std::string _name ) {
123 
124  for (UniformListIt it = pool_.begin(); it != pool_.end(); ++it){
125  if ((*it)->id.compare(_name) == 0)
126  return it;
127  }
128 
129  return pool_.end();
130  }
131 
136  void UniformPool::addPool( const UniformPool& _src ){
137 
138  for (UniformList::const_iterator it = _src.pool_.begin(); it != _src.pool_.end(); ++it){
139 
140  // determine type
141  const UniformVecf* pVecf = dynamic_cast<const UniformVecf*>(*it);
142  const UniformVeci* pVeci = dynamic_cast<const UniformVeci*>(*it);
143  const UniformVecui* pVecui = dynamic_cast<const UniformVecui*>(*it);
144  const UniformMat* pMat = dynamic_cast<const UniformMat*>(*it);
145  const UniformBuf* pBuf = dynamic_cast<const UniformBuf*>(*it);
146 
147  // add to our list
148  if (pVecf)
149  addVecf(*pVecf);
150 
151  if (pVeci)
152  addVeci(*pVeci);
153 
154  if (pVecui)
155  addVecui(*pVecui);
156 
157  else if (pMat)
158  addMatrix(*pMat);
159 
160  else if (pBuf)
161  addBuf(pBuf->id.c_str(), pBuf->val, pBuf->size, pBuf->integer);
162  }
163  }
164 
165 
170  void UniformPool::UniformVecf::bind( GLuint _progID ) const {
171  checkGLError2("prev opengl error");
172  GLint location = glGetUniformLocation(_progID, id.c_str());
173  checkGLError2(id.c_str());
174 
175  switch (size){
176  case 1:
177  glUniform1fv(location, 1, val.data());
178  break;
179  case 2:
180  glUniform2fv(location, 1, val.data());
181  break;
182  case 3:
183  glUniform3fv(location, 1, val.data());
184  break;
185  case 4:
186  glUniform4fv(location, 1, val.data());
187  break;
188 
189  default:
190  std::cerr << "UniformPool::UniformVecf : invalid size " << size << std::endl;
191  break;
192  }
193 
194  checkGLError2(id.c_str());
195  }
196 
201  void UniformPool::UniformVeci::bind( GLuint _progID ) const {
202  checkGLError2("prev opengl error");
203  GLint location = glGetUniformLocation(_progID, id.c_str());
204  checkGLError2(id.c_str());
205 
206  switch (size){
207  case 1:
208  glUniform1iv(location, 1, (GLint*)val.data());
209  break;
210  case 2:
211  glUniform2iv(location, 1, (GLint*)val.data());
212  break;
213  case 3:
214  glUniform3iv(location, 1, (GLint*)val.data());
215  break;
216  case 4:
217  glUniform4iv(location, 1, (GLint*)val.data());
218  break;
219 
220  default:
221  std::cerr << "UniformPool::UniformVeci : invalid size " << size << std::endl;
222  break;
223  }
224 
225  checkGLError2(id.c_str());
226  }
227 
232  void UniformPool::UniformVecui::bind( GLuint _progID ) const {
233  checkGLError2("prev opengl error");
234  GLint location = glGetUniformLocation(_progID, id.c_str());
235  checkGLError2(id.c_str());
236 
237  switch (size){
238  case 1:
239  glUniform1uiv(location, 1, (GLuint*)val.data());
240  break;
241  case 2:
242  glUniform2uiv(location, 1, (GLuint*)val.data());
243  break;
244  case 3:
245  glUniform3uiv(location, 1, (GLuint*)val.data());
246  break;
247  case 4:
248  glUniform4uiv(location, 1, (GLuint*)val.data());
249  break;
250 
251  default:
252  std::cerr << "UniformPool::UniformVecui : invalid size " << size << std::endl;
253  break;
254  }
255 
256  checkGLError2(id.c_str());
257  }
258 
263  void UniformPool::UniformMat::bind( GLuint _progID ) const {
264  checkGLError2("prev opengl error");
265  GLint location = glGetUniformLocation(_progID, id.c_str());
266  checkGLError2(id.c_str());
267 
268  switch (size){
269  case 2: {
270  float tmp[4];
271  for (int i = 0; i < 2; ++i)
272  for (int k = 0; k < 2; ++k)
273  tmp[i*2+k] = val.data()[i*4+k];
274  glUniformMatrix2fv(location, 1, transposed, tmp);
275  } break;
276 
277  case 3: {
278  float tmp[9];
279  for (int i = 0; i < 3; ++i)
280  for (int k = 0; k < 3; ++k)
281  tmp[i*3+k] = val.data()[i*4+k];
282  glUniformMatrix3fv(location, 1, transposed, tmp);
283  } break;
284 
285  case 4: glUniformMatrix4fv(location, 1, transposed, val.data()); break;
286 
287  default:
288  std::cerr << "UniformPool::UniformMat : invalid size " << size << std::endl;
289  break;
290  }
291 
292  checkGLError2(id.c_str());
293  }
294 
299  void UniformPool::UniformBuf::bind( GLuint _progID ) const {
300  checkGLError2("prev opengl error");
301  GLint location = glGetUniformLocation(_progID, id.c_str());
302  checkGLError2(id.c_str());
303 
304  if (integer){
305  glUniform1iv(location, size, (GLint*)val);
306  }
307  else{
308  glUniform1fv(location, size, val);
309  }
310 
311  checkGLError2(id.c_str());
312  }
313 
314 
318  : val(0), integer(false), size(0)
319  {
320  }
321 
325  delete [] val;
326  }
327 
328 
333  void UniformPool::addVecf( const UniformVecf& _vec ) {
334  // look for existing uniform in pool
335  UniformListIt it = findEntry(_vec.id);
336 
337  // storage address of uniform
338  UniformVecf* dst = 0;
339 
340  if ( it == pool_.end() ){
341  // create new entry
342  dst = new UniformVecf;
343  pool_.push_back(dst);
344  }
345  else{
346  // use existing entry
347  dst = dynamic_cast<UniformVecf*>( *it );
348 
349  if (!dst)
350  std::cerr << "UniformPool::addVecf type of " << _vec.id << " incorrect." << std::endl;
351  }
352 
353  if (dst) {
354  // update data
355  dst->id = _vec.id;
356  dst->size = _vec.size;
357  dst->val = _vec.val;
358  }
359 
360  }
361 
366  void UniformPool::addVeci( const UniformVeci& _vec ) {
367  // look for existing uniform in pool
368  UniformListIt it = findEntry(_vec.id);
369 
370  // storage address of uniform
371  UniformVeci* dst = 0;
372 
373  if ( it == pool_.end() ){
374  // create new entry
375  dst = new UniformVeci;
376  pool_.push_back(dst);
377  }
378  else{
379  // use existing entry
380  dst = dynamic_cast<UniformVeci*>( *it );
381 
382  if (!dst)
383  std::cerr << "UniformPool::addVeci type of " << _vec.id << " incorrect." << std::endl;
384  }
385 
386  if (dst) {
387  // update data
388  dst->id = _vec.id;
389  dst->size = _vec.size;
390  dst->val = _vec.val;
391  }
392 
393  }
394 
399  void UniformPool::addVecui( const UniformVecui& _vec ) {
400  // look for existing uniform in pool
401  UniformListIt it = findEntry(_vec.id);
402 
403  // storage address of uniform
404  UniformVecui* dst = 0;
405 
406  if ( it == pool_.end() ){
407  // create new entry
408  dst = new UniformVecui;
409  pool_.push_back(dst);
410  }
411  else{
412  // use existing entry
413  dst = dynamic_cast<UniformVecui*>( *it );
414 
415  if (!dst)
416  std::cerr << "UniformPool::addVecui type of " << _vec.id << " incorrect." << std::endl;
417  }
418 
419  if (dst) {
420  // update data
421  dst->id = _vec.id;
422  dst->size = _vec.size;
423  dst->val = _vec.val;
424  }
425 
426  }
427 
432  void UniformPool::addMatrix( const UniformMat& _mat ) {
433  // look for existing uniform in pool
434  UniformListIt it = findEntry(_mat.id);
435 
436  // storage address of uniform
437  UniformMat* dst = 0;
438 
439  if ( it == pool_.end() ){
440  // create new entry
441  dst = new UniformMat;
442  pool_.push_back(dst);
443  }
444  else{
445  // use existing entry
446  dst = dynamic_cast<UniformMat*>( *it );
447 
448  if (!dst)
449  std::cerr << "UniformPool::addMatrix type of " << _mat.id << " incorrect." << std::endl;
450  }
451 
452  if (dst) {
453  // update data
454  dst->id = _mat.id;
455  dst->size = _mat.size;
456  dst->transposed = _mat.transposed;
457  dst->val = _mat.val;
458  }
459  }
460 
468  void UniformPool::addBuf( const char* _name, void* _values, int _count, bool _integer ) {
469  // look for existing uniform in pool
470  UniformListIt it = findEntry(_name);
471 
472  // storage address of uniform
473  UniformBuf* dst = 0;
474 
475  if ( it == pool_.end() ){
476  // create new entry
477  dst = new UniformBuf();
478  pool_.push_back(dst);
479  }
480  else{
481  // use existing entry
482  dst = dynamic_cast<UniformBuf*>( *it );
483 
484  if (!dst)
485  std::cerr << "UniformPool::addBuf type of " << _name << " incorrect." << std::endl;
486  }
487 
488  if (dst) {
489  // update data
490  dst->id = _name;
491 
492  if (dst->size < _count)
493  {
494  // resize
495  delete [] dst->val;
496  dst->val = new float[_count];
497  }
498 
499  dst->size = _count;
500 
501  if (_values)
502  memcpy(dst->val, _values, _count * sizeof(float));
503  }
504  }
505 
506 
512  void UniformPool::setUniform( const char *_name, GLint _value ) {
513  // create uniform descriptor
514  UniformVeci tmp;
515  tmp.id = _name;
516  tmp.size = 1;
517  tmp.val[0] = _value;
518 
519  // add/update in pool
520  addVeci(tmp);
521  }
522 
528  void UniformPool::setUniform( const char *_name, const ACG::Vec2i &_value ) {
529  // create uniform descriptor
530  UniformVeci tmp;
531  tmp.id = _name;
532  tmp.size = 2;
533  tmp.val[0] = _value[0];
534  tmp.val[1] = _value[1];
535 
536  // add/update in pool
537  addVeci(tmp);
538  }
539 
545  void UniformPool::setUniform( const char *_name, const ACG::Vec3i &_value ) {
546  // create uniform descriptor
547  UniformVeci tmp;
548  tmp.id = _name;
549  tmp.size = 3;
550  tmp.val[0] = _value[0];
551  tmp.val[1] = _value[1];
552  tmp.val[2] = _value[2];
553 
554  // add/update in pool
555  addVeci(tmp);
556  }
557 
563  void UniformPool::setUniform( const char *_name, const ACG::Vec4i &_value ) {
564  // create uniform descriptor
565  UniformVeci tmp;
566  tmp.id = _name;
567  tmp.size = 4;
568  tmp.val = _value;
569 
570  // add/update in pool
571  addVeci(tmp);
572  }
573 
579  void UniformPool::setUniform( const char *_name, GLuint _value ) {
580  // create uniform descriptor
581  UniformVecui tmp;
582  tmp.id = _name;
583  tmp.size = 1;
584  tmp.val[0] = _value;
585 
586  // add/update in pool
587  addVecui(tmp);
588  }
589 
595  void UniformPool::setUniform( const char *_name, const ACG::Vec2ui &_value ) {
596  // create uniform descriptor
597  UniformVecui tmp;
598  tmp.id = _name;
599  tmp.size = 2;
600  tmp.val[0] = _value[0];
601  tmp.val[1] = _value[1];
602 
603  // add/update in pool
604  addVecui(tmp);
605  }
606 
612  void UniformPool::setUniform( const char *_name, const ACG::Vec3ui &_value ) {
613  // create uniform descriptor
614  UniformVecui tmp;
615  tmp.id = _name;
616  tmp.size = 3;
617  tmp.val[0] = _value[0];
618  tmp.val[1] = _value[1];
619  tmp.val[2] = _value[2];
620 
621  // add/update in pool
622  addVecui(tmp);
623  }
624 
630  void UniformPool::setUniform( const char *_name, const ACG::Vec4ui &_value ) {
631  // create uniform descriptor
632  UniformVecui tmp;
633  tmp.id = _name;
634  tmp.size = 4;
635  tmp.val = _value;
636 
637  // add/update in pool
638  addVecui(tmp);
639  }
640 
641 
647  void UniformPool::setUniform( const char *_name, GLfloat _value ) {
648  // create uniform descriptor
649  UniformVecf tmp;
650  tmp.id = _name;
651  tmp.size = 1;
652  tmp.val[0] = _value;
653 
654  // add/update in pool
655  addVecf(tmp);
656  }
657 
663  void UniformPool::setUniform( const char *_name, const ACG::Vec2f &_value ) {
664  // create uniform descriptor
665  UniformVecf tmp;
666  tmp.id = _name;
667  tmp.size = 2;
668  tmp.val[0] = _value[0];
669  tmp.val[1] = _value[1];
670 
671  // add/update in pool
672  addVecf(tmp);
673  }
674 
680  void UniformPool::setUniform( const char *_name, const ACG::Vec3f &_value ) {
681  // create uniform descriptor
682  UniformVecf tmp;
683  tmp.id = _name;
684  tmp.size = 3;
685  tmp.val[0] = _value[0];
686  tmp.val[1] = _value[1];
687  tmp.val[2] = _value[2];
688 
689  // add/update in pool
690  addVecf(tmp);
691  }
692 
698  void UniformPool::setUniform( const char *_name, const ACG::Vec4f &_value ) {
699  // create uniform descriptor
700  UniformVecf tmp;
701  tmp.id = _name;
702  tmp.size = 4;
703  tmp.val = _value;
704 
705  // add/update in pool
706  addVecf(tmp);
707  }
708 
715  void UniformPool::setUniform( const char *_name, const ACG::GLMatrixf &_value, bool _transposed ) {
716  // create uniform descriptor
717  UniformMat tmp;
718  tmp.id = _name;
719  tmp.transposed = _transposed;
720  tmp.size = 4;
721  tmp.val = _value;
722 
723  // add/update in pool
724  addMatrix(tmp);
725  }
726 
733  void UniformPool::setUniformMat3( const char *_name, const ACG::GLMatrixf &_value, bool _transposed ) {
734  // create uniform descriptor
735  UniformMat tmp;
736  tmp.id = _name;
737  tmp.transposed = _transposed;
738  tmp.size = 3;
739  tmp.val = _value;
740 
741  // add/update in pool
742  addMatrix(tmp);
743  }
744 
751  void UniformPool::setUniform( const char *_name, GLint *_values, int _count ) {
752  // add/update in pool
753  addBuf(_name, _values, _count, true);
754  }
755 
762  void UniformPool::setUniform( const char *_name, GLfloat *_values, int _count ) {
763  // add/update in pool
764  addBuf(_name, _values, _count, false);
765  }
766 
767 }
768 
769 
770 //==============================================================================
void addPool(const UniformPool &_src)
Add all uniforms of a pool to this pool.
Definition: UniformPool.cc:136
void bind(GLuint _progID) const
Bind uniform uint vector to shader.
Definition: UniformPool.cc:232
UniformList pool_
list of uniform params
Definition: UniformPool.hh:184
void bind(GLuint _progID) const
Bind uniform matrix to shader.
Definition: UniformPool.cc:263
void bind(GLuint _progID) const
Bind uniform array to shader.
Definition: UniformPool.cc:299
void clear()
Clear the pool.
Definition: UniformPool.cc:86
UniformBuf()
Creates a copy of input data.
Definition: UniformPool.cc:317
GLSL uniform pool.
Definition: UniformPool.hh:71
GLuint getProgramId()
Returns opengl id.
Definition: GLSLShader.cc:382
void addBuf(const char *_name, void *_values, int _count, bool _integer)
Add or update an array type uniform in pool.
Definition: UniformPool.cc:468
void addVecf(const UniformVecf &_vec)
Add or update a vector type uniform in pool.
Definition: UniformPool.cc:333
void addVeci(const UniformVeci &_vec)
Add or update a vector type uniform in pool.
Definition: UniformPool.cc:366
This namespace contains all the classes and functions for handling GLSL shader and program objects...
Definition: AntiAliasing.hh:75
UniformPool()
Constructor.
Definition: UniformPool.cc:71
void setUniformMat3(const char *_name, const ACG::GLMatrixf &_value, bool _transposed=false)
Set 3x3fMatrix uniform to specified value.
Definition: UniformPool.cc:733
void bind(GLuint _progID) const
Bind uniform float vector to shader.
Definition: UniformPool.cc:170
void bind(GLuint _progID) const
Bind uniform int vector to shader.
Definition: UniformPool.cc:201
GLSL program class.
Definition: GLSLShader.hh:217
bool empty() const
returns if the pool is empty
Definition: UniformPool.cc:95
void addMatrix(const UniformMat &_mat)
Add or update a matrix type uniform in pool.
Definition: UniformPool.cc:432
void bind(PtrProgram _prog) const
Send all stored uniforms to program.
Definition: UniformPool.cc:103
void addVecui(const UniformVecui &_vec)
Add or update a vector type uniform in pool.
Definition: UniformPool.cc:399
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
Definition: UniformPool.cc:512
UniformListIt findEntry(std::string _name)
Search the pool for an existing value for a uniform name.
Definition: UniformPool.cc:122
virtual ~UniformPool()
Destructor.
Definition: UniformPool.cc:82