Developer Documentation
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#include <iostream>
44#include <QTextStream>
45
46#include <ACG/GL/acg_glew.hh>
47#include <ACG/GL/GLError.hh>
48#include "UniformPool.hh"
49
50#ifdef WIN32
51 #ifndef __MINGW32__
52 #define snprintf sprintf_s
53 #endif
54#endif
55
56//==============================================================================
57
58namespace GLSL {
59
60 //--------------------------------------------------------------------------
61 // Uniform Pool
62 //--------------------------------------------------------------------------
63
64
66 }
67
68
70 addPool(_pool);
71 }
72
73
77 clear();
78 }
79
80
82 addPool(_other);
83 return *this;
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
99
100 QString UniformPool::toString() const {
101
102 QString result;
103 QTextStream resultStrm(&result);
104
105 for (UniformList::const_iterator it = pool_.begin(); it != pool_.end(); ++it) {
106 resultStrm << (*it)->toString() << "\n";
107 }
108
109 return result;
110 }
111
116 void UniformPool::bind( PtrProgram _prog ) const {
117 bind(_prog->getProgramId());
118 }
119
124 void UniformPool::bind( GLuint _prog ) const {
125 for (UniformList::const_iterator it = pool_.begin(); it != pool_.end(); ++it) {
126 (*it)->bind(_prog);
127 }
128 }
129
135 UniformPool::UniformListIt UniformPool::findEntry( std::string _name ) {
136
137 for (UniformListIt it = pool_.begin(); it != pool_.end(); ++it){
138 if ((*it)->id.compare(_name) == 0)
139 return it;
140 }
141
142 return pool_.end();
143 }
144
150
151 for (UniformList::const_iterator it = _src.pool_.begin(); it != _src.pool_.end(); ++it){
152
153 // determine type
154 const UniformVecf* pVecf = dynamic_cast<const UniformVecf*>(*it);
155 const UniformVeci* pVeci = dynamic_cast<const UniformVeci*>(*it);
156 const UniformVecui* pVecui = dynamic_cast<const UniformVecui*>(*it);
157 const UniformMat* pMat = dynamic_cast<const UniformMat*>(*it);
158 const UniformBuf* pBuf = dynamic_cast<const UniformBuf*>(*it);
159
160 // add to our list
161 if (pVecf)
162 addVecf(*pVecf);
163
164 if (pVeci)
165 addVeci(*pVeci);
166
167 if (pVecui)
168 addVecui(*pVecui);
169
170 else if (pMat)
171 addMatrix(*pMat);
172
173 else if (pBuf)
174 addBuf(pBuf->id.c_str(), pBuf->val, pBuf->size, pBuf->integer);
175 }
176 }
177
178
183 void UniformPool::UniformVecf::bind( GLuint _progID ) const {
184 checkGLError2("prev opengl error");
185 GLint location = glGetUniformLocation(_progID, id.c_str());
186 checkGLError2(id.c_str());
187
188 switch (size){
189 case 1:
190 glUniform1fv(location, 1, val.data());
191 break;
192 case 2:
193 glUniform2fv(location, 1, val.data());
194 break;
195 case 3:
196 glUniform3fv(location, 1, val.data());
197 break;
198 case 4:
199 glUniform4fv(location, 1, val.data());
200 break;
201
202 default:
203 std::cerr << "UniformPool::UniformVecf : invalid size " << size << std::endl;
204 break;
205 }
206
207 checkGLError2(id.c_str());
208 }
209
210
215 const char* fmt = size > 1 ? "uniform vec%2 %1 = vec%2(" : "uniform float %1 = ";
216 QString str = QString(fmt).arg(id.c_str()).arg(size);
217 for (int i = 0; i < size; ++i) {
218 str += QString::number(val[i]);
219 if (i + 1 < size)
220 str += ", ";
221 }
222 if (size > 1)
223 str += ");";
224 return str;
225 }
226
231 void UniformPool::UniformVeci::bind( GLuint _progID ) const {
232 checkGLError2("prev opengl error");
233 GLint location = glGetUniformLocation(_progID, id.c_str());
234 checkGLError2(id.c_str());
235
236 switch (size){
237 case 1:
238 glUniform1iv(location, 1, (GLint*)val.data());
239 break;
240 case 2:
241 glUniform2iv(location, 1, (GLint*)val.data());
242 break;
243 case 3:
244 glUniform3iv(location, 1, (GLint*)val.data());
245 break;
246 case 4:
247 glUniform4iv(location, 1, (GLint*)val.data());
248 break;
249
250 default:
251 std::cerr << "UniformPool::UniformVeci : invalid size " << size << std::endl;
252 break;
253 }
254
255 checkGLError2(id.c_str());
256 }
257
258
263 const char* fmt = size > 1 ? "uniform ivec%2 %1 = ivec%2(" : "uniform int %1 = ";
264 QString str = QString(fmt).arg(id.c_str()).arg(size);
265 for (int i = 0; i < size; ++i) {
266 str += QString::number(val[i]);
267 if (i + 1 < size)
268 str += ", ";
269 }
270 if (size > 1)
271 str += ");";
272 return str;
273 }
274
279 void UniformPool::UniformVecui::bind( GLuint _progID ) const {
280 checkGLError2("prev opengl error");
281 GLint location = glGetUniformLocation(_progID, id.c_str());
282 checkGLError2(id.c_str());
283
284 switch (size){
285 case 1:
286 glUniform1uiv(location, 1, (GLuint*)val.data());
287 break;
288 case 2:
289 glUniform2uiv(location, 1, (GLuint*)val.data());
290 break;
291 case 3:
292 glUniform3uiv(location, 1, (GLuint*)val.data());
293 break;
294 case 4:
295 glUniform4uiv(location, 1, (GLuint*)val.data());
296 break;
297
298 default:
299 std::cerr << "UniformPool::UniformVecui : invalid size " << size << std::endl;
300 break;
301 }
302
303 checkGLError2(id.c_str());
304 }
305
306
311 const char* fmt = size > 1 ? "uniform uvec%2 %1 = uvec%2(" : "uniform uint %1 = ";
312 QString str = QString(fmt).arg(id.c_str()).arg(size);
313 for (int i = 0; i < size; ++i) {
314 str += QString::number(val[i]);
315 if (i + 1 < size)
316 str += ", ";
317 }
318 if (size > 1)
319 str += ");";
320 return str;
321 }
322
327 void UniformPool::UniformMat::bind( GLuint _progID ) const {
328 checkGLError2("prev opengl error");
329 GLint location = glGetUniformLocation(_progID, id.c_str());
330 checkGLError2(id.c_str());
331
332 switch (size){
333 case 2: {
334 float tmp[4];
335 for (int i = 0; i < 2; ++i)
336 for (int k = 0; k < 2; ++k)
337 tmp[i*2+k] = val.data()[i*4+k];
338 glUniformMatrix2fv(location, 1, transposed, tmp);
339 } break;
340
341 case 3: {
342 float tmp[9];
343 for (int i = 0; i < 3; ++i)
344 for (int k = 0; k < 3; ++k)
345 tmp[i*3+k] = val.data()[i*4+k];
346 glUniformMatrix3fv(location, 1, transposed, tmp);
347 } break;
348
349 case 4: glUniformMatrix4fv(location, 1, transposed, val.data()); break;
350
351 default:
352 std::cerr << "UniformPool::UniformMat : invalid size " << size << std::endl;
353 break;
354 }
355
356 checkGLError2(id.c_str());
357 }
358
359
364 QString str = QString("uniform mat%2 %1 = {").arg(id.c_str()).arg(size);
365 for (int y = 0; y < size; ++y) {
366 str += "{";
367 for (int x = 0; x < size; ++x) {
368 str += QString::number(val(y,x));
369 if (x + 1 < size)
370 str += ", ";
371 }
372 str += "}";
373 if (y + 1 < size)
374 str += ", ";
375 }
376 str += "};";
377 return str;
378 }
379
384 void UniformPool::UniformBuf::bind( GLuint _progID ) const {
385 checkGLError2("prev opengl error");
386 GLint location = glGetUniformLocation(_progID, id.c_str());
387 checkGLError2(id.c_str());
388
389 if (integer){
390 glUniform1iv(location, size, (GLint*)val);
391 }
392 else{
393 glUniform1fv(location, size, val);
394 }
395
396 checkGLError2(id.c_str());
397 }
398
399
404 QString str = QString("uniform %3 %2[%1] = {").arg(id.c_str()).arg(size).arg(integer ? "int" : "float");
405 for (int y = 0; y < size; ++y) {
406 if (integer)
407 str += QString::number(((GLint*)val)[y]);
408 else
409 str += QString::number(val[y]);
410 if (y + 1 < size)
411 str += ", ";
412 }
413 str += "};";
414 return str;
415 }
416
420 : val(0), integer(false), size(0)
421 {
422 }
423
427 delete [] val;
428 }
429
430
435 void UniformPool::addVecf( const UniformVecf& _vec ) {
436 // look for existing uniform in pool
437 UniformListIt it = findEntry(_vec.id);
438
439 // storage address of uniform
440 UniformVecf* dst = 0;
441
442 if ( it == pool_.end() ){
443 // create new entry
444 dst = new UniformVecf;
445 pool_.push_back(dst);
446 }
447 else{
448 // use existing entry
449 dst = dynamic_cast<UniformVecf*>( *it );
450
451 if (!dst)
452 std::cerr << "UniformPool::addVecf type of " << _vec.id << " incorrect." << std::endl;
453 }
454
455 if (dst) {
456 // update data
457 dst->id = _vec.id;
458 dst->size = _vec.size;
459 dst->val = _vec.val;
460 }
461
462 }
463
468 void UniformPool::addVeci( const UniformVeci& _vec ) {
469 // look for existing uniform in pool
470 UniformListIt it = findEntry(_vec.id);
471
472 // storage address of uniform
473 UniformVeci* dst = 0;
474
475 if ( it == pool_.end() ){
476 // create new entry
477 dst = new UniformVeci;
478 pool_.push_back(dst);
479 }
480 else{
481 // use existing entry
482 dst = dynamic_cast<UniformVeci*>( *it );
483
484 if (!dst)
485 std::cerr << "UniformPool::addVeci type of " << _vec.id << " incorrect." << std::endl;
486 }
487
488 if (dst) {
489 // update data
490 dst->id = _vec.id;
491 dst->size = _vec.size;
492 dst->val = _vec.val;
493 }
494
495 }
496
502 // look for existing uniform in pool
503 UniformListIt it = findEntry(_vec.id);
504
505 // storage address of uniform
506 UniformVecui* dst = 0;
507
508 if ( it == pool_.end() ){
509 // create new entry
510 dst = new UniformVecui;
511 pool_.push_back(dst);
512 }
513 else{
514 // use existing entry
515 dst = dynamic_cast<UniformVecui*>( *it );
516
517 if (!dst)
518 std::cerr << "UniformPool::addVecui type of " << _vec.id << " incorrect." << std::endl;
519 }
520
521 if (dst) {
522 // update data
523 dst->id = _vec.id;
524 dst->size = _vec.size;
525 dst->val = _vec.val;
526 }
527
528 }
529
534 void UniformPool::addMatrix( const UniformMat& _mat ) {
535 // look for existing uniform in pool
536 UniformListIt it = findEntry(_mat.id);
537
538 // storage address of uniform
539 UniformMat* dst = 0;
540
541 if ( it == pool_.end() ){
542 // create new entry
543 dst = new UniformMat;
544 pool_.push_back(dst);
545 }
546 else{
547 // use existing entry
548 dst = dynamic_cast<UniformMat*>( *it );
549
550 if (!dst)
551 std::cerr << "UniformPool::addMatrix type of " << _mat.id << " incorrect." << std::endl;
552 }
553
554 if (dst) {
555 // update data
556 dst->id = _mat.id;
557 dst->size = _mat.size;
558 dst->transposed = _mat.transposed;
559 dst->val = _mat.val;
560 }
561 }
562
570 void UniformPool::addBuf( const char* _name, void* _values, int _count, bool _integer ) {
571 // look for existing uniform in pool
572 UniformListIt it = findEntry(_name);
573
574 // storage address of uniform
575 UniformBuf* dst = 0;
576
577 if ( it == pool_.end() ){
578 // create new entry
579 dst = new UniformBuf();
580 pool_.push_back(dst);
581 }
582 else{
583 // use existing entry
584 dst = dynamic_cast<UniformBuf*>( *it );
585
586 if (!dst)
587 std::cerr << "UniformPool::addBuf type of " << _name << " incorrect." << std::endl;
588 }
589
590 if (dst) {
591 // update data
592 dst->id = _name;
593
594 if (dst->size < _count)
595 {
596 // resize
597 delete [] dst->val;
598 dst->val = new float[_count];
599 }
600
601 dst->size = _count;
602
603 if (_values)
604 memcpy(dst->val, _values, _count * sizeof(float));
605 }
606 }
607
608
614 void UniformPool::setUniform( const char *_name, GLint _value ) {
615 // create uniform descriptor
616 UniformVeci tmp;
617 tmp.id = _name;
618 tmp.size = 1;
619 tmp.val[0] = _value;
620
621 // add/update in pool
622 addVeci(tmp);
623 }
624
630 void UniformPool::setUniform( const char *_name, const ACG::Vec2i &_value ) {
631 // create uniform descriptor
632 UniformVeci tmp;
633 tmp.id = _name;
634 tmp.size = 2;
635 tmp.val[0] = _value[0];
636 tmp.val[1] = _value[1];
637
638 // add/update in pool
639 addVeci(tmp);
640 }
641
647 void UniformPool::setUniform( const char *_name, const ACG::Vec3i &_value ) {
648 // create uniform descriptor
649 UniformVeci tmp;
650 tmp.id = _name;
651 tmp.size = 3;
652 tmp.val[0] = _value[0];
653 tmp.val[1] = _value[1];
654 tmp.val[2] = _value[2];
655
656 // add/update in pool
657 addVeci(tmp);
658 }
659
665 void UniformPool::setUniform( const char *_name, const ACG::Vec4i &_value ) {
666 // create uniform descriptor
667 UniformVeci tmp;
668 tmp.id = _name;
669 tmp.size = 4;
670 tmp.val = _value;
671
672 // add/update in pool
673 addVeci(tmp);
674 }
675
681 void UniformPool::setUniform( const char *_name, GLuint _value ) {
682 // create uniform descriptor
683 UniformVecui tmp;
684 tmp.id = _name;
685 tmp.size = 1;
686 tmp.val[0] = _value;
687
688 // add/update in pool
689 addVecui(tmp);
690 }
691
697 void UniformPool::setUniform( const char *_name, const ACG::Vec2ui &_value ) {
698 // create uniform descriptor
699 UniformVecui tmp;
700 tmp.id = _name;
701 tmp.size = 2;
702 tmp.val[0] = _value[0];
703 tmp.val[1] = _value[1];
704
705 // add/update in pool
706 addVecui(tmp);
707 }
708
714 void UniformPool::setUniform( const char *_name, const ACG::Vec3ui &_value ) {
715 // create uniform descriptor
716 UniformVecui tmp;
717 tmp.id = _name;
718 tmp.size = 3;
719 tmp.val[0] = _value[0];
720 tmp.val[1] = _value[1];
721 tmp.val[2] = _value[2];
722
723 // add/update in pool
724 addVecui(tmp);
725 }
726
732 void UniformPool::setUniform( const char *_name, const ACG::Vec4ui &_value ) {
733 // create uniform descriptor
734 UniformVecui tmp;
735 tmp.id = _name;
736 tmp.size = 4;
737 tmp.val = _value;
738
739 // add/update in pool
740 addVecui(tmp);
741 }
742
743
749 void UniformPool::setUniform( const char *_name, GLfloat _value ) {
750 // create uniform descriptor
751 UniformVecf tmp;
752 tmp.id = _name;
753 tmp.size = 1;
754 tmp.val[0] = _value;
755
756 // add/update in pool
757 addVecf(tmp);
758 }
759
765 void UniformPool::setUniform( const char *_name, const ACG::Vec2f &_value ) {
766 // create uniform descriptor
767 UniformVecf tmp;
768 tmp.id = _name;
769 tmp.size = 2;
770 tmp.val[0] = _value[0];
771 tmp.val[1] = _value[1];
772
773 // add/update in pool
774 addVecf(tmp);
775 }
776
782 void UniformPool::setUniform( const char *_name, const ACG::Vec3f &_value ) {
783 // create uniform descriptor
784 UniformVecf tmp;
785 tmp.id = _name;
786 tmp.size = 3;
787 tmp.val[0] = _value[0];
788 tmp.val[1] = _value[1];
789 tmp.val[2] = _value[2];
790
791 // add/update in pool
792 addVecf(tmp);
793 }
794
800 void UniformPool::setUniform( const char *_name, const ACG::Vec4f &_value ) {
801 // create uniform descriptor
802 UniformVecf tmp;
803 tmp.id = _name;
804 tmp.size = 4;
805 tmp.val = _value;
806
807 // add/update in pool
808 addVecf(tmp);
809 }
810
817 void UniformPool::setUniform( const char *_name, const ACG::GLMatrixf &_value, bool _transposed ) {
818 // create uniform descriptor
819 UniformMat tmp;
820 tmp.id = _name;
821 tmp.transposed = _transposed;
822 tmp.size = 4;
823 tmp.val = _value;
824
825 // add/update in pool
826 addMatrix(tmp);
827 }
828
835 void UniformPool::setUniformMat3( const char *_name, const ACG::GLMatrixf &_value, bool _transposed ) {
836 // create uniform descriptor
837 UniformMat tmp;
838 tmp.id = _name;
839 tmp.transposed = _transposed;
840 tmp.size = 3;
841 tmp.val = _value;
842
843 // add/update in pool
844 addMatrix(tmp);
845 }
846
853 void UniformPool::setUniform( const char *_name, GLint *_values, int _count ) {
854 // add/update in pool
855 addBuf(_name, _values, _count, true);
856 }
857
864 void UniformPool::setUniform( const char *_name, GLfloat *_values, int _count ) {
865 // add/update in pool
866 addBuf(_name, _values, _count, false);
867 }
868
869}
870
871
872//==============================================================================
GLSL program class.
Definition: GLSLShader.hh:211
GLuint getProgramId()
Returns opengl id.
Definition: GLSLShader.cc:376
GLSL uniform pool.
Definition: UniformPool.hh:64
UniformListIt findEntry(std::string _name)
Search the pool for an existing value for a uniform name.
Definition: UniformPool.cc:135
void addBuf(const char *_name, void *_values, int _count, bool _integer)
Add or update an array type uniform in pool.
Definition: UniformPool.cc:570
UniformPool()
Constructor.
Definition: UniformPool.cc:65
void addPool(const UniformPool &_src)
Add all uniforms of a pool to this pool.
Definition: UniformPool.cc:149
void clear()
Clear the pool.
Definition: UniformPool.cc:86
void addVecf(const UniformVecf &_vec)
Add or update a vector type uniform in pool.
Definition: UniformPool.cc:435
void addVecui(const UniformVecui &_vec)
Add or update a vector type uniform in pool.
Definition: UniformPool.cc:501
bool empty() const
returns if the pool is empty
Definition: UniformPool.cc:95
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
Definition: UniformPool.cc:614
UniformList pool_
list of uniform params
Definition: UniformPool.hh:199
void bind(PtrProgram _prog) const
Send all stored uniforms to program.
Definition: UniformPool.cc:116
void setUniformMat3(const char *_name, const ACG::GLMatrixf &_value, bool _transposed=false)
Set 3x3fMatrix uniform to specified value.
Definition: UniformPool.cc:835
void addMatrix(const UniformMat &_mat)
Add or update a matrix type uniform in pool.
Definition: UniformPool.cc:534
QString toString() const
print to string for debugging
Definition: UniformPool.cc:100
UniformPool & operator=(const UniformPool &_other)
copy
Definition: UniformPool.cc:81
void addVeci(const UniformVeci &_vec)
Add or update a vector type uniform in pool.
Definition: UniformPool.cc:468
virtual ~UniformPool()
Destructor.
Definition: UniformPool.cc:76
Scalar * data()
access to Scalar array
Definition: Vector11T.hh:201
This namespace contains all the classes and functions for handling GLSL shader and program objects.
Definition: AntiAliasing.hh:66
UniformBuf()
Creates a copy of input data.
Definition: UniformPool.cc:419
void bind(GLuint _progID) const override
Bind uniform array to shader.
Definition: UniformPool.cc:384
virtual QString toString() const override
print buffer id to string
Definition: UniformPool.cc:403
void bind(GLuint _progID) const override
Bind uniform matrix to shader.
Definition: UniformPool.cc:327
virtual QString toString() const override
print matrix to string
Definition: UniformPool.cc:363
void bind(GLuint _progID) const override
Bind uniform float vector to shader.
Definition: UniformPool.cc:183
virtual QString toString() const override
print float vector to string
Definition: UniformPool.cc:214
virtual QString toString() const override
print int vector to string
Definition: UniformPool.cc:262
void bind(GLuint _progID) const override
Bind uniform int vector to shader.
Definition: UniformPool.cc:231
void bind(GLuint _progID) const override
Bind uniform uint vector to shader.
Definition: UniformPool.cc:279
virtual QString toString() const override
print uint vector to string
Definition: UniformPool.cc:310