SLProject  4.2.000
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
SLGLVertexBuffer Class Reference

SLGLVertexBuffer encapsulates an OpenGL buffer for vertex attributes. More...

#include <SLGLVertexBuffer.h>

Public Member Functions

 SLGLVertexBuffer ()
 Constructor initializing with default values. More...
 
 ~SLGLVertexBuffer ()
 
void deleteGL ()
 Deletes all vertex array & vertex buffer objects. More...
 
void clear ()
 Calls deleteGL & clears the attributes. More...
 
SLint attribIndex (SLGLAttributeType type)
 Returns the vector index if a vertex attribute exists otherwise -1. More...
 
void updateAttrib (SLGLAttributeType type, SLint elementSize, void *dataPointer)
 Updates a specific vertex attribute in the VBO. More...
 
void updateAttrib (SLGLAttributeType type, SLVuint &data)
 Updates a specific vertex attribute in the VBO. More...
 
void updateAttrib (SLGLAttributeType type, SLVfloat &data)
 Updates a specific vertex attribute in the VBO. More...
 
void updateAttrib (SLGLAttributeType type, SLVVec2f &data)
 Updates a specific vertex attribute in the VBO. More...
 
void updateAttrib (SLGLAttributeType type, SLVVec3f &data)
 Updates a specific vertex attribute in the VBO. More...
 
void updateAttrib (SLGLAttributeType type, SLVVec4f &data)
 Updates a specific vertex attribute in the VBO. More...
 
void generate (SLuint numVertices, SLGLBufferUsage usage=BU_static, SLbool outputInterleaved=true)
 Generates the VBO. More...
 
void bindAndEnableAttrib (SLuint divisor=0) const
 Binds & enables the vertex attribute for OpenGL < 3.0 and during VAO creation. More...
 
void disableAttrib ()
 disables the vertex attribute for OpenGL < 3.0 More...
 
SLuint id () const
 
SLuint size () const
 
SLVVertexAttribattribs ()
 
SLbool outputIsInterleaved () const
 

Static Public Member Functions

static SLuint sizeOfType (SLGLBufferType type)
 static total size of all buffers in bytes More...
 

Static Public Attributes

static SLuint totalBufferCount = 0
 
static SLuint totalBufferSize = 0
 static total no. of buffers in use More...
 

Protected Attributes

SLuint _id
 
SLuint _numVertices
 OpenGL id of vertex buffer object. More...
 
SLVVertexAttrib _attribs
 NO. of vertices in array. More...
 
SLbool _outputIsInterleaved
 Vector of vertex attributes. More...
 
SLbool _inputIsInterleaved
 Flag if VBO should be generated interleaved. More...
 
SLuint _strideBytes
 Flag if VBO should be generated interleaved. More...
 
SLuint _sizeBytes
 Distance for interleaved attributes in bytes. More...
 
SLGLBufferUsage _usage
 Total size of float VBO in bytes. More...
 

Detailed Description

SLGLVertexBuffer encapsulates an OpenGL buffer for vertex attributes.

SLGLVertexBuffer is only meant to be used within the SLGLVertexArray class. Attributes can be either be in sequential order (first all positions, then all normals, etc.) or interleaved (all attributes together for one vertex). See SLGLVertexBuffer::generate for more information.
Vertex index buffer are not handled in this class. They are generated in SLGLVertexArray.

Definition at line 44 of file SLGLVertexBuffer.h.

Constructor & Destructor Documentation

◆ SLGLVertexBuffer()

SLGLVertexBuffer::SLGLVertexBuffer ( )

Constructor initializing with default values.

Definition at line 19 of file SLGLVertexBuffer.cpp.

