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