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 
86 
87  void UniformPool::operator =(const UniformPool& _other) {
88  addPool(_other);
89  }
90 
92  // Delete the uniforms in that pool
93  for (UniformListIt it = pool_.begin(); it != pool_.end(); ++it)
94  delete (*it);
95 
96  // Clear the pool
97  pool_.clear();
98  }
99 
100  bool UniformPool::empty() const {
101  return pool_.empty();
102  }
103 
108  void UniformPool::bind( PtrProgram _prog ) const {
109  bind(_prog->getProgramId());
110  }
111 
116  void UniformPool::bind( GLuint _prog ) const {
117  for (UniformList::const_iterator it = pool_.begin(); it != pool_.end(); ++it) {
118  (*it)->bind(_prog);
119  }
120  }
121 
127  UniformPool::UniformListIt UniformPool::findEntry( std::string _name ) {
128 
129  for (UniformListIt it = pool_.begin(); it != pool_.end(); ++it){
130  if ((*it)->id.compare(_name) == 0)
131  return it;
132  }
133 
134  return pool_.end();
135  }
136 
141  void UniformPool::addPool( const UniformPool& _src ){
142 
143  for (UniformList::const_iterator it = _src.pool_.begin(); it != _src.pool_.end(); ++it){
144 
145  // determine type
146  const UniformVecf* pVecf = dynamic_cast<const UniformVecf*>(*it);
147  const UniformVeci* pVeci = dynamic_cast<const UniformVeci*>(*it);
148  const UniformVecui* pVecui = dynamic_cast<const UniformVecui*>(*it);
149  const UniformMat* pMat = dynamic_cast<const UniformMat*>(*it);
150  const UniformBuf* pBuf = dynamic_cast<const UniformBuf*>(*it);
151 
152  // add to our list
153  if (pVecf)
154  addVecf(*pVecf);
155 
156  if (pVeci)
157  addVeci(*pVeci);
158 
159  if (pVecui)
160  addVecui(*pVecui);
161 
162  else if (pMat)
163  addMatrix(*pMat);
164 
165  else if (pBuf)
166  addBuf(pBuf->id.c_str(), pBuf->val, pBuf->size, pBuf->integer);
167  }
168  }
169 
170 
175  void UniformPool::UniformVecf::bind( GLuint _progID ) const {
176  checkGLError2("prev opengl error");
177  GLint location = glGetUniformLocation(_progID, id.c_str());
178  checkGLError2(id.c_str());
179 
180  switch (size){
181  case 1:
182  glUniform1fv(location, 1, val.data());
183  break;
184  case 2:
185  glUniform2fv(location, 1, val.data());
186  break;
187  case 3:
188  glUniform3fv(location, 1, val.data());
189  break;
190  case 4:
191  glUniform4fv(location, 1, val.data());
192  break;
193 
194  default:
195  std::cerr << "UniformPool::UniformVecf : invalid size " << size << std::endl;
196  break;
197  }
198 
199  checkGLError2(id.c_str());
200  }
201 
206  void UniformPool::UniformVeci::bind( GLuint _progID ) const {
207  checkGLError2("prev opengl error");
208  GLint location = glGetUniformLocation(_progID, id.c_str());
209  checkGLError2(id.c_str());
210 
211  switch (size){
212  case 1:
213  glUniform1iv(location, 1, (GLint*)val.data());
214  break;
215  case 2:
216  glUniform2iv(location, 1, (GLint*)val.data());
217  break;
218  case 3:
219  glUniform3iv(location, 1, (GLint*)val.data());
220  break;
221  case 4:
222  glUniform4iv(location, 1, (GLint*)val.data());
223  break;
224 
225  default:
226  std::cerr << "UniformPool::UniformVeci : invalid size " << size << std::endl;
227  break;
228  }
229 
230  checkGLError2(id.c_str());
231  }
232 
237  void UniformPool::UniformVecui::bind( GLuint _progID ) const {
238  checkGLError2("prev opengl error");
239  GLint location = glGetUniformLocation(_progID, id.c_str());
240  checkGLError2(id.c_str());
241 
242  switch (size){
243  case 1:
244  glUniform1uiv(location, 1, (GLuint*)val.data());
245  break;
246  case 2:
247  glUniform2uiv(location, 1, (GLuint*)val.data());
248  break;
249  case 3:
250  glUniform3uiv(location, 1, (GLuint*)val.data());
251  break;
252  case 4:
253  glUniform4uiv(location, 1, (GLuint*)val.data());
254  break;
255 
256  default:
257  std::cerr << "UniformPool::UniformVecui : invalid size " << size << std::endl;
258  break;
259  }
260 
261  checkGLError2(id.c_str());
262  }
263 
268  void UniformPool::UniformMat::bind( GLuint _progID ) const {
269  checkGLError2("prev opengl error");
270  GLint location = glGetUniformLocation(_progID, id.c_str());
271  checkGLError2(id.c_str());
272 
273  switch (size){
274  case 2: {
275  float tmp[4];
276  for (int i = 0; i < 2; ++i)
277  for (int k = 0; k < 2; ++k)
278  tmp[i*2+k] = val.data()[i*4+k];
279  glUniformMatrix2fv(location, 1, transposed, tmp);
280  } break;
281 
282  case 3: {
283  float tmp[9];
284  for (int i = 0; i < 3; ++i)
285  for (int k = 0; k < 3; ++k)
286  tmp[i*3+k] = val.data()[i*4+k];
287  glUniformMatrix3fv(location, 1, transposed, tmp);
288  } break;
289 
290  case 4: glUniformMatrix4fv(location, 1, transposed, val.data()); break;
291 
292  default:
293  std::cerr << "UniformPool::UniformMat : invalid size " << size << std::endl;
294  break;
295  }
296 
297  checkGLError2(id.c_str());
298  }
299 
304  void UniformPool::UniformBuf::bind( GLuint _progID ) const {
305  checkGLError2("prev opengl error");
306  GLint location = glGetUniformLocation(_progID, id.c_str());
307  checkGLError2(id.c_str());
308 
309  if (integer){
310  glUniform1iv(location, size, (GLint*)val);
311  }
312  else{
313  glUniform1fv(location, size, val);
314  }
315 
316  checkGLError2(id.c_str());
317  }
318 
322  : val(0), integer(false), size(0)
323  {
324  }
325 
329  delete [] val;
330  }
331 
332 
337  void UniformPool::addVecf( const UniformVecf& _vec ) {
338  // look for existing uniform in pool
339  UniformListIt it = findEntry(_vec.id);
340 
341  // storage address of uniform
342  UniformVecf* dst = 0;
343 
344  if ( it == pool_.end() ){
345  // create new entry
346  dst = new UniformVecf;
347  pool_.push_back(dst);
348  }
349  else{
350  // use existing entry
351  dst = dynamic_cast<UniformVecf*>( *it );
352 
353  if (!dst)
354  std::cerr << "UniformPool::addVecf type of " << _vec.id << " incorrect." << std::endl;
355  }
356 
357  if (dst) {
358  // update data
359  dst->id = _vec.id;
360  dst->size = _vec.size;
361  dst->val = _vec.val;
362  }
363 
364  }
365 
370  void UniformPool::addVeci( const UniformVeci& _vec ) {
371  // look for existing uniform in pool
372  UniformListIt it = findEntry(_vec.id);
373 
374  // storage address of uniform
375  UniformVeci* dst = 0;
376 
377  if ( it == pool_.end() ){
378  // create new entry
379  dst = new UniformVeci;
380  pool_.push_back(dst);
381  }
382  else{
383  // use existing entry
384  dst = dynamic_cast<UniformVeci*>( *it );
385 
386  if (!dst)
387  std::cerr << "UniformPool::addVeci type of " << _vec.id << " incorrect." << std::endl;
388  }
389 
390  if (dst) {
391  // update data
392  dst->id = _vec.id;
393  dst->size = _vec.size;
394  dst->val = _vec.val;
395  }
396 
397  }
398 
403  void UniformPool::addVecui( const UniformVecui& _vec ) {
404  // look for existing uniform in pool
405  UniformListIt it = findEntry(_vec.id);
406 
407  // storage address of uniform
408  UniformVecui* dst = 0;
409 
410  if ( it == pool_.end() ){
411  // create new entry
412  dst = new UniformVecui;
413  pool_.push_back(dst);
414  }
415  else{
416  // use existing entry
417  dst = dynamic_cast<UniformVecui*>( *it );
418 
419  if (!dst)
420  std::cerr << "UniformPool::addVecui type of " << _vec.id << " incorrect." << std::endl;
421  }
422 
423  if (dst) {
424  // update data
425  dst->id = _vec.id;
426  dst->size = _vec.size;
427  dst->val = _vec.val;
428  }
429 
430  }
431 
436  void UniformPool::addMatrix( const UniformMat& _mat ) {
437  // look for existing uniform in pool
438  UniformListIt it = findEntry(_mat.id);
439 
440  // storage address of uniform
441  UniformMat* dst = 0;
442 
443  if ( it == pool_.end() ){
444  // create new entry
445  dst = new UniformMat;
446  pool_.push_back(dst);
447  }
448  else{
449  // use existing entry
450  dst = dynamic_cast<UniformMat*>( *it );
451 
452  if (!dst)
453  std::cerr << "UniformPool::addMatrix type of " << _mat.id << " incorrect." << std::endl;
454  }
455 
456  if (dst) {
457  // update data
458  dst->id = _mat.id;
459  dst->size = _mat.size;
460  dst->transposed = _mat.transposed;
461  dst->val = _mat.val;
462  }
463  }
464 
472  void UniformPool::addBuf( const char* _name, void* _values, int _count, bool _integer ) {
473  // look for existing uniform in pool
474  UniformListIt it = findEntry(_name);
475 
476  // storage address of uniform
477  UniformBuf* dst = 0;
478 
479  if ( it == pool_.end() ){
480  // create new entry
481  dst = new UniformBuf();
482  pool_.push_back(dst);
483  }
484  else{
485  // use existing entry
486  dst = dynamic_cast<UniformBuf*>( *it );
487 
488  if (!dst)
489  std::cerr << "UniformPool::addBuf type of " << _name << " incorrect." << std::endl;
490  }
491 
492  if (dst) {
493  // update data
494  dst->id = _name;
495 
496  if (dst->size < _count)
497  {
498  // resize
499  delete [] dst->val;
500  dst->val = new float[_count];
501  }
502 
503  dst->size = _count;
504 
505  if (_values)
506  memcpy(dst->val, _values, _count * sizeof(float));
507  }
508  }
509 
510 
516  void UniformPool::setUniform( const char *_name, GLint _value ) {
517  // create uniform descriptor
518  UniformVeci tmp;
519  tmp.id = _name;
520  tmp.size = 1;
521  tmp.val[0] = _value;
522 
523  // add/update in pool
524  addVeci(tmp);
525  }
526 
532  void UniformPool::setUniform( const char *_name, const ACG::Vec2i &_value ) {
533  // create uniform descriptor
534  UniformVeci tmp;
535  tmp.id = _name;
536  tmp.size = 2;
537  tmp.val[0] = _value[0];
538  tmp.val[1] = _value[1];
539 
540  // add/update in pool
541  addVeci(tmp);
542  }
543 
549  void UniformPool::setUniform( const char *_name, const ACG::Vec3i &_value ) {
550  // create uniform descriptor
551  UniformVeci tmp;
552  tmp.id = _name;
553  tmp.size = 3;
554  tmp.val[0] = _value[0];
555  tmp.val[1] = _value[1];
556  tmp.val[2] = _value[2];
557 
558  // add/update in pool
559  addVeci(tmp);
560  }
561 
567  void UniformPool::setUniform( const char *_name, const ACG::Vec4i &_value ) {
568  // create uniform descriptor
569  UniformVeci tmp;
570  tmp.id = _name;
571  tmp.size = 4;
572  tmp.val = _value;
573 
574  // add/update in pool
575  addVeci(tmp);
576  }
577 
583  void UniformPool::setUniform( const char *_name, GLuint _value ) {
584  // create uniform descriptor
585  UniformVecui tmp;
586  tmp.id = _name;
587  tmp.size = 1;
588  tmp.val[0] = _value;
589 
590  // add/update in pool
591  addVecui(tmp);
592  }
593 
599  void UniformPool::setUniform( const char *_name, const ACG::Vec2ui &_value ) {
600  // create uniform descriptor
601  UniformVecui tmp;
602  tmp.id = _name;
603  tmp.size = 2;
604  tmp.val[0] = _value[0];
605  tmp.val[1] = _value[1];
606 
607  // add/update in pool
608  addVecui(tmp);
609  }
610 
616  void UniformPool::setUniform( const char *_name, const ACG::Vec3ui &_value ) {
617  // create uniform descriptor
618  UniformVecui tmp;
619  tmp.id = _name;
620  tmp.size = 3;
621  tmp.val[0] = _value[0];
622  tmp.val[1] = _value[1];
623  tmp.val[2] = _value[2];
624 
625  // add/update in pool
626  addVecui(tmp);
627  }
628 
634  void UniformPool::setUniform( const char *_name, const ACG::Vec4ui &_value ) {
635  // create uniform descriptor
636  UniformVecui tmp;
637  tmp.id = _name;
638  tmp.size = 4;
639  tmp.val = _value;
640 
641  // add/update in pool
642  addVecui(tmp);
643  }
644 
645 
651  void UniformPool::setUniform( const char *_name, GLfloat _value ) {
652  // create uniform descriptor
653  UniformVecf tmp;
654  tmp.id = _name;
655  tmp.size = 1;
656  tmp.val[0] = _value;
657 
658  // add/update in pool
659  addVecf(tmp);
660  }
661 
667  void UniformPool::setUniform( const char *_name, const ACG::Vec2f &_value ) {
668  // create uniform descriptor
669  UniformVecf tmp;
670  tmp.id = _name;
671  tmp.size = 2;
672  tmp.val[0] = _value[0];
673  tmp.val[1] = _value[1];
674 
675  // add/update in pool
676  addVecf(tmp);
677  }
678 
684  void UniformPool::setUniform( const char *_name, const ACG::Vec3f &_value ) {
685  // create uniform descriptor
686  UniformVecf tmp;
687  tmp.id = _name;
688  tmp.size = 3;
689  tmp.val[0] = _value[0];
690  tmp.val[1] = _value[1];
691  tmp.val[2] = _value[2];
692 
693  // add/update in pool
694  addVecf(tmp);
695  }
696 
702  void UniformPool::setUniform( const char *_name, const ACG::Vec4f &_value ) {
703  // create uniform descriptor
704  UniformVecf tmp;
705  tmp.id = _name;
706  tmp.size = 4;
707  tmp.val = _value;
708 
709  // add/update in pool
710  addVecf(tmp);
711  }
712 
719  void UniformPool::setUniform( const char *_name, const ACG::GLMatrixf &_value, bool _transposed ) {
720  // create uniform descriptor
721  UniformMat tmp;
722  tmp.id = _name;
723  tmp.transposed = _transposed;
724  tmp.size = 4;
725  tmp.val = _value;
726 
727  // add/update in pool
728  addMatrix(tmp);
729  }
730 
737  void UniformPool::setUniformMat3( const char *_name, const ACG::GLMatrixf &_value, bool _transposed ) {
738  // create uniform descriptor
739  UniformMat tmp;
740  tmp.id = _name;
741  tmp.transposed = _transposed;
742  tmp.size = 3;
743  tmp.val = _value;
744 
745  // add/update in pool
746  addMatrix(tmp);
747  }
748 
755  void UniformPool::setUniform( const char *_name, GLint *_values, int _count ) {
756  // add/update in pool
757  addBuf(_name, _values, _count, true);
758  }
759 
766  void UniformPool::setUniform( const char *_name, GLfloat *_values, int _count ) {
767  // add/update in pool
768  addBuf(_name, _values, _count, false);
769  }
770 
771 }
772 
773 
774 //==============================================================================
void addVeci(const UniformVeci &_vec)
Add or update a vector type uniform in pool.
Definition: UniformPool.cc:370
UniformList pool_
list of uniform params
Definition: UniformPool.hh:189
void clear()
Clear the pool.
Definition: UniformPool.cc:91
void bind(GLuint _progID) const
Bind uniform float vector to shader.
Definition: UniformPool.cc:175
void bind(GLuint _progID) const
Bind uniform matrix to shader.
Definition: UniformPool.cc:268
bool empty() const
returns if the pool is empty
Definition: UniformPool.cc:100
void bind(GLuint _progID) const
Bind uniform uint vector to shader.
Definition: UniformPool.cc:237
void addVecui(const UniformVecui &_vec)
Add or update a vector type uniform in pool.
Definition: UniformPool.cc:403
void bind(GLuint _progID) const
Bind uniform array to shader.
Definition: UniformPool.cc:304
virtual ~UniformPool()
Destructor.
Definition: UniformPool.cc:82
void operator=(const UniformPool &_other)
copy
Definition: UniformPool.cc:87
void addMatrix(const UniformMat &_mat)
Add or update a matrix type uniform in pool.
Definition: UniformPool.cc:436
void bind(GLuint _progID) const
Bind uniform int vector to shader.
Definition: UniformPool.cc:206
GLSL program class.
Definition: GLSLShader.hh:217
void addPool(const UniformPool &_src)
Add all uniforms of a pool to this pool.
Definition: UniformPool.cc:141
UniformListIt findEntry(std::string _name)
Search the pool for an existing value for a uniform name.
Definition: UniformPool.cc:127
void setUniformMat3(const char *_name, const ACG::GLMatrixf &_value, bool _transposed=false)
Set 3x3fMatrix uniform to specified value.
Definition: UniformPool.cc:737
This namespace contains all the classes and functions for handling GLSL shader and program objects...
Definition: AntiAliasing.hh:75
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
Definition: UniformPool.cc:516
UniformBuf()
Creates a copy of input data.
Definition: UniformPool.cc:321
GLSL uniform pool.
Definition: UniformPool.hh:71
void addBuf(const char *_name, void *_values, int _count, bool _integer)
Add or update an array type uniform in pool.
Definition: UniformPool.cc:472
void bind(PtrProgram _prog) const
Send all stored uniforms to program.
Definition: UniformPool.cc:108
UniformPool()
Constructor.
Definition: UniformPool.cc:71
GLuint getProgramId()
Returns opengl id.
Definition: GLSLShader.cc:382
void addVecf(const UniformVecf &_vec)
Add or update a vector type uniform in pool.
Definition: UniformPool.cc:337