20 {
21  _id = 0;
22  _numVertices = 0;
23  _sizeBytes = 0;
24  _outputIsInterleaved = false;
25  _usage = BU_stream;
26 }
@ BU_stream
Buffer will be modified once and used at most a few times.
Definition: SLGLEnums.h:92
SLuint _sizeBytes
Distance for interleaved attributes in bytes.
SLbool _outputIsInterleaved
Vector of vertex attributes.
SLGLBufferUsage _usage
Total size of float VBO in bytes.
SLuint _numVertices
OpenGL id of vertex buffer object.

◆ ~SLGLVertexBuffer()

SLGLVertexBuffer::~SLGLVertexBuffer ( )
inline

Definition at line 48 of file SLGLVertexBuffer.h.

48 { clear(); }
void clear()
Calls deleteGL & clears the attributes.

Member Function Documentation

◆ attribIndex()

SLint SLGLVertexBuffer::attribIndex ( SLGLAttributeType  type)

Returns the vector index if a vertex attribute exists otherwise -1.

Definition at line 48 of file SLGLVertexBuffer.cpp.

49 {
50  for (SLuint i = 0; i < _attribs.size(); ++i)
51  if (_attribs[i].type == type)
52  return (SLint)i;
53  return -1;
54 }
unsigned int SLuint
Definition: SL.h:171
int SLint
Definition: SL.h:170
SLVVertexAttrib _attribs
NO. of vertices in array.

◆ attribs()

SLVVertexAttrib& SLGLVertexBuffer::attribs ( )
inline

Definition at line 98 of file SLGLVertexBuffer.h.

98 { return _attribs; }

◆ bindAndEnableAttrib()

void SLGLVertexBuffer::bindAndEnableAttrib ( SLuint  instanceDivisor = 0) const

Binds & enables the vertex attribute for OpenGL < 3.0 and during VAO creation.

This method is only used by SLGLVertexArray drawing methods for OpenGL contexts prior to 3.0 where vertex array objects did not exist. This is the additional overhead that had to be done per draw call. For VAO (Vertex Array Objects) this method is only used once at the creation of the VAO. The instanceDivisor number is only used for instanced drawing. For all other usage it is by default 0.

Definition at line 268 of file SLGLVertexBuffer.cpp.

269 {
270  /////////////////////////////////////////
271  // Associate VBO to Attribute location //
272  /////////////////////////////////////////
273 
274  glBindBuffer(GL_ARRAY_BUFFER, _id);
275 
276  if (_outputIsInterleaved) // Copy attribute data interleaved
277  {
278  for (auto a : _attribs)
279  {
280  if (a.location > -1)
281  { // Sets the vertex attribute data pointer to its corresponding GLSL variable
282  if (a.dataType == BT_int || a.dataType == BT_uint)
283  {
284  glVertexAttribIPointer((SLuint)a.location,
285  a.elementSize,
286  a.dataType,
288  (void*)(size_t)a.offsetBytes);
289  }
290  else
291  {
292  glVertexAttribPointer((SLuint)a.location,
293  a.elementSize,
294  a.dataType,
295  GL_FALSE,
297  (void*)(size_t)a.offsetBytes);
298  }
299 
300  // Tell the attribute to be an array attribute instead of a state variable
301  glEnableVertexAttribArray((SLuint)a.location);
302 
303  // Special setting for instanced drawing
304  if (instanceDivisor > 0)
305  glVertexAttribDivisor((SLuint)a.location,
306  instanceDivisor);
307  }
308  }
309  }
310  else // copy attributes buffers sequentially
311  {
312  for (auto a : _attribs)
313  {
314  if (a.location > -1)
315  {
316  // Sets the vertex attribute data pointer to its corresponding GLSL variable
317  if (a.dataType == BT_int || a.dataType == BT_uint)
318  {
319  glVertexAttribIPointer((SLuint)a.location,
320  a.elementSize,
321  a.dataType,
322  0,
323  (void*)(size_t)a.offsetBytes);
324  }
325  else
326  {
327  glVertexAttribPointer((SLuint)a.location,
328  a.elementSize,
329  a.dataType,
330  GL_FALSE,
331  0,
332  (void*)(size_t)a.offsetBytes);
333  }
334 
335  // Tell the attribute to be an array attribute instead of a state variable
336  glEnableVertexAttribArray((SLuint)a.location);
337 
338  // Special setting for instanced drawing
339  if (instanceDivisor > 0)
340  glVertexAttribDivisor((SLuint)a.location,
341  instanceDivisor);
342  }
343  }
344  }
345 }
@ BT_int
int vertex attributes
Definition: SLGLEnums.h:22
@ BT_uint
vertex index type (0-2^32)
Definition: SLGLEnums.h:25
SLuint _strideBytes
Flag if VBO should be generated interleaved.

