Developer Documentation

globjects.hh
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 //
45 // OpenGL Objects
46 //
47 //=============================================================================
48
49
50 #ifndef GL_OBJECTS_HH
51 #define GL_OBJECTS_HH
52
53
54 //== INCLUDES =================================================================
55
56 // GL
57 #include <ACG/GL/gl.hh>
58 #include <ACG/GL/GLState.hh>
59
60 // C++
61 #include <iostream>
62 #include <fstream>
63 #include <string>
64 #include <map>
65 #include <vector>
66
67 // C
68 #include <cstdio>
69 #include <cstring>
70
71 #ifdef max
72 # undef max
73 #endif
74
75 #ifdef min
76 # undef min
77 #endif
78
79
80 //== NAMESPACES ===============================================================
81
82 namespace GLSL {
83 class Program; // prototype
84 }
85
86 namespace ACG {
87
88
89 //== CLASS DEFINITION =========================================================
90
91
92 class DisplayList
93 {
94 public:
95
96 DisplayList() : valid(false) {}
97
98 virtual ~DisplayList() { del(); }
99
100 void call() { if (valid) glCallList(dlist); }
101
102 void new_list(GLenum mode) { if(!valid) gen(); glNewList(dlist, mode); }
103
104 void end_list() { glEndList(); }
105
106 void del() { if(valid) glDeleteLists(dlist, 1); valid = false; }
107
108 bool is_valid() const { return valid; }
109
110 private:
111
112 void gen() { dlist = glGenLists(1); valid=true; }
113
114 bool valid;
115 GLuint dlist;
116 };
117
118
119 //== CLASS DEFINITION =========================================================
120
121
122 #if defined(GL_VERSION_1_5)
123
124 class ACGDLLEXPORT VertexBufferObject
125 {
126 public:
127
128 VertexBufferObject(GLenum _target) : target(_target), valid(false), vbo(0u) {}
129
130 virtual ~VertexBufferObject() { del(); }
131
132 void del();
133 bool is_valid() const { return valid; }
134
135 void bind() { if(!valid) gen(); ACG::GLState::bindBuffer(target, vbo); }
136 void unbind() { ACG::GLState::bindBuffer(target, 0); }
137
138 void upload(GLsizeiptr size, const GLvoid* data, GLenum usage);
139
140 // Upload a subset of the buffer data
141 void uploadSubData(GLuint _offset, GLuint _size, const GLvoid* _data );
142
143 char* offset(unsigned int _offset) const
144 {
145 return reinterpret_cast<char*>(_offset);
146 }
147
148 GLuint id() const {return vbo;}
149
150 int size();
151
152 private:
153
154 void gen();
155
156 GLenum target;
157 bool valid;
158 GLuint vbo;
159
160 };
161
162
163 class GeometryBuffer : public VertexBufferObject
164 {
165 public:
166 GeometryBuffer() : VertexBufferObject(GL_ARRAY_BUFFER) {}
167 };
168
169
170 class IndexBuffer : public VertexBufferObject
171 {
172 public:
173 IndexBuffer() : VertexBufferObject(GL_ELEMENT_ARRAY_BUFFER) {}
174 };
175
176
177 #endif
178
179
180 /* Vertex array object
181 https://www.opengl.org/wiki/Vertex_Specification#Vertex_Array_Object
182
183 A VAO is a state collection for vertex, index buffers and vertex attribute locations.
184 It basically stores all vertex and index buffer related opengl states.
185 Maybe Vertex- or GeometryInputState is a more fitting name for this class..
186
187 extension: https://www.opengl.org/registry/specs/ARB/vertex_array_object.txt
188 opengl-core: 3.0
189
190
191 usage:
192
193 setup VAO:
194 vao.bind()
195 usual opengl setup of vertex and indexbuffer and attribute locations
196
197 draw with VAO:
198 vao.bind()
199 glDraw..()
200 */
201 class ACGDLLEXPORT VertexArrayObject
202 {
203 public:
204 VertexArrayObject();
205 virtual ~VertexArrayObject();
206
207 // check hardware support
208 static bool isSupported();
209
210 void bind();
211 void unbind();
212
213 // implicitly called on bind(), but can be used to reset the VAO
214 void init();
215
216 // opengl object id
217 GLuint id() const {return id_;}
218
219 bool is_valid() const {return id_ != 0;}
220
221 operator GLuint() const {return id_;}
222
223 private:
224 GLuint id_;
225
226 static int supportStatus_;
227 };
228
229
230
231 //== CLASS DEFINITION =========================================================
232
233
234 class ACGDLLEXPORT Texture
235 {
236 public:
237
238 Texture(GLenum tgt, GLenum _unit=GL_NONE);
239
240 virtual ~Texture() { del(); }
241
242
243 void bind(GLenum _unit)
244 {
245 if(!valid) gen();
246 activate(_unit);
247 ACG::GLState::bindTexture(target, texture);
248 }
249
250 void activate(GLenum _unit)
251 {
252 if (_unit != GL_NONE) ACG::GLState::activeTexture(_unit);
253 }
254
255 void bind() { bind(unit); }
256
257 void activate() { activate(unit); }
258
259 void parameter(GLenum pname, GLint i)
260 {
261 activate();
262 glTexParameteri(target, pname, i);
263 }
264
265 void parameter(GLenum pname, GLfloat f)
266 {
267 activate();
268 glTexParameterf(target, pname, f);
269 }
270
271 void parameter(GLenum pname, GLint * ip)
272 {
273 activate();
274 glTexParameteriv(target, pname, ip);
275 }
276
277 void parameter(GLenum pname, GLfloat * fp)
278 {
279 activate();
280 glTexParameterfv(target, pname, fp);
281 }
282
283 void enable()
284 {
285 activate();
286 ACG::GLState::enable(target);
287 }
288
289 void disable()
290 {
291 activate();
292 ACG::GLState::disable(target);
293 }
294
295 void del()
296 {
297 if(valid) glDeleteTextures(1, &texture);
298 valid = false;
299 }
300
301 void gen() { glGenTextures(1, &texture); valid = (texture > 0u ? true : valid); }
302
303 bool is_valid() const { return valid; }
304
305 GLuint id() const { return texture; }
306
307 void setUnit(GLenum u) {unit = u;}
308 GLenum getUnit() const { return unit; }
309 GLenum getTarget() const {return target;}
310
311 // note: might bind the texture in order to find the format
312 GLint getInternalFormat();
313
314
315 // check supportsClearTexture to find out whether clear is supported (ARB_clear_texture)
316 // clear does not work for buffer textures!
317
318 // clear normalized / floating point texture
319 bool clear(const ACG::Vec4f& _color);
320
321 // clear integer texture
322 bool clear(const ACG::Vec4i& _color);
323 bool clear(const ACG::Vec4ui& _color);
324
325
326 // use texture as image load/store (equivalent of unordered access buffers in dx11)
327 // allows data scattering operations in shader ie. random read/write access
328 // ref: https://www.opengl.org/registry/specs/ARB/shader_image_load_store.txt
329 // _index zero-based image unit
330 // _access access operations in shader: GL_READ_WRITE, GL_READ_ONLY, GL_WRITE_ONLY
331 // requires opengl 4.2
332 void bindAsImage(GLuint _index, GLenum _access);
333
334 // test for shader_image_load_store support
335 static bool supportsImageLoadStore();
336
337 // test for texture buffer support
338 static bool supportsTextureBuffer();
339
340 // test for clear_texture support
341 static bool supportsClearTexture();
342
343 // test for hardware accelerated mip map generation
344 static bool supportsGenerateMipmap();
345
346 private:
347
348 GLenum target, unit;
349 bool valid;
350 GLuint texture;
351
352 protected:
353 GLint internalFormat_;
354 };
355
356
357 //-----------------------------------------------------------------------------
358
359
360 class ACGDLLEXPORT Texture1D : public Texture
361 {
362 public:
363 Texture1D(GLenum unit=GL_NONE);
364
365 // initialize and set texture data via glTexImage1D
366 void setData(GLint _level, GLint _internalFormat, GLsizei _width, GLenum _format, GLenum _type, const GLvoid* _data);
367
368 // specify storage of texture (OpenGL 4.2)
369 // use setData with a nullptr instead if 4.2 is not available
370 void setStorage(GLsizei _levels, GLenum _internalFormat, GLsizei _width);
371
372 // get params from glTexImage1D
373 GLsizei getWidth() const {return width_;}
374 GLenum getFormat() const {return format_;}
375 GLenum getType() const {return type_;}
376
377 // read data back to sysmem
378 bool getData(GLint _level, void* _dst);
379 bool getData(GLint _level, std::vector<char>& _dst);
380
381 private:
382
383 GLsizei width_;
384 GLenum format_, type_;
385 };
386
387
388 //-----------------------------------------------------------------------------
389
390
391 class ACGDLLEXPORT Texture2D : public Texture
392 {
393 public:
394 Texture2D(GLenum unit=GL_NONE);
395
396 // Enable automatic mipmap generation (either on gpu or cpu).
397 // The mipmap chain is generated the next time the base level of the texture is changed.
398 // So this should be called after bind() but before setData()!
399 // returns true if the hardware supports this feature, false if it runs in software mode
400 bool autogenerateMipMaps();
401
402 // Disabled automatic generation of the mip map chain
403 void disableAutogenerateMipMaps();
404
405 // initialize and set texture data via glTexImage2D
406 void setData(GLint _level, GLint _internalFormat, GLsizei _width, GLsizei _height, GLenum _format, GLenum _type, const GLvoid* _data, bool _mipmaps = false);
407
408 // specify storage of texture (OpenGL 4.2)
409 // use setData with a nullptr instead if 4.2 is not available
410 void setStorage(GLsizei _levels, GLenum _internalFormat, GLsizei _width, GLsizei _height);
411
412 // initialize and load from file
413 // supports png, jpg etc. (any format that can be loaded by qt)
414 // additionally supports dds if the gli library is available while building ACG
415 bool loadFromFile(const std::string& _filename, GLenum _minFilter = GL_NEAREST_MIPMAP_LINEAR, GLenum _magFilter = GL_LINEAR);
416
417 // initialize and fill with uniform random data in [0,1] (or [-1,1] for signed formats)
418 void loadRandom(GLint _internalFormat, GLsizei _width, GLsizei _height);
419
420 // get params from glTexImage2D
421 GLsizei getWidth() const {return width_;}
422 GLsizei getHeight() const {return height_;}
423 GLenum getFormat() const {return format_;}
424 GLenum getType() const {return type_;}
425
426 // read data back to sysmem
427 bool getData(GLint _level, void* _dst);
428 bool getData(GLint _level, std::vector<char>& _dst);
429
430 // check if there is enough mem space to allocate a texture of requested size and format
431 static bool checkTextureMem(GLenum _internalFormat, GLsizei _width, GLsizei _height,
432 GLenum _format);
433
434 private:
435
436 // build mipmap chain on cpu
437 void buildMipMaps(GLenum _internalfmt,
438 GLint _width,
439 GLint _height,
440 GLenum _format,
441 GLenum _type,
442 const void* _data);
443
444 private:
445
446 GLsizei width_, height_;
447 GLenum format_, type_;
448
449 bool buildMipsCPU_;
450 };
451
452
453 //-----------------------------------------------------------------------------
454
455
456 class Texture3D : public Texture
457 {
458 public:
459 Texture3D(GLenum unit=GL_NONE) : Texture(GL_TEXTURE_3D, unit) {}
460 };
461
462
463 //-----------------------------------------------------------------------------
464
465
466 #if defined(GL_ARB_texture_cube_map)
467
468 class TextureCubeMap : public Texture
469 {
470 public:
471 TextureCubeMap(GLenum u=GL_NONE) : Texture(GL_TEXTURE_CUBE_MAP_ARB, u) {}
472 };
473
474 #elif defined(GL_EXT_texture_cube_map)
475
476 class TextureCubeMap : public Texture
477 {
478 public:
479 TextureCubeMap(GLenum u=GL_NONE) : Texture(GL_TEXTURE_CUBE_MAP_EXT, u) {}
480 };
481
482 #endif
483
484
485 //-----------------------------------------------------------------------------
486
487
488 #if defined(GL_EXT_texture_rectangle)
489
490 class TextureRectangleEXT : public Texture
491 {
492 public:
493 TextureRectangleEXT(GLenum u=GL_NONE)
494 : Texture(GL_TEXTURE_RECTANGLE_EXT, u) {}
495 };
496
497 #endif
498
499
500 #if defined(GL_NV_texture_rectangle)
501
502 class TextureRectangleNV : public Texture
503 {
504 public:
505 TextureRectangleNV(GLenum u=GL_NONE)
506 : Texture(GL_TEXTURE_RECTANGLE_NV, u) {}
507 };
508
509 #endif
510
511
512
513 class ACGDLLEXPORT TextureBuffer : public Texture
514 {
515 public:
516 TextureBuffer(GLenum u=GL_NONE);
517
518 ~TextureBuffer();
519
520 // _size size in bytes of buffer data
521 // _data buffer data
522 // _internalFormat format of buffer - http://www.opengl.org/sdk/docs/man3/xhtml/glTexBuffer.xml
523 // _usage buffer usage hint - https://www.opengl.org/sdk/docs/man3/xhtml/glBufferData.xml
524 void setBufferData(size_t _size, const void* _data, GLenum _internalFormat, GLenum _usage = GL_STATIC_DRAW);
525
526 size_t getBufferSize() const {return bufferSize_;}
527
528 GLuint getBufferId() const {return buffer_;}
529
530 GLenum getUsage() const {return usage_;}
531
532 GLenum getFormat() const {return fmt_;}
533
534
535 // read buffer data back to sysmem
536 bool getBufferData(void* _dst);
537 bool getBufferData(std::vector<char>& _dst);
538
539 private:
540
541 size_t bufferSize_;
542 GLuint buffer_;
543 GLenum usage_;
544 GLenum fmt_;
545 };
546
547
548
549
550 //== CLASS DEFINITION =========================================================
551
552
553 class ProgramBase
554 {
555 public:
556
557 ProgramBase(GLenum tgt) : valid(false), target(tgt), program(0) {}
558 virtual ~ProgramBase() {}
559
560 bool is_valid() const { return valid; }
561 GLuint id() const { return program; }
562
563 virtual void bind() = 0;
564 virtual void unbind() = 0;
565 virtual bool load(const char* prog_text) = 0;
566
567 bool load_file(const char* _filename)
568 {
569 std::ifstream ifs(_filename);
570 if (!ifs)
571 {
572 std::cerr << "Can't open " << _filename << "\n";
573 return false;
574 }
575 std::string prog;
576 char line[255];
577 while (!ifs.eof())
578 {
579 if (!ifs.getline(line, 255).bad())
580 {
581 prog += std::string(line);
582 prog += '\n';
583 }
584 }
585 ifs.close();
586 return load(prog.c_str());
587 }
588
589
590 protected:
591
592 bool valid;
593 GLenum target;
594 GLuint program;
595 };
596
597
598 //== CLASS DEFINITION =========================================================
599
600
601 #if defined(GL_NV_vertex_program) || defined(GL_NV_fragment_program)
602
603 class ProgramBaseNV : public ProgramBase
604 {
605 public:
606
607 ProgramBaseNV(GLenum tgt) : ProgramBase(tgt) {}
608 ~ProgramBaseNV() { del(); }
609
610 void bind();
611 void unbind();
612
613 bool load(const char* prog_text);
614
615
616 private:
617 void gen();
618 void del();
619 };
620
621 #endif
622
623
624 //== CLASS DEFINITION =========================================================
625
626
627 #if defined(GL_ARB_vertex_program) || defined(GL_ARB_fragment_program)
628
629 class ProgramBaseARB : public ProgramBase
630 {
631 public:
632
633 ProgramBaseARB(GLenum tgt) : ProgramBase(tgt) {}
634 ~ProgramBaseARB() { del(); }
635
636 void bind();
637 void unbind();
638
639 bool load(const char* prog_text);
640
641 void parameter() {}
642
643 private:
644 void gen();
645 void del();
646 };
647
648 #endif
649
650
651 //-----------------------------------------------------------------------------
652
653
654 #if defined(GL_NV_vertex_program)
655
656 class VertexProgramNV : public ProgramBaseNV
657 {
658 public:
659 VertexProgramNV() : ProgramBaseNV(GL_VERTEX_PROGRAM_NV) {}
660 };
661
662
663 class VertexStateProgramNV : public ProgramBaseNV
664 {
665 public:
666 VertexStateProgramNV() : ProgramBaseNV(GL_VERTEX_STATE_PROGRAM_NV) {}
667 };
668
669 #endif
670
671
672 //-----------------------------------------------------------------------------
673
674
675 #if defined(GL_NV_fragment_program)
676
677 class FragmentProgramNV : public ProgramBaseNV
678 {
679 public:
680 FragmentProgramNV() : ProgramBaseNV(GL_FRAGMENT_PROGRAM_NV) {}
681 };
682
683 #endif
684
685
686
687 //-----------------------------------------------------------------------------
688
689
690 #if defined(GL_ARB_vertex_program)
691
692 class VertexProgramARB : public ProgramBaseARB
693 {
694 public:
695 VertexProgramARB() : ProgramBaseARB(GL_VERTEX_PROGRAM_ARB) {}
696 };
697
698 #endif
699
700
701 //-----------------------------------------------------------------------------
702
703
704 #if defined(GL_ARB_fragment_program)
705
706 class FragmentProgramARB : public ProgramBaseARB
707 {
708 public:
709 FragmentProgramARB() : ProgramBaseARB(GL_FRAGMENT_PROGRAM_ARB) {}
710 };
711
712 #endif
713
714
715 //== CLASS DEFINITION =========================================================
716
717 /*
718 Atomic counter for shaders:
719 http://www.opengl.org/wiki/Atomic_Counter
720
721 This is a global counter that can be incremented/decremented within shaders.
722 Counting is atomic for all shader invocations (ie. inc/decrement is thread-safe in parallel invocations)
723
724 extension: http://www.opengl.org/registry/specs/ARB/shader_atomic_counters.txt
725 opengl-core: 4.2
726
727 usage:
728 counter is initialized implicitly or explicitly via init(num)
729 -> reset counter via set()
730 -> call bind() before rendering
731 -> in shader:
732 layout(binding = 0, offset = 0) uniform atomic_uint myCounter;
733 ...
734
735 uint counterVal = atomicCounter(myCounter);
736 counterVal = atomicCounterIncrement(myCounter);
737 counterVal = atomicCounterDecrement(myCounter);
738 */
739 class ACGDLLEXPORT AtomicCounter
740 {
741 public:
742 // _numCounters number of counters in the buffer, each counter is a uint value
743 AtomicCounter(int _numCounters = 1);
744
745 virtual ~AtomicCounter();
746
747 // create counter buffer, implicitly called for a single counter value
748 void init();
749
750 // set counter value
751 void set(unsigned int _value = 0);
752
753 // read counter values after rendering
754 // _out ptr to array of size numCounters_, receiving the actual counter values
755 void get(unsigned int* _out);
756
757 // bind
758 void bind();
759
760 // bind to index corresponding to binding point in shader: layout (binding = _index)
761 void bind(GLuint _index);
762
763 // deactivate
764 void unbind();
765
766 // check hardware support
767 static bool isSupported();
768
769 bool isValid() const;
770
771 GLuint getBufferId() const {return buffer_;}
772 int getNumCounters() const {return numCounters_;}
773
774 private:
775
776 int numCounters_;
777 GLuint buffer_;
778
779 static int supportStatus_;
780 };
781
782 //== CLASS DEFINITION =========================================================
783
784
785 /*
786 Query object (occlusion queries):
787
788 ref: https://www.opengl.org/wiki/Query_Object
789 opengl-core: 1.5
790
791 usage:
792 query.begin(GL_SAMPLES_PASSED);
793 .. gl-calls
794 query.end();
795 GLuint numSamples = query.result();
796
797 \note result() method synchronizes CPU and GPU, so this might stall the cpu
798 */
799
800 class ACGDLLEXPORT QueryObject
801 {
802 public:
803
804 // set the type of the query object:
805 // GL_SAMPLES_PASSED - number of samples that passed the depth test
806 // GL_ANY_SAMPLES_PASSED - return true iff there is at least one sample that passed the depth test (gl 3.3+)
807 // GL_ANY_SAMPLES_PASSED_CONSERVATIVE - return true if there might be a sample that passed the depth test (gl 4.3+)
808 // GL_TIME_ELAPSED - measure elapsed time (gl 3.3+)
809 // also see: https://www.opengl.org/sdk/docs/man/docbook4/xhtml/glBeginQuery.xml
810 QueryObject(GLenum _type = GL_SAMPLES_PASSED);
811 virtual ~QueryObject();
812
814 void begin();
815
817 void end();
818
820 bool available() const;
821
823 GLuint result() const;
824
825 private:
826
827 GLuint id_;
828 int state_; // -1 : not started, 0 : started, 1 : stopped
829 GLenum type_;
830 };
831
832
833 //== CLASS DEFINITION =========================================================
834
835 /*
836 Timer query:
837
838 Performance counter for profiling GPU timings
839
840 extension: https://www.opengl.org/registry/specs/ARB/timer_query.txt
841 opengl-core: 3.2
842
843 usage:
844 counter.restart();
845 .. gl-calls
846 GLuint64 ns = counter.elapsedNs();
847
848 \note elapsedX() methods synchronize CPU and GPU, so this has a performance hit on CPU side
849 */
850 class ACGDLLEXPORT QueryCounter
851 {
852 public:
853 QueryCounter();
854 virtual ~QueryCounter();
855
856 void restart();
857 void stop();
858
860 GLuint64 elapsedNs();
861
863 GLuint64 elapsedMs();
864
866 float elapsedSecs();
867
869 static bool isSupported();
870
871 private:
872
873 GLuint queryObjects_[2];
874 int state_; // -1 : not started, 0 : started, 1 : stopped
875
876 static int supportStatus_;
877 };
878
879
880
881 //== CLASS DEFINITION =========================================================
882
883 /*
884 Uniform buffer object:
885 https://www.opengl.org/wiki/Uniform_Buffer_Object
886
887 Grouping shader uniforms into a buffer allows to reuse
888 the same set of uniforms across multiple shaders.
889 Also avoids having to call lots of setUniform functions.
890
891 extension: https://www.opengl.org/registry/specs/ARB/uniform_buffer_object.txt
892 opengl-core: 3.1
893
894 usage:
895 ACG::Vec4f vec0 = ..;
896 ubo.setUniformData(shader, "blockName", "uniformName0", vec0.data());
897
898 bind to a binding index:
899 ubo.bind(idx);
900 shader->setUniformBlockBinding(idx);
901
902 in shader:
903 uniform blockName
904 {
905 vec4 uniformName0;
906 vec4 uniformName1;
907 ..
908 };
909
910 */
911 class ACGDLLEXPORT UniformBufferObject : public VertexBufferObject
912 {
913 public:
914 UniformBufferObject();
915
916 virtual ~UniformBufferObject();
917
918 // set data for a uniform (makes a byte-wise)
919 // if _delay is true, the buffer is only locally changed and must be updated later via upload().
920 // otherwise, the buffer is immediately updated via glBufferSubData
921 void setUniformData(GLSL::Program* _prog, const char* _bufferName, const char* _uniformName, const void* _data, int _datasize, bool _delay = false);
922
923 // upload the buffer after delayed initialization via setUniformData
924 void upload();
925
926 // use this to bind to a shader binding point
927 void bind(GLuint _index);
928
929 // check hardware support
930 static bool isSupported();
931
932 // get hw caps
933 static int getMaxBindings();
934 static int getMaxBlocksize();
935 static int getMaxCombinedShaderBlocks();
936 static int getOffsetAlignment();
937
938 private:
939
940 // buffer data (optional)
941 std::vector<char> data_;
942
943 static void queryCaps();
944
945 // hw caps
946 static int supportStatus_;
947 static int maxBlockSize_;
948 static int maxBindings_;
949 static int maxCombinedShaderBlocks_;
950 static int offsetAlignment_;
951 };
952
953
954 //== CLASS DEFINITION =========================================================
955
956 /*
957 Shader storage buffer object:
958 http://www.opengl.org/wiki/Shader_Storage_Buffer_Object
959
960 Similar to uniform buffer object and also texture buffer.
961 Can be read and written to from within shaders.
962 Also, the size of a SSBO is typically only bounded by the physical VRAM limitation,
963 so it should be used for large data sets or unknown sized arrays.
964
965 extension: https://www.opengl.org/registry/specs/ARB/shader_storage_buffer_object.txt
966 opengl-core: 4.3
967
968 usage:
969 init on application-side with data:
970 ssbo.bind();
971 ssbo.upload(datasize, dataptr, GL_DYNAMIC_DRAW);
972
973 bind to a binding index:
974 ssbo.bind(idx);
975
976 in shader:
977 layout (stdxxx, binding = idx) buffer mySSBO
978 {
979 vec4 v4;
980 vec4 v_unbounded[];
981 };
982
983 */
984 class ACGDLLEXPORT ShaderStorageBufferObject : public VertexBufferObject
985 {
986 public:
987 ShaderStorageBufferObject();
988
989 virtual ~ShaderStorageBufferObject();
990
991 // use this to bind to a shader binding point
992 void bind(GLuint _index);
993
994 // check hardware support
995 static bool isSupported();
996
997 // get hw caps
998 static int getMaxBindings();
999 static int getMaxBlocksize();
1000 static int getMaxCombinedShaderBlocks();
1001
1002 private:
1003
1004 static void queryCaps();
1005
1006 // hw caps
1007 static int supportStatus_;
1008 static int maxBlockSize_;
1009 static int maxBindings_;
1010 static int maxCombinedShaderBlocks_;
1011 };
1012
1013
1014
1015 //=============================================================================
1016 } // namespace ACG
1017 //=============================================================================
1018 #endif // GL_OBJECTS_HH defined
1019 //=============================================================================
ACG::GLState::enable
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
Definition: GLState.cc:1507
ACG::QueryObject
Definition: globjects.hh:800
ACG::TextureBuffer
Definition: globjects.hh:513
ACG
Namespace providing different geometric functions concerning angles.
Definition: BaseObjectData.hh:68
ACG::VertexArrayObject
Definition: globjects.hh:201
ACG::AtomicCounter
Definition: globjects.hh:739
ACG::GLState::bindTexture
static void bindTexture(GLenum _target, GLuint _buffer)
replaces glBindTexture, supports locking
Definition: GLState.cc:1868
ACG::Texture2D
Definition: globjects.hh:391
OpenMesh::VectorT
Definition: Vector11T.hh:83
ACG::GLState::disable
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
Definition: GLState.cc:1527
GLSL::Program
GLSL program class.
Definition: GLSLShader.hh:211
GLSL
This namespace contains all the classes and functions for handling GLSL shader and program objects...
Definition: AntiAliasing.hh:66
OpenMesh::Kernel_OSG::bind
bool bind(osg::GeometryPtr &_geo, Mesh &_mesh)
Definition: bindT.hh:101
VectorT< signed int, 4 >
ACG::Texture3D
Definition: globjects.hh:456
ACG::QueryCounter
Definition: globjects.hh:850
ACG::Texture1D
Definition: globjects.hh:360
ACG::ShaderStorageBufferObject
Definition: globjects.hh:984
ACG::Texture
Definition: globjects.hh:234
ACG::DisplayList
Definition: globjects.hh:92
ACG::GLState::bindBuffer
static void bindBuffer(GLenum _target, GLuint _buffer)
replaces glBindBuffer, supports locking
Definition: GLState.cc:1820
ACG::UniformBufferObject
Definition: globjects.hh:911
ACG::GLState::activeTexture
static void activeTexture(GLenum _texunit)
replaces glActiveTexture, no locking support
Definition: GLState.cc:1857
ACG::ProgramBase
Definition: globjects.hh:553