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 
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:
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 
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:
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:
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 //=============================================================================
This namespace contains all the classes and functions for handling GLSL shader and program objects...
Definition: AntiAliasing.hh:66
bool bind(osg::GeometryPtr &_geo, Mesh &_mesh)
Definition: bindT.hh:101
Namespace providing different geometric functions concerning angles.
GLSL program class.
Definition: GLSLShader.hh:211
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
Definition: GLState.cc:1507
static void activeTexture(GLenum _texunit)
replaces glActiveTexture, no locking support
Definition: GLState.cc:1857
static void bindBuffer(GLenum _target, GLuint _buffer)
replaces glBindBuffer, supports locking
Definition: GLState.cc:1820
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
Definition: GLState.cc:1527
static void bindTexture(GLenum _target, GLuint _buffer)
replaces glBindTexture, supports locking
Definition: GLState.cc:1868