◆ clear()

void SLGLVertexBuffer::clear ( )

Calls deleteGL & clears the attributes.

Definition at line 42 of file SLGLVertexBuffer.cpp.

43 {
44  deleteGL();
45  _attribs.clear();
46 }
void deleteGL()
Deletes all vertex array & vertex buffer objects.

◆ deleteGL()

void SLGLVertexBuffer::deleteGL ( )

Deletes all vertex array & vertex buffer objects.

Deletes the OpenGL objects for the vertex array and the vertex buffer. The vector _attribs with the attribute information is not cleared.

Definition at line 31 of file SLGLVertexBuffer.cpp.

32 {
33  if (_id)
34  {
35  glDeleteBuffers(1, &_id);
36  _id = 0;
39  }
40 }
static SLuint totalBufferSize
static total no. of buffers in use
static SLuint totalBufferCount

◆ disableAttrib()

void SLGLVertexBuffer::disableAttrib ( )

disables the vertex attribute for OpenGL < 3.0

This method is only used by SLGLVertexArray drawing methods for OpenGL contexts prior to 3.0 where vertex array objects did not exist. This is the additional overhead that had to be done per draw call.

Definition at line 351 of file SLGLVertexBuffer.cpp.

352 {
353  if (_attribs.size())
354  {
355  for (auto a : _attribs)
356  if (a.location > -1)
357  glDisableVertexAttribArray((SLuint)a.location);
358  }
359 }

◆ generate()

void SLGLVertexBuffer::generate ( SLuint  numVertices,
SLGLBufferUsage  usage = BU_static,
SLbool  outputInterleaved = true 
)

Generates the VBO.

Generates the OpenGL VBO for one or more vertex attributes. If the input data is an interleaved array (all attribute data pointer where identical) also the output buffer will be generated as an interleaved array. Vertex arrays with attributes that are updated can not be interleaved. Vertex attributes with separate arrays can generate an interleaved or a sequential vertex buffer.


Sequential attribute layout:
| Positions | Normals | TexCoords |
Attribs: | Position0 | Position1 | Normal0 | Normal1 |TexCoord0|TexCoord1|
Elements: | PX | PY | PZ | PX | PY | PZ | NX | NY | NZ | NX | NY | NZ | TX | TY | TX | TY |
Bytes: |#### #### ####|#### #### ####|#### #### ####|#### #### ####|#### ####|#### ####|
| | |
|<------ offset Normals ----->| |
|<-------------------- offset TexCoords ------------------->|

Interleaved attribute layout:
| Vertex 0 | Vertex 1 |
Attribs: | Position0 | Normal0 |TexCoord0| Position1 | Normal1 |TexCoord1|
Elements: | PX | PY | PZ | NX | NY | NZ | TX | TY | PX | PY | PZ | NX | NY | NZ | TX | TY |
Bytes: |#### #### ####|#### #### ####|#### ####|#### #### ####|#### #### ####|#### ####|
| | | |
|<-offsetN=32->| | |
|<------- offsetTC=32 ------->| |
| |
|<---------- strideBytes=32 ----------->|

Definition at line 122 of file SLGLVertexBuffer.cpp.

