SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
SLGLVertexArray.cpp
Go to the documentation of this file.
1 /**
2  * \file SLGLVertexArray.cpp
3  * \brief Wrapper around an OpenGL Vertex Array Objects
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 #include <SLGLState.h>
12 #include <SLGLProgram.h>
13 #include <SLGLVertexArray.h>
14 #include <SLScene.h>
15 
16 //-----------------------------------------------------------------------------
19 //-----------------------------------------------------------------------------
20 /*! Constructor initializing with default values
21  */
23 {
24  _vaoID = 0;
25  _vbo.clear();
26  _idVBOIndices = 0;
28  _numIndicesEdges = 0;
29  _numVertices = 0;
30  _indexDataElements = nullptr;
31  _indexDataEdges = nullptr;
32  _instanceVbo = nullptr;
33 }
34 //-----------------------------------------------------------------------------
35 /*! Deletes the OpenGL objects for the vertex array and the vertex buffer.
36 The vector _attribs with the attribute information is not cleared.
37 */
39 {
40  if (_vaoID)
41  glDeleteVertexArrays(1, &_vaoID);
42  _vaoID = 0;
43 
44  if (_vbo.id())
45  _vbo.clear();
46 
47  if (_idVBOIndices)
48  {
49  glDeleteBuffers(1, &_idVBOIndices);
50  _idVBOIndices = 0;
54  }
55 }
56 //-----------------------------------------------------------------------------
57 /*! Defines a vertex attribute for the later generation.
58 It must be of a specific SLVertexAttribType. Each attribute can appear only
59 once in an vertex array.
60 If all attributes of a vertex array have the same data pointer the data input
61 will be interpreted as an interleaved array. See example in SLGLOculus::init.
62 Be aware that the VBO for the attribute will not be generated until generate
63 is called. The data pointer must still be valid when SLGLVertexArray::generate
64 is called.
65 */
67  SLint elementSize,
68  SLint location,
69  void* dataPointer,
70  SLGLBufferType dataType)
71 {
72  assert(dataPointer);
73  assert(elementSize);
74 
75  if (type == AT_position && location == -1)
76  SL_EXIT_MSG("The position attribute has no variable location.");
77 
78  if (_vbo.attribIndex(type) >= 0)
79  SL_EXIT_MSG("Attribute type already exists.");
80 
81  SLGLAttribute va;
82  va.type = type;
83  va.elementSize = elementSize;
84  va.dataType = dataType;
85  va.dataPointer = dataPointer;
86  va.location = location;
87  va.bufferSizeBytes = 0;
88 
89  _vbo.attribs().push_back(va);
90 }
91 //-----------------------------------------------------------------------------
92 /*! Assignment of the additional VBO for instanced drawing. The passed vbo
93  * contains the positions for the instanced drawing done in
94  * drawElementsInstanced. This used e.g. for SLParticleSystems on systems
95  * without geometry shaders.
96  */
98 {
99  _instanceVbo = vbo;
100  _instanceDivisor = divisor;
101 }
102 //-----------------------------------------------------------------------------
103 /*! Defines the vertex indices for the element drawing. Without indices vertex
104 array can only be drawn with SLGLVertexArray::drawArrayAs.
105 Be aware that the VBO for the indices will not be generated until generate
106 is called. The data pointer must still be valid when generate is called.
107 */
108 void SLGLVertexArray::setIndices(SLuint numIndicesElements,
109  SLGLBufferType indexDataType,
110  void* indexDataElements,
111  SLuint numIndicesEdges,
112  void* indexDataEdges)
113 {
114  assert(numIndicesElements);
115  assert(indexDataElements);
116 
117  if (indexDataType == BT_ushort && _numVertices > 65535)
118  SL_EXIT_MSG("Index data type not sufficient.");
119  if (indexDataType == BT_ubyte && _numVertices > 255)
120  SL_EXIT_MSG("Index data type not sufficient.");
121 
123  _indexDataElements = indexDataElements;
124  _indexDataType = indexDataType;
126  _indexDataEdges = indexDataEdges;
127 }
128 //-----------------------------------------------------------------------------
129 /*! Updates the specified vertex attribute. This works only for sequential
130 attributes and not for interleaved attributes. This is used e.g. for meshes
131 with vertex skinning. See SLMesh::draw where we have joint attributes.
132 */
134  SLint elementSize,
135  void* dataPointer)
136 {
137  assert(dataPointer && "No data pointer passed");
138  assert(elementSize > 0 && elementSize < 5 && "Element size invalid");
139 
140  // Get attribute index and check element size
141  SLint indexf = _vbo.attribIndex(type);
142  if (indexf == -1)
143  SL_EXIT_MSG("Attribute type does not exist in VAO.");
144 
145  if (!_vaoID)
146  glGenVertexArrays(1, &_vaoID);
147  glBindVertexArray(_vaoID);
148 
149  // update the appropriate VBO
150  if (indexf > -1)
151  _vbo.updateAttrib(type, elementSize, dataPointer);
152 
153  glBindVertexArray(0);
154  GET_GL_ERROR;
155 }
156 
157 //-----------------------------------------------------------------------------
158 /*! Generates the OpenGL objects for the vertex array and the vertex buffer
159  object. If the input data is an interleaved array (all attribute data pointer
160  where identical) also the output buffer will be generated as an interleaved
161  array. Vertex arrays with attributes that are updated can not be interleaved.
162  Vertex attributes with separate arrays can generate an interleaved or a
163  sequential vertex buffer.\n\n
164  <PRE>
165  \n Sequential attribute layout:
166  \n | Positions | Normals | TexCoords |
167  \n Attribs: | Position0 | Position1 | Normal0 | Normal1 | UV1_0 | UV1_1 |
168  \n Elements: | PX | PY | PZ | PX | PY | PZ | NX | NY | NZ | NX | NY | NZ | TX | TY | TX | TY |
169  \n Bytes: |#### #### ####|#### #### ####|#### #### ####|#### #### ####|#### ####|#### ####|
170  \n | | |
171  \n |<------ offset Normals ----->| |
172  \n |<----------------------- offset UVs ---------------------->|
173  \n
174  \n Interleaved attribute layout:
175  \n | Vertex 0 | Vertex 1 |
176  \n Attribs: | Position0 | Normal0 | UV1_0 | Position1 | Normal1 | UV1_1 |
177  \n Elements: | PX | PY | PZ | NX | NY | NZ | TX | TY | PX | PY | PZ | NX | NY | NZ | TX | TY |
178  \n Bytes: |#### #### ####|#### #### ####|#### ####|#### #### ####|#### #### ####|#### ####|
179  \n | | | |
180  \n |<-offsetN=32->| | |
181  \n |<------- offsetUV=32 ------->| |
182  \n | |
183  \n |<---------- strideBytes=32 ----------->|
184  </PRE>
185  The VAO has no or one active index buffer. For drawArrayAs no indices are needed.
186  For drawElementsAs the index buffer is used. For triangle meshes also hard edges
187  are generated. Their indices are stored behind the indices of the triangles.
188 */
190  SLGLBufferUsage usage,
191  SLbool outputInterleaved,
192  SLuint divisor)
193 {
194  assert(numVertices);
195 
196  // if buffers exist delete them first
197  deleteGL();
198 
200 
201  // Generate and bind VAO
202  glGenVertexArrays(1, &_vaoID);
203  glBindVertexArray(_vaoID);
204 
205  ///////////////////////////////
206  // Create Vertex Buffer Objects
207  ///////////////////////////////
208 
209  // Generate the vertex buffer object for float attributes
210  if (_vbo.attribs().size())
211  {
212  _vbo.generate(numVertices, usage, outputInterleaved);
213  _vbo.bindAndEnableAttrib(divisor);
214  }
215 
216  if (_instanceVbo != nullptr)
217  {
219  }
220 
221  /////////////////////////////////////////////////////////////////
222  // Create Element Array Buffer for Indices for elements and edges
223  /////////////////////////////////////////////////////////////////
224 
227  {
228  // create temp. buffer with both index arrays
231  (SLuint)typeSize;
232  SLubyte* tmpBuf = new SLubyte[tmBufSize];
233  memcpy(tmpBuf,
235  _numIndicesElements * (SLuint)typeSize);
236  memcpy(tmpBuf + _numIndicesElements * (SLuint)typeSize,
238  _numIndicesEdges * (SLuint)typeSize);
239 
240  glGenBuffers(1, &_idVBOIndices);
241  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
242  _idVBOIndices);
243  glBufferData(GL_ELEMENT_ARRAY_BUFFER,
244  tmBufSize,
245  tmpBuf,
246  GL_STATIC_DRAW);
249  delete[] tmpBuf;
250  }
251  else if (_numIndicesElements && _indexDataElements) // for elements only
252  {
254  glGenBuffers(1, &_idVBOIndices);
255  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _idVBOIndices);
256  glBufferData(GL_ELEMENT_ARRAY_BUFFER,
257  (GLsizeiptr)_numIndicesElements * (SLuint)typeSize,
259  GL_STATIC_DRAW);
262  (SLuint)typeSize;
263  }
264 
265  glBindVertexArray(0);
266  GET_GL_ERROR;
267 }
268 //-----------------------------------------------------------------------------
269 /*! Same as generate but with transform feedback */
271  SLGLBufferUsage usage,
272  SLbool outputInterleaved,
273  SLuint divisor)
274 {
275  assert(numVertices);
276 
277  // if buffers exist delete them first
278  deleteGL();
279 
281 
282  // Generate TFO
283  glGenTransformFeedbacks(1, &_tfoID);
284 
285  // Generate and bind VAO
286  glGenVertexArrays(1, &_vaoID);
287  glBindVertexArray(_vaoID);
288 
289  ///////////////////////////////
290  // Create Vertex Buffer Objects
291  ///////////////////////////////
292 
293  // Generate the vertex buffer object for float attributes
294  if (_vbo.attribs().size())
295  {
296  _vbo.generate(numVertices, usage, outputInterleaved);
297  _vbo.bindAndEnableAttrib(divisor);
298  }
299 
300  // ???
301  if (_instanceVbo != nullptr)
302  {
304  }
305 
306  ///////////////////////////////
307  // Bind transform feedback
308  ///////////////////////////////
309 
310  glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, _tfoID);
311  glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, _vbo.id());
312 
313  /////////////////////////////////////////////////////////////////
314  // Create Element Array Buffer for Indices for elements and edges
315  /////////////////////////////////////////////////////////////////
316 
319  {
320  // create temp. buffer with both index arrays
323  (SLuint)typeSize;
324  SLubyte* tmpBuf = new SLubyte[tmBufSize];
325  memcpy(tmpBuf,
327  _numIndicesElements * (SLuint)typeSize);
328  memcpy(tmpBuf + _numIndicesElements * (SLuint)typeSize,
330  _numIndicesEdges * (SLuint)typeSize);
331 
332  glGenBuffers(1, &_idVBOIndices);
333  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _idVBOIndices);
334  glBufferData(GL_ELEMENT_ARRAY_BUFFER,
335  tmBufSize,
336  tmpBuf,
337  GL_STATIC_DRAW);
340  delete[] tmpBuf;
341  }
342  else if (_numIndicesElements && _indexDataElements) // for elements only
343  {
345  glGenBuffers(1, &_idVBOIndices);
346  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _idVBOIndices);
347  glBufferData(GL_ELEMENT_ARRAY_BUFFER,
348  (GLsizeiptr)_numIndicesElements * (SLuint)typeSize,
350  GL_STATIC_DRAW);
353  (SLuint)typeSize;
354  }
355 
356  glBindVertexArray(0);
357  GET_GL_ERROR;
358 }
359 //-----------------------------------------------------------------------------
360 /*! Discard the rendering because we just compute next position with the
361  * transform feedback. We need to bind a transform feedback object but not the
362  * same from this vao, because we want to read from one vao and write on another.
363  */
365 {
366  // Disable rendering
367  glEnable(GL_RASTERIZER_DISCARD);
368 
369  // Bind the feedback object for the buffers to be drawn next
370  glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfoID);
371 
372  // Draw points from input buffer with transform feedback
373  glBeginTransformFeedback(GL_POINTS);
374 }
375 
376 //-----------------------------------------------------------------------------
377 /*! We activate back the rendering and stop the transform feedback.
378  */
380 {
381  // End transform feedback
382  glEndTransformFeedback();
383 
384  // Enable rendering
385  glDisable(GL_RASTERIZER_DISCARD);
386 
387  // Un-bind the feedback object.
388  glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
389 }
390 //-----------------------------------------------------------------------------
391 /*! Draws the vertex attributes as a specified primitive type by elements with
392 the indices from the index buffer defined in setIndices.
393 */
395  SLuint numIndexes,
396  SLuint indexOffset)
397 {
398  assert(_numIndicesElements && _idVBOIndices && "No index VBO generated for VAO");
399 
400  // From OpenGL 3.0 on we have the OpenGL Vertex Arrays
401  // Binding the VAO saves all the commands after the else (per draw call!)
402  glBindVertexArray(_vaoID);
403  GET_GL_ERROR;
404 
405  // Do the draw call with indices
406  if (numIndexes == 0)
407  numIndexes = (SLuint)_numIndicesElements;
408 
410 
411  /////////////////////////////////////////////////////////////////////
412  glDrawElements(primitiveType,
413  (SLsizei)numIndexes,
415  (void*)(size_t)(indexOffset * (SLuint)indexTypeSize));
416  /////////////////////////////////////////////////////////////////////
417 
418  GET_GL_ERROR;
419  totalDrawCalls++;
420  switch (primitiveType)
421  {
422  case PT_triangles:
423  totalPrimitivesRendered += (numIndexes / 3);
424  break;
425  case PT_lines:
426  totalPrimitivesRendered += (numIndexes / 2);
427  break;
428  case PT_points:
429  totalPrimitivesRendered += numIndexes;
430  break;
431  default: break;
432  }
433 
434  glBindVertexArray(0);
435  GET_GL_ERROR;
436 }
437 //-----------------------------------------------------------------------------
438 /*!
439  * Draws the vertex attributes as a specified primitive type as the vertices
440  * are defined in the attribute arrays.
441  */
443  SLint firstVertex,
444  SLsizei countVertices)
445 {
446  assert((_vbo.id()) && "No VBO generated for VAO.");
447 
448  glBindVertexArray(_vaoID);
449 
450  if (countVertices == 0)
451  countVertices = (SLsizei)_numVertices;
452 
453  //////////////////////////////////
454  glDrawArrays(primitiveType,
455  firstVertex,
456  countVertices);
457  //////////////////////////////////
458 
459  // Update statistics
460  totalDrawCalls++;
461  SLint numVertices = countVertices - firstVertex;
462  switch (primitiveType)
463  {
464  case PT_triangles:
466  break;
467  case PT_lines:
469  break;
470  case PT_points:
472  break;
473  default: break;
474  }
475 
476  glBindVertexArray(0);
477 
478  GET_GL_ERROR;
479 }
480 //-----------------------------------------------------------------------------
481 /*! Wrapper around glDrawElementsInstanced using a second VBO (_instanceVbo)
482  * that contains all positions for the instances. This used e.g. for
483  * SLParticleSystems on systems without geometry shaders.
484  */
486  SLuint countInstances,
487  SLuint numIndexes,
488  SLuint indexOffset)
489 {
490  assert(_numIndicesElements &&
491  _idVBOIndices &&
492  "No index VBO generated for VAO");
493 
494  // From OpenGL 3.0 on we have the OpenGL Vertex Arrays
495  // Binding the VAO saves all the commands after the else (per draw call!)
496  glBindVertexArray(_vaoID);
497  GET_GL_ERROR;
498 
499  // Do the draw call with indices
500  if (numIndexes == 0)
501  numIndexes = (SLuint)_numIndicesElements;
502 
504 
505  ////////////////////////////////////////////////////////
506  glDrawElementsInstanced(primitiveType,
507  (GLsizei)numIndexes,
509  (void*)(size_t)(indexOffset * (SLuint)indexTypeSize),
510  (GLsizei)countInstances);
511  ////////////////////////////////////////////////////////
512 
513  GET_GL_ERROR;
514 
515  // Update statistics
516  totalDrawCalls++;
517  switch (primitiveType)
518  {
519  case PT_triangles:
520  totalPrimitivesRendered += (numIndexes / 3);
521  break;
522  case PT_lines:
523  totalPrimitivesRendered += (numIndexes / 2);
524  break;
525  case PT_points:
526  totalPrimitivesRendered += numIndexes;
527  break;
528  default: break;
529  }
530  glBindVertexArray(0);
531 
532  GET_GL_ERROR;
533 }
534 //-----------------------------------------------------------------------------
535 /*! Draws the hard edges with the specified color.
536  The VAO has no or one active index buffer. For drawArrayAs no indices are needed.
537  For drawElementsAs the index buffer is used. For triangle meshes also hard edges
538  are generated. Their indices are stored behind the indices of the triangles.
539 */
541  SLfloat lineWidth)
542 {
543  if (!_vbo.id())
544  SL_EXIT_MSG("No VBO generated for VAO in drawArrayAsColored.");
545 
546  // Prepare shader
548  SLGLState* stateGL = SLGLState::instance();
549  sp->useProgram();
550  sp->uniformMatrix4fv("u_mMatrix", 1, (SLfloat*)&stateGL->modelMatrix);
551  sp->uniformMatrix4fv("u_vMatrix", 1, (SLfloat*)&stateGL->viewMatrix);
552  sp->uniformMatrix4fv("u_pMatrix", 1, (SLfloat*)&stateGL->projectionMatrix);
553  sp->uniform1f("u_oneOverGamma", 1.0f);
554  stateGL->currentMaterial(nullptr);
555 
556  // Set uniform color
557  glUniform4fv(sp->getUniformLocation("u_matDiff"), 1, (SLfloat*)&color);
558 
559 #if not defined(SL_GLES) && not defined(SL_EMSCRIPTEN)
560  if (lineWidth != 1.0f)
561  glLineWidth(lineWidth);
562 #endif
563 
564  //////////////////////////////////////////////////////
568  //////////////////////////////////////////////////////
569 
570 #if not defined(SL_GLES) && not defined(SL_EMSCRIPTEN)
571  if (lineWidth != 1.0f)
572  glLineWidth(1.0f);
573 #endif
574 
575  GET_GL_ERROR;
576 }
577 //-----------------------------------------------------------------------------
float SLfloat
Definition: SL.h:173
unsigned int SLuint
Definition: SL.h:171
bool SLbool
Definition: SL.h:175
unsigned char SLubyte
Definition: SL.h:167
#define SL_EXIT_MSG(message)
Definition: SL.h:240
int SLsizei
Definition: SL.h:172
int SLint
Definition: SL.h:170
SLGLAttributeType
Enumeration for float vertex attribute types.
Definition: SLGLEnums.h:45
@ AT_position
Vertex position as a 2, 3 or 4 component vectors.
Definition: SLGLEnums.h:58
SLGLPrimitiveType
Definition: SLGLEnums.h:30
@ PT_points
Definition: SLGLEnums.h:31
@ PT_lines
Definition: SLGLEnums.h:32
@ PT_triangles
Definition: SLGLEnums.h:35
SLGLBufferUsage
Enumeration for buffer usage types also supported by OpenGL ES.
Definition: SLGLEnums.h:90
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
@ SP_colorUniform
Singleton class for global render state.
#define GET_GL_ERROR
Definition: SLGLState.h:56
Wrapper class around OpenGL Vertex Array Objects (VAO)
Encapsulation of an OpenGL shader program object.
Definition: SLGLProgram.h:56
SLint uniformMatrix4fv(const SLchar *name, SLsizei count, const SLfloat *value, GLboolean transpose=false) const
Passes a 4x4 float matrix values py pointer to the uniform variable "name".
SLint uniform1f(const SLchar *name, SLfloat v0) const
Passes the float value v0 to the uniform variable "name".
SLint getUniformLocation(const SLchar *name) const
void useProgram()
static SLGLProgramGeneric * get(SLStdShaderProg id)
Get program reference for given id.
Singleton class holding all OpenGL states.
Definition: SLGLState.h:71
SLMat4f modelMatrix
Init all states.
Definition: SLGLState.h:89
static SLGLState * instance()
Public static instance getter for singleton pattern.
Definition: SLGLState.h:74
SLMat4f viewMatrix
matrix for the active cameras view transform
Definition: SLGLState.h:91
SLMat4f projectionMatrix
matrix for projection transform
Definition: SLGLState.h:90
void currentMaterial(SLMaterial *mat)
Definition: SLGLState.h:120
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
SLuint _idVBOIndices
Vertex buffer object for float attributes.
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.
static SLuint totalDrawCalls
void updateAttrib(SLGLAttributeType type, SLint elementSize, void *dataPointer)
Updates a specific vertex attribute in the VBO.
void drawElementsAs(SLGLPrimitiveType primitiveType, SLuint numIndexes=0, SLuint indexOffsetBytes=0)
Draws the VAO by element indices with a primitive type.
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.
SLuint _instanceDivisor
Vertex buffer object containing the positions for instanced drawing.
SLuint _numVertices
OpenGL id of transform feedback object.
void generateTF(SLuint numVertices, SLGLBufferUsage usage=BU_static, SLbool outputInterleaved=true, SLuint divisor=0)
Generates the VA & VB & TF objects.
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 * _indexDataElements
NO. of vertex indices in array for triangles, lines or points.
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 deleteGL()
Deletes all vertex array & vertex buffer objects.
SLuint numIndicesEdges() const
SLGLVertexBuffer encapsulates an OpenGL buffer for vertex attributes.
SLint attribIndex(SLGLAttributeType type)
Returns the vector index if a vertex attribute exists otherwise -1.
void generate(SLuint numVertices, SLGLBufferUsage usage=BU_static, SLbool outputInterleaved=true)
Generates the VBO.
static SLuint totalBufferSize
static total no. of buffers in use
static SLuint totalBufferCount
SLuint id() const
void clear()
Calls deleteGL & clears the attributes.
static SLuint sizeOfType(SLGLBufferType type)
static total size of all buffers in bytes
SLVVertexAttrib & attribs()
void bindAndEnableAttrib(SLuint divisor=0) const
Binds & enables the vertex attribute for OpenGL < 3.0 and during VAO creation.
void updateAttrib(SLGLAttributeType type, SLint elementSize, void *dataPointer)
Updates a specific vertex attribute in the VBO.
Struct for vertex attribute information.
SLGLAttributeType type
type of vertex attribute
SLint location
GLSL input variable location index.
SLint elementSize
size of attribute element (SLVec3f has 3)
SLGLBufferType dataType
SLuint bufferSizeBytes
size of the attribute part in the buffer
void * dataPointer
pointer to the attributes source data