SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
SLGLVertexArray.h
Go to the documentation of this file.
1 /**
2  * \file SLGLVertexArray.h
3  * \brief Wrapper class around OpenGL Vertex Array Objects (VAO)
4  * \date January 2016
5  * \authors Marcus Hudritsch
6  * \copyright http://opensource.org/licenses/GPL-3.0
7  * \remarks Please use clangformat to format the code. See more code style on
8  * https://github.com/cpvrlab/SLProject4/wiki/SLProject-Coding-Style
9 */
10 
11 #ifndef SLGLVERTEXARRAY_H
12 #define SLGLVERTEXARRAY_H
13 
14 #include <SLGLEnums.h>
15 #include <SLGLVertexBuffer.h>
16 
17 //-----------------------------------------------------------------------------
18 //! SLGLVertexArray encapsulates the core OpenGL drawing
19 /*! An SLGLVertexArray instance handles all OpenGL drawing with an OpenGL
20  Vertex Array Object (VAO), a vertex buffer objects (VBO) for the attributes
21  and an index buffer for element drawing. Attributes can be stored in a float
22  VBO of type SLGLVertexBuffer.\n
23  VAOs where introduces OpenGL 3.0 and reduce the overhead per draw call.
24  All vertex attributes (e.g. position, normals, texture coords, etc.) must be
25  float at the input. All float attributes will be in one VBO (_vbo).
26  Vertices can be drawn either directly as in the array (SLGLVertexArray::drawArrayAs)
27  or by element (SLGLVertexArray::drawElementsAs) with a separate indices buffer.\n
28  The setup of a VAO has multiple steps:\n
29  - Define one ore more attributes with SLGLVertexArray::setAttrib.
30  - Define the index array for element drawing with SLGLVertexArray::setIndices.
31  - Generate the OpenGL VAO and VBO with SLGLVertexArray::generate.\n
32  It is important that the data structures passed in SLGLVertexArray::setAttrib and
33  SLGLVertexArray::setIndices are still present when generate is called.
34  The VAO has no or one active index buffer. For drawArrayAs no indices are needed.
35  For drawElementsAs the index buffer is used. For triangle meshes also hard edges
36  are generated. Their indices are stored behind the indices of the triangles.
37  See SLMesh::computeHardEdgesIndices for more infos on hard edges.
38 */
40 {
41 public:
44 
45  //! Deletes all vertex array & vertex buffer objects
46  void deleteGL();
47 
48  //! Clears the attribute definition
49  void clearAttribs()
50  {
51  deleteGL();
52  _vbo.clear();
53  }
54 
55  //! Returns either the VAO id or the VBO id
56  SLuint vaoID() const { return _vaoID; }
57 
58  //! Returns the TFO id
59  SLuint tfoID() const { return _tfoID; }
60 
61  //! Adds a vertex attribute with data pointer and an element size
62  void setAttrib(SLGLAttributeType type,
63  SLint elementSize,
64  SLint location,
65  void* dataPointer,
66  SLGLBufferType dataType = BT_float);
67 
68  //! Adds a vertex attribute with vector of SLuint
70  SLint location,
71  SLVuint* data) { setAttrib(type, 1, location, &data->operator[](0), BT_uint); }
72 
73  //! Adds a vertex attribute with vector of SLfloat
75  SLint location,
76  SLVfloat* data) { setAttrib(type, 1, location, &data->operator[](0)); }
77 
78  //! Adds a vertex attribute with vector of SLVec2f
80  SLint location,
81  SLVVec2f* data) { setAttrib(type, 2, location, &data->operator[](0)); }
82 
83  //! Adds a vertex attribute with vector of SLVec3f
85  SLint location,
86  SLVVec3f* data) { setAttrib(type, 3, location, &data->operator[](0)); }
87 
88  //! Adds a vertex attribute with vector of SLVec4f
90  SLint location,
91  SLVVec4f* data) { setAttrib(type, 4, location, &data->operator[](0)); }
92 
93  //! Adds a vertex attribute with vector of SLVec4i
95  SLint location,
96  SLVVec4i* data) { setAttrib(type, 4, location, &data->operator[](0), BT_int); }
97 
98  //! Adds the index array for indexed element drawing
100  SLGLBufferType indexDataType,
101  void* indexDataElements,
103  void* indexDataEdges = nullptr);
104 
105  //! Adds the index array for indexed element drawing with a vector of ubyte
106  void setIndices(SLVubyte* indicesElements,
107  SLVubyte* indicesEdges = nullptr)
108  {
109  setIndices((SLuint)indicesElements->size(),
110  BT_ubyte,
111  (void*)&indicesElements->operator[](0),
112  indicesEdges ? (SLuint)indicesEdges->size() : 0,
113  indicesEdges && indicesEdges->size() ? (void*)&indicesEdges->operator[](0) : nullptr);
114  };
115 
116  //! Adds the index array for indexed element drawing with a vector of ushort
117  void setIndices(SLVushort* indicesElements,
118  SLVushort* indicesEdges = nullptr)
119  {
120  setIndices((SLuint)indicesElements->size(),
121  BT_ushort,
122  (void*)&indicesElements->operator[](0),
123  indicesEdges ? (SLuint)indicesEdges->size() : 0,
124  indicesEdges && indicesEdges->size() ? (void*)&indicesEdges->operator[](0) : nullptr);
125  };
126 
127  //! Adds the index array for indexed element drawing with a vector of uint
128  void setIndices(SLVuint* indicesElements,
129  SLVuint* indicesEdges = nullptr)
130  {
131  setIndices((SLuint)indicesElements->size(),
132  BT_uint,
133  (void*)&indicesElements->operator[](0),
134  indicesEdges ? (SLuint)indicesEdges->size() : 0,
135  indicesEdges && indicesEdges->size() ? (void*)&indicesEdges->operator[](0) : nullptr);
136  }
137 
138  //! Attach a VBO that has been created outside of this VAO
139  void setInstanceVBO(SLGLVertexBuffer* vbo, SLuint divisor = 0);
140 
141  //! Updates a specific vertex attribute in the VBO
143  SLint elementSize,
144  void* dataPointer);
145 
146  //! Updates a specific vertex attribute in the VBO
148  SLVuint* data) { updateAttrib(type, 1, (void*)&data->operator[](0)); }
149 
150  //! Updates a specific vertex attribute in the VBO
152  SLVfloat* data) { updateAttrib(type, 1, (void*)&data->operator[](0)); }
153 
154  //! Updates a specific vertex attribute in the VBO
156  SLVVec2f* data) { updateAttrib(type, 2, (void*)&data->operator[](0)); }
157 
158  //! Updates a specific vertex attribute in the VBO
160  SLVVec3f* data) { updateAttrib(type, 3, (void*)&data->operator[](0)); }
161 
162  //! Updates a specific vertex attribute in the VBO
164  SLVVec4f* data) { updateAttrib(type, 4, (void*)&data->operator[](0)); }
165 
166  //! Generates the VA & VB objects for a NO. of vertices
168  SLGLBufferUsage usage = BU_static,
169  SLbool outputInterleaved = true,
170  SLuint divisor = 0);
171 
172  //! Generates the VA & VB & TF objects
174  SLGLBufferUsage usage = BU_static,
175  SLbool outputInterleaved = true,
176  SLuint divisor = 0);
177 
178  //! Begin transform feedback
179  void beginTF(SLuint tfoID);
180 
181  //! End transform feedback
182  void endTF();
183 
184  //! Draws the VAO by element indices with a primitive type
185  void drawElementsAs(SLGLPrimitiveType primitiveType,
186  SLuint numIndexes = 0,
187  SLuint indexOffsetBytes = 0);
188 
189  //! Draws the VAO as an array with a primitive type
190  void drawArrayAs(SLGLPrimitiveType primitiveType,
191  SLint firstVertex = 0,
192  SLsizei countVertices = 0);
193 
194  //! Draws the VAO as an array with instance primitive type
195  void drawElementsInstanced(SLGLPrimitiveType primitiveType,
196  SLuint countInstance = 0,
197  SLuint numIndexes = 0,
198  SLuint indexOffset = 0);
199 
200  //! Draws the hard edges of the VAO with the edge indices
201  void drawEdges(SLCol4f color, SLfloat lineWidth = 1.0f);
202 
203  // Some getters
204  SLuint numVertices() const { return _numVertices; }
207  SLGLVertexBuffer* vbo() { return &_vbo; }
208 
209  // Some statistics
210  static SLuint totalDrawCalls; //! static total no. of draw calls
211  static SLuint totalPrimitivesRendered; //! static total no. of primitives rendered
212 
213 protected:
214  SLuint _instances; //! Number of instances of drawing
215  SLuint _vaoID; //! OpenGL id of vertex array object
216  SLuint _tfoID; //! OpenGL id of transform feedback object
217  SLuint _numVertices; //! NO. of vertices in array
218  SLGLVertexBuffer _vbo; //! Vertex buffer object for float attributes
219  SLuint _idVBOIndices; //! OpenGL id of index vbo
220  size_t _numIndicesElements; //! NO. of vertex indices in array for triangles, lines or points
221  void* _indexDataElements; //! Pointer to index data for elements
222  size_t _numIndicesEdges; //! NO. of vertex indices in array for hard edges
223  void* _indexDataEdges; //! Pointer to index data for hard edges
224  SLGLBufferType _indexDataType; //! index data type (ubyte, ushort, uint)
225  SLGLVertexBuffer* _instanceVbo; //! Vertex buffer object containing the positions for instanced drawing
226  SLuint _instanceDivisor; //! instanceVBO divisor number
227 };
228 //-----------------------------------------------------------------------------
229 
230 #endif
float SLfloat
Definition: SL.h:173
vector< SLubyte > SLVubyte
Definition: SL.h:191
unsigned int SLuint
Definition: SL.h:171
bool SLbool
Definition: SL.h:175
vector< SLfloat > SLVfloat
Definition: SL.h:200
vector< SLushort > SLVushort
Definition: SL.h:195
int SLsizei
Definition: SL.h:172
vector< SLuint > SLVuint
Definition: SL.h:197
int SLint
Definition: SL.h:170
Enumerations containing OpenGL constants.
SLGLAttributeType
Enumeration for float vertex attribute types.
Definition: SLGLEnums.h:45
SLGLPrimitiveType
Definition: SLGLEnums.h:30
SLGLBufferUsage
Enumeration for buffer usage types also supported by OpenGL ES.
Definition: SLGLEnums.h:90
@ BU_static
Buffer will be modified once and used many times.
Definition: SLGLEnums.h:91
SLGLBufferType
Enumeration for buffer data types.
Definition: SLGLEnums.h:20
@ BT_ubyte
vertex index type (0-2^8)
Definition: SLGLEnums.h:23
@ BT_ushort
vertex index type (0-2^16)
Definition: SLGLEnums.h:24
@ BT_float
float vertex attributes
Definition: SLGLEnums.h:21
@ BT_int
int vertex attributes
Definition: SLGLEnums.h:22
@ BT_uint
vertex index type (0-2^32)
Definition: SLGLEnums.h:25
Wrapper class around OpenGL Vertex Buffer Objects (VBO)
vector< SLVec2f > SLVVec2f
Definition: SLVec2.h:143
vector< SLVec3f > SLVVec3f
Definition: SLVec3.h:325
vector< SLVec4f > SLVVec4f
Definition: SLVec4.h:239
vector< SLVec4i > SLVVec4i
Definition: SLVec4.h:240
SLGLVertexArray encapsulates the core OpenGL drawing.
void updateAttrib(SLGLAttributeType type, SLVVec3f *data)
Updates a specific vertex attribute in the VBO.
SLGLVertexBuffer _vbo
NO. of vertices in array.
size_t _numIndicesEdges
Pointer to index data for elements.
void beginTF(SLuint tfoID)
Begin transform feedback.
SLGLVertexBuffer * _instanceVbo
index data type (ubyte, ushort, uint)
SLuint numVertices() const
void setAttrib(SLGLAttributeType type, SLint location, SLVVec4i *data)
Adds a vertex attribute with vector of SLVec4i.
void setIndices(SLVubyte *indicesElements, SLVubyte *indicesEdges=nullptr)
Adds the index array for indexed element drawing with a vector of ubyte.
SLuint _idVBOIndices
Vertex buffer object for float attributes.
void clearAttribs()
Clears the attribute definition.
void setInstanceVBO(SLGLVertexBuffer *vbo, SLuint divisor=0)
Attach a VBO that has been created outside of this VAO.
void * _indexDataEdges
NO. of vertex indices in array for hard edges.
void endTF()
End transform feedback.
SLuint tfoID() const
Returns the TFO id.
size_t _numIndicesElements
OpenGL id of index vbo.
SLuint _vaoID
Number of instances of drawing.
SLuint _tfoID
OpenGL id of vertex array object.
void updateAttrib(SLGLAttributeType type, SLVVec4f *data)
Updates a specific vertex attribute in the VBO.
void updateAttrib(SLGLAttributeType type, SLVfloat *data)
Updates a specific vertex attribute in the VBO.
static SLuint totalDrawCalls
void updateAttrib(SLGLAttributeType type, SLint elementSize, void *dataPointer)
Updates a specific vertex attribute in the VBO.
void setAttrib(SLGLAttributeType type, SLint location, SLVuint *data)
Adds a vertex attribute with vector of SLuint.
void drawElementsAs(SLGLPrimitiveType primitiveType, SLuint numIndexes=0, SLuint indexOffsetBytes=0)
Draws the VAO by element indices with a primitive type.
void setIndices(SLVushort *indicesElements, SLVushort *indicesEdges=nullptr)
Adds the index array for indexed element drawing with a vector of ushort.
void setAttrib(SLGLAttributeType type, SLint elementSize, SLint location, void *dataPointer, SLGLBufferType dataType=BT_float)
Adds a vertex attribute with data pointer and an element size.
static SLuint totalPrimitivesRendered
static total no. of draw calls
SLGLBufferType _indexDataType
Pointer to index data for hard edges.
void setIndices(SLVuint *indicesElements, SLVuint *indicesEdges=nullptr)
Adds the index array for indexed element drawing with a vector of uint.
SLuint _instanceDivisor
Vertex buffer object containing the positions for instanced drawing.
SLuint _instances
static total no. of primitives rendered
SLuint _numVertices
OpenGL id of transform feedback object.
void updateAttrib(SLGLAttributeType type, SLVuint *data)
Updates a specific vertex attribute in the VBO.
void generateTF(SLuint numVertices, SLGLBufferUsage usage=BU_static, SLbool outputInterleaved=true, SLuint divisor=0)
Generates the VA & VB & TF objects.
void setAttrib(SLGLAttributeType type, SLint location, SLVfloat *data)
Adds a vertex attribute with vector of SLfloat.
void drawArrayAs(SLGLPrimitiveType primitiveType, SLint firstVertex=0, SLsizei countVertices=0)
Draws the VAO as an array with a primitive type.
SLuint numIndicesElements() const
void drawElementsInstanced(SLGLPrimitiveType primitiveType, SLuint countInstance=0, SLuint numIndexes=0, SLuint indexOffset=0)
Draws the VAO as an array with instance primitive type.
void updateAttrib(SLGLAttributeType type, SLVVec2f *data)
Updates a specific vertex attribute in the VBO.
void * _indexDataElements
NO. of vertex indices in array for triangles, lines or points.
SLuint vaoID() const
Returns either the VAO id or the VBO id.
void setIndices(SLuint numIndicesElements, SLGLBufferType indexDataType, void *indexDataElements, SLuint numIndicesEdges=0, void *indexDataEdges=nullptr)
Adds the index array for indexed element drawing.
SLGLVertexBuffer * vbo()
void generate(SLuint numVertices, SLGLBufferUsage usage=BU_static, SLbool outputInterleaved=true, SLuint divisor=0)
Generates the VA & VB objects for a NO. of vertices.
void drawEdges(SLCol4f color, SLfloat lineWidth=1.0f)
Draws the hard edges of the VAO with the edge indices.
void setAttrib(SLGLAttributeType type, SLint location, SLVVec2f *data)
Adds a vertex attribute with vector of SLVec2f.
void setAttrib(SLGLAttributeType type, SLint location, SLVVec3f *data)
Adds a vertex attribute with vector of SLVec3f.
void deleteGL()
Deletes all vertex array & vertex buffer objects.
void setAttrib(SLGLAttributeType type, SLint location, SLVVec4f *data)
Adds a vertex attribute with vector of SLVec4f.
SLuint numIndicesEdges() const
SLGLVertexBuffer encapsulates an OpenGL buffer for vertex attributes.
void clear()
Calls deleteGL & clears the attributes.