125 {
126  assert(numVertices);
127 
128  // if buffers exist delete them first
129  deleteGL();
130 
131  _numVertices = numVertices;
132  _usage = usage;
133  _outputIsInterleaved = outputInterleaved;
134 
135  // Generate the vertex buffer object
136  if (_attribs.size())
137  {
138  glGenBuffers(1, &_id);
139  glBindBuffer(GL_ARRAY_BUFFER, _id);
140  }
141 
142  // Check first if all attribute data pointer point to the same interleaved data
143  _inputIsInterleaved = false;
144  if (_attribs.size() > 1)
145  {
146  _inputIsInterleaved = true;
147  for (auto a : _attribs)
148  {
149  if (a.dataPointer != _attribs[0].dataPointer)
150  {
151  _inputIsInterleaved = false;
152  break;
153  }
154  }
155  }
156 
157  ///////////////////////////////////////////////////////
158  // Calculate total VBO size & attribute stride & offset
159  ///////////////////////////////////////////////////////
160 
161  _sizeBytes = 0;
162  _strideBytes = 0;
163 
165  {
166  _outputIsInterleaved = true;
167 
168  for (SLuint i = 0; i < _attribs.size(); ++i)
169  {
170  SLuint elementSizeBytes = (SLuint)_attribs[i].elementSize *
171  sizeOfType(_attribs[i].dataType);
172  _attribs[i].offsetBytes = _strideBytes;
173  _attribs[i].bufferSizeBytes = elementSizeBytes * _numVertices;
174  _sizeBytes += _attribs[i].bufferSizeBytes;
175  _strideBytes += elementSizeBytes;
176  }
177  }
178  else // input is in separate attribute data blocks
179  {
180  for (SLuint i = 0; i < _attribs.size(); ++i)
181  {
182  SLuint elementSizeBytes = (SLuint)_attribs[i].elementSize *
183  sizeOfType(_attribs[i].dataType);
185  _attribs[i].offsetBytes = _strideBytes;
186  else
187  _attribs[i].offsetBytes = _sizeBytes;
188  _attribs[i].bufferSizeBytes = elementSizeBytes * _numVertices;
189  _sizeBytes += _attribs[i].bufferSizeBytes;
190  if (_outputIsInterleaved) _strideBytes += elementSizeBytes;
191  }
192  }
193 
194  //////////////////////////////
195  // Generate VBO for Attributes
196  //////////////////////////////
197 
199  {
200  // generate the interleaved VBO buffer on the GPU
201  glBufferData(GL_ARRAY_BUFFER,
202  _sizeBytes,
203  _attribs[0].dataPointer,
204  _usage);
205  }
206  else // input is in separate attribute data block
207  {
208  if (_outputIsInterleaved) // Copy attribute data interleaved
209  {
210  SLVuchar data;
211  data.resize(_sizeBytes);
212  for (auto a : _attribs)
213  {
214  SLuint elementSizeBytes = (SLuint)a.elementSize *
215  sizeOfType(a.dataType);
216 
217  // Copy attributes interleaved
218  for (SLuint v = 0; v < _numVertices; ++v)
219  {
220  SLuint iDst = v * _strideBytes + a.offsetBytes;
221  SLuint iSrc = v * elementSizeBytes;
222  for (SLuint b = 0; b < elementSizeBytes; ++b)
223  data[iDst + b] = ((SLuchar*)a.dataPointer)[iSrc + b];
224  }
225 
226  // generate the interleaved VBO buffer on the GPU
227  glBufferData(GL_ARRAY_BUFFER,
228  _sizeBytes,
229  &data[0],
230  _usage);
231  }
232  }
233  else // copy attributes buffers sequentially
234  {
235  // allocate the VBO buffer on the GPU
236  glBufferData(GL_ARRAY_BUFFER,
237  _sizeBytes,
238  nullptr,
239  _usage);
240 
241  for (auto a : _attribs)
242  {
243  if (a.location > -1)
244  {
245  // Copies the attributes data at the right offset into the VBO
246  glBufferSubData(GL_ARRAY_BUFFER,
247  a.offsetBytes,
248  a.bufferSizeBytes,
249  a.dataPointer);
250  }
251  }
252  }
253  }
254 
257  GET_GL_ERROR;
258 }
unsigned char SLuchar
Definition: SL.h:163
vector< SLuchar > SLVuchar
Definition: SL.h:193
#define GET_GL_ERROR
Definition: SLGLState.h:56
SLbool _inputIsInterleaved
Flag if VBO should be generated interleaved.
static SLuint sizeOfType(SLGLBufferType type)
static total size of all buffers in bytes

◆ id()

SLuint SLGLVertexBuffer::id ( ) const
inline

Definition at line 96 of file SLGLVertexBuffer.h.

96 { return _id; }

◆ outputIsInterleaved()

SLbool SLGLVertexBuffer::outputIsInterleaved ( ) const
inline

Definition at line 99 of file SLGLVertexBuffer.h.

99 { return _outputIsInterleaved; }

◆ size()

SLuint SLGLVertexBuffer::size ( ) const
inline

Definition at line 97 of file SLGLVertexBuffer.h.

97 { return _id; }

◆ sizeOfType()

SLuint SLGLVertexBuffer::sizeOfType ( SLGLBufferType  type)
static

static total size of all buffers in bytes

Returns the size in byte depending off the buffer type.

Returns the size of a buffer data type

Definition at line 362 of file SLGLVertexBuffer.cpp.

363 {
364  switch (type)
365  {
366  case BT_float: return sizeof(SLfloat);
367  case BT_int: return sizeof(SLint);
368  case BT_ubyte: return sizeof(SLuchar);
369  case BT_ushort: return sizeof(SLushort);
370  case BT_uint: return sizeof(SLint);
371  default: SL_EXIT_MSG("Invalid buffer data type");
372  }
373  return 0;
374 }
float SLfloat
Definition: SL.h:173
unsigned short SLushort
Definition: SL.h:169
#define SL_EXIT_MSG(message)
Definition: SL.h:240
@ 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

◆ updateAttrib() [1/6]

void SLGLVertexBuffer::updateAttrib ( SLGLAttributeType  type,
SLint  elementSize,
void dataPointer 
)

Updates a specific vertex attribute in the VBO.

Updates the specified vertex attribute. This works only for sequential attributes and not for interleaved attributes. This is used e.g. for meshes with vertex skinning. See SLMesh::draw where we have joint attributes.

Definition at line 60 of file SLGLVertexBuffer.cpp.

63 {
64  assert(dataPointer && "No data pointer passed");
65  assert(elementSize > 0 && elementSize < 5 && "Element size invalid");
66 
67  // Get attribute index and check element size
68  SLint index = attribIndex(type);
69  if (index == -1)
70  SL_EXIT_MSG("Attribute type does not exist in VBO.");
71  if (_attribs[(SLuint)index].elementSize != elementSize)
72  SL_EXIT_MSG("Attribute element size differs.");
74  SL_EXIT_MSG("Interleaved buffers can't be updated.");
75 
76  // Generate the vertex buffer object if there is none
77  if (index && !_id)
78  glGenBuffers(1, &_id);
79 
80  _attribs[(SLuint)index].dataPointer = dataPointer;
81 
82  ///////////////////////////////////////////////
83  // copy sub-data into existing buffer object //
84  ///////////////////////////////////////////////
85 
86  glBindBuffer(GL_ARRAY_BUFFER, _id);
87  glBufferSubData(GL_ARRAY_BUFFER,
88  _attribs[(SLuint)index].offsetBytes,
89  _attribs[(SLuint)index].bufferSizeBytes,
90  _attribs[(SLuint)index].dataPointer);
92 }
SLint attribIndex(SLGLAttributeType type)
Returns the vector index if a vertex attribute exists otherwise -1.

◆ updateAttrib() [2/6]

void SLGLVertexBuffer::updateAttrib ( SLGLAttributeType  type,
SLVfloat data 
)
inline

Updates a specific vertex attribute in the VBO.

Definition at line 69 of file SLGLVertexBuffer.h.

70  { updateAttrib(type, 1, (void*)&data[0]); }
void updateAttrib(SLGLAttributeType type, SLint elementSize, void *dataPointer)
Updates a specific vertex attribute in the VBO.

◆ updateAttrib() [3/6]

void SLGLVertexBuffer::updateAttrib ( SLGLAttributeType  type,
SLVuint data 
)
inline

Updates a specific vertex attribute in the VBO.

Definition at line 65 of file SLGLVertexBuffer.h.

66  { updateAttrib(type, 1, (void*)&data[0]); }

◆ updateAttrib() [4/6]

void SLGLVertexBuffer::updateAttrib ( SLGLAttributeType  type,
SLVVec2f data 
)
inline

Updates a specific vertex attribute in the VBO.

Definition at line 73 of file SLGLVertexBuffer.h.

74  { updateAttrib(type, 2, (void*)&data[0]); }

◆ updateAttrib() [5/6]

void SLGLVertexBuffer::updateAttrib ( SLGLAttributeType  type,
SLVVec3f data 
)
inline

Updates a specific vertex attribute in the VBO.

Definition at line 77 of file SLGLVertexBuffer.h.

78  { updateAttrib(type, 3, (void*)&data[0]); }

◆ updateAttrib() [6/6]

void SLGLVertexBuffer::updateAttrib ( SLGLAttributeType  type,
SLVVec4f data 
)
inline

Updates a specific vertex attribute in the VBO.

Definition at line 81 of file SLGLVertexBuffer.h.

82  { updateAttrib(type, 4, (void*)&data[0]); }

Member Data Documentation

◆ _attribs

SLVVertexAttrib SLGLVertexBuffer::_attribs
protected

NO. of vertices in array.

Definition at line 113 of file SLGLVertexBuffer.h.

◆ _id

SLuint SLGLVertexBuffer::_id
protected

Definition at line 111 of file SLGLVertexBuffer.h.

◆ _inputIsInterleaved

SLbool SLGLVertexBuffer::_inputIsInterleaved
protected

Flag if VBO should be generated interleaved.

Definition at line 115 of file SLGLVertexBuffer.h.

◆ _numVertices

SLuint SLGLVertexBuffer::_numVertices
protected

OpenGL id of vertex buffer object.

Definition at line 112 of file SLGLVertexBuffer.h.

◆ _outputIsInterleaved

SLbool SLGLVertexBuffer::_outputIsInterleaved
protected

Vector of vertex attributes.

Definition at line 114 of file SLGLVertexBuffer.h.

◆ _sizeBytes

SLuint SLGLVertexBuffer::_sizeBytes
protected

Distance for interleaved attributes in bytes.

Definition at line 117 of file SLGLVertexBuffer.h.

◆ _strideBytes

SLuint SLGLVertexBuffer::_strideBytes
protected

Flag if VBO should be generated interleaved.

Definition at line 116 of file SLGLVertexBuffer.h.

◆ _usage

SLGLBufferUsage SLGLVertexBuffer::_usage
protected

Total size of float VBO in bytes.

Definition at line 118 of file SLGLVertexBuffer.h.

◆ totalBufferCount

SLuint SLGLVertexBuffer::totalBufferCount = 0
static

Definition at line 104 of file SLGLVertexBuffer.h.

◆ totalBufferSize

SLuint SLGLVertexBuffer::totalBufferSize = 0
static

static total no. of buffers in use

Definition at line 105 of file SLGLVertexBuffer.h.


The documentation for this class was generated from the following files: