NGL  6.5
The NCCA Graphics Library
VertexArrayObject.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 Jon Macey
3 
4  This program is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17 #include "VertexArrayObject.h"
18 #include <iostream>
19 //----------------------------------------------------------------------------------------------------------------------
22 //----------------------------------------------------------------------------------------------------------------------
23 namespace ngl
24 {
25 
26 //----------------------------------------------------------------------------------------------------------------------
28 {
29  m_allocated=false;
30  // first we create a vertex array Object
32  m_bound=false;
33  m_drawMode=_mode;
35  m_indexed=false;
37  m_iboID=0;
38 }
39 
40 //----------------------------------------------------------------------------------------------------------------------
42 {
44  m_bound=true;
45 }
46 //----------------------------------------------------------------------------------------------------------------------
48 {
50  m_bound=false;
51 }
52 //----------------------------------------------------------------------------------------------------------------------
54 {
55  if(m_bound == true)
56  {
57  unbind();
58  }
59  if( m_allocated ==true)
60  {
61  for(auto b : m_vboIDs)
62  {
63  glDeleteBuffers(1,&b);
64  }
66  m_allocated=false;
67  }
68 }
69 //----------------------------------------------------------------------------------------------------------------------
70 void VertexArrayObject::setData(size_t _size,const GLfloat &_data,GLenum _mode)
71 {
72  if(m_bound == false)
73  {
74  std::cerr<<"trying to set VOA data when unbound\n";
75  }
76  GLuint vboID;
77  glGenBuffers(1, &vboID);
78  m_vboIDs.push_back(vboID);
79  // now we will bind an array buffer to the first one and load the data for the verts
81  glBufferData(GL_ARRAY_BUFFER,static_cast<GLsizeiptr>( _size), &_data, _mode);
82  m_allocated=true;
83 
84 }
85 
86 
87 void VertexArrayObject::setIndexedData(size_t _size, const GLfloat &_data, unsigned int _indexSize, const GLvoid *_indexData, GLenum _indexType, GLenum _mode )
88 {
89 
90  if(m_bound == false)
91  {
92  std::cerr<<"trying to set VOA data when unbound\n";
93  }
94  GLuint vboID;
95  glGenBuffers(1, &vboID);
96  m_vboIDs.push_back(vboID);
97 
98  GLuint iboID;
99  glGenBuffers(1, &iboID);
100  m_iboID = iboID;
101 
102  //glEnableVertexAttribArray(0);
103  // now we will bind an array buffer to the first one and load the data for the verts
105  glBufferData(GL_ARRAY_BUFFER, static_cast<GLsizeiptr>(_size), &_data, _mode);
106  // we need to determine the size of the data type before we set it
107  // in default to a ushort
108  int size=sizeof(GLushort);
109  switch(_indexType)
110  {
111  case GL_UNSIGNED_INT : size=sizeof(GLuint); break;
112  case GL_UNSIGNED_SHORT : size=sizeof(GLushort); break;
113  case GL_UNSIGNED_BYTE : size=sizeof(GLubyte); break;
114  default : std::cerr<<"wrong data type send for index value\n"; break;
115  }
116  // now for the indices
118  glBufferData(GL_ELEMENT_ARRAY_BUFFER, _indexSize * static_cast<GLsizeiptr>(size), const_cast<GLvoid *>(_indexData), _mode);
119 
120  m_allocated=true;
121  m_indexed=true;
122  m_indexType=_indexType;
123 }
124 
125 
126 void VertexArrayObject::setRawIndexedData(size_t _size, const GLvoid *_data, unsigned int _indexSize,const GLvoid *_indexData, GLenum _indexType,GLenum _mode)
127 {
128 
129  if(m_bound == false)
130  {
131  std::cerr<<"trying to set VOA data when unbound\n";
132  }
133  GLuint vboID;
134  glGenBuffers(1, &vboID);
135  m_vboIDs.push_back(vboID);
136 
137  GLuint iboID;
138  glGenBuffers(1, &iboID);
139  m_iboID = iboID;
140 
141  //glEnableVertexAttribArray(0);
142  // now we will bind an array buffer to the first one and load the data for the verts
144  glBufferData(GL_ARRAY_BUFFER, static_cast<GLsizeiptr>(_size), _data, _mode);
145  // we need to determine the size of the data type before we set it
146  // in default to a ushort
147  int size=sizeof(GLushort);
148  switch(_indexType)
149  {
150  case GL_UNSIGNED_INT : size=sizeof(GLuint); break;
151  case GL_UNSIGNED_SHORT : size=sizeof(GLushort); break;
152  case GL_UNSIGNED_BYTE : size=sizeof(GLubyte); break;
153  default : std::cerr<<"wrong data type sent for index value\n"; break;
154  }
155  // now for the indices
157  glBufferData(GL_ELEMENT_ARRAY_BUFFER, static_cast<GLsizeiptr>(_indexSize)*size , _indexData, _mode);
158 
159  m_allocated=true;
160  m_indexed=true;
161  m_indexType=_indexType;
162 }
163 
164 
165 
166 
167 void VertexArrayObject::updateIndexedData( size_t _size, const GLfloat &_data,GLenum _mode )
168 {
169 
170  if(m_bound == false)
171  {
172  std::cerr<<"trying to set VOA data when unbound\n";
173  }
174 
175  if(m_allocated && m_indexed)
176  {
178  glBufferData(GL_ARRAY_BUFFER, static_cast<GLsizeiptr>(_size), &_data, _mode);
179  }
180 }
181 
182 
183 void VertexArrayObject::updateIndexedData(GLuint vboidx, size_t _size,const GLfloat &_data,GLenum _mode)
184 {
185  if(m_bound == false)
186  {
187  std::cerr<<"trying to set VOA data when unbound\n";
188  }
189 
190  if(m_allocated && m_indexed)
191  {
193  glBufferData(GL_ARRAY_BUFFER, static_cast<GLsizeiptr>(_size), &_data, _mode);
194  }
195 }
196 
197 
198 
199 void VertexArrayObject::updateData( unsigned int _size, const GLfloat &_data,GLenum _mode )
200 {
201 
202  if(m_bound == false)
203  {
204  std::cerr<<"trying to set VOA data when unbound\n";
205  }
206 
207  if(m_allocated )
208  {
210  glBufferData(GL_ARRAY_BUFFER, _size, &_data, _mode);
211  }
212 }
213 
214 
215 void VertexArrayObject::updateData(GLuint vboidx, unsigned int _size,const GLfloat &_data,GLenum _mode)
216 {
217  if(m_bound == false)
218  {
219  std::cerr<<"trying to set VOA data when unbound\n";
220  }
221 
222  if(m_allocated )
223  {
225  glBufferData(GL_ARRAY_BUFFER, _size, &_data, _mode);
226  }
227 }
228 
229 
230 
232 {
233  GLuint id=0;
235  if(_index<m_vboIDs.size())
236  {
237  id=m_vboIDs[_index];
238  }
239  return id;
240 }
241 
242 //----------------------------------------------------------------------------------------------------------------------
243 void VertexArrayObject::setVertexAttributePointer(GLuint _id, GLint _size, GLenum _type, GLsizei _stride, unsigned int _dataOffset, bool _normalise )
244 {
245  if(m_bound !=true)
246  {
247  std::cerr<<"Warning trying to set attribute on Unbound VOA\n";
248  }
249 
250  glVertexAttribPointer(_id,_size,_type,_normalise,_stride,static_cast<Real *>(NULL) + _dataOffset);// ((Real *)NULL + (_dataOffset)));
252 }
253 
254 
255 void VertexArrayObject::setVertexAttributeIPointer( GLuint _id, GLint _size, GLenum _type, GLsizei _stride, unsigned int _dataOffset )
256 {
257  if(m_bound !=true)
258  {
259  std::cerr<<"Warning trying to set attribute on Unbound VOA\n";
260  }
261 
262  glVertexAttribIPointer(_id,_size,_type,_stride,static_cast<Real *>(NULL) +_dataOffset) ;//((Real *)NULL + (_dataOffset)));
264 }
265 
266 
267 
268 //----------------------------------------------------------------------------------------------------------------------
270 {
271  if(m_allocated == false)
272  {
273  std::cerr<<"Warning trying to draw an unallocated VOA\n";
274  }
275  if(m_bound == false)
276  {
277  std::cerr<<"Warning trying to draw an unbound VOA\n";
278  }
279 
280  if(m_indexed == false)
281  {
282  glDrawArrays(m_drawMode, 0, static_cast<GLsizei>(m_indicesCount)); // draw first object
283  }
284  else
285  {
286  glDrawElements(m_drawMode,static_cast<GLsizei>(m_indicesCount),m_indexType,static_cast<GLvoid *>(nullptr));
287  }
288 }
289 
290 
291 void VertexArrayObject::draw(unsigned int _startIndex, unsigned int _numVerts, GLenum _mode ) const
292 {
293  if(m_allocated == false)
294  {
295  std::cerr<<"Warning trying to draw an unallocated VOA\n";
296  }
297  if(m_bound == false)
298  {
299  std::cerr<<"Warning trying to draw an unbound VOA\n";
300  }
301  glDrawArrays(_mode, static_cast<GLsizei>(_startIndex), static_cast<GLsizei>(_numVerts)); // draw first object
302 }
303 
305 {
306  if(m_allocated == false)
307  {
308  std::cerr<<"Warning trying to draw an unallocated VOA\n";
309  }
310  if(m_bound == false)
311  {
312  std::cerr<<"Warning trying to draw an unbound VOA\n";
313  }
314 
315  if(m_indexed == false)
316  {
317  glDrawArrays(_mode, 0, static_cast<GLsizei>(m_indicesCount)); // draw first object
318  }
319  else
320  {
321  glDrawElements(_mode,static_cast<GLsizei>(m_indicesCount),m_indexType,static_cast<GLvoid *>(nullptr));//(GLvoid*)((char*)NULL));
322  }
323 }
324 
325 void VertexArrayObject::drawInstanced(unsigned int _n) const
326 {
327  if(m_allocated == false)
328  {
329  std::cerr<<"Warning trying to draw an unallocated VOA\n";
330  }
331  if(m_bound == false)
332  {
333  std::cerr<<"Warning trying to draw an unbound VOA\n";
334  }
335 
336  if(m_indexed == false)
337  {
338  glDrawArraysInstanced(m_drawMode, 0, static_cast<GLsizei>(m_indicesCount),static_cast<GLsizei>(_n)); // draw first object
339  }
340  else
341  {
342 
343  glDrawElementsInstanced(m_drawMode,static_cast<GLsizei>(m_indicesCount),m_indexType,nullptr,static_cast<GLsizei>(_n));
344  }
345 }
346 
347 //----------------------------------------------------------------------------------------------------------------------
348 Real *VertexArrayObject::getDataPointer(unsigned int _vbo, GLenum _accessMode)
349 {
350  Real *ptr=nullptr;
351 // code was this but g++ 4.2 gives warning about it always being true
352 // removed the first test as change to uint so should be ok
353 // if(_vbo >=0 && _vbo<m_vboIDs.size())
354 //
355  if(_vbo<m_vboIDs.size())
356  {
357  bind();
359  #ifndef USINGIOS_
360  ptr = static_cast<Real *>(glMapBuffer(GL_ARRAY_BUFFER, _accessMode));
361  #endif
362  }
363  return ptr;
364 }
365 
367 {
368  glUnmapBuffer(GL_ARRAY_BUFFER); // unmap it after use
369 }
370 
372 {
373  if(m_bound == false)
374  {
375  std::cerr<<"Warning trying to access an unbound VOA\n";
376  }
377 
378  int size;
380  return size;
381 }
382 
383 } // end namspace ngl
384 
385 
386 
void setVertexAttributePointer(GLuint _id, GLint _size, GLenum _type, GLsizei _stride, unsigned int _dataOffset, bool _normalise=GL_FALSE)
set the generic vertex attribute pointer data
bool m_indexed
flag to indicate if we have an index or non index vao to draw
#define glGenVertexArrays
Definition: glew.h:7447
#define glVertexAttribIPointer
Definition: glew.h:2276
#define glVertexAttribPointer
Definition: glew.h:2002
unsigned int GLuint
Definition: glew.h:280
void GLvoid
Definition: glew.h:293
void updateData(unsigned int _size, const GLfloat &_data, GLenum _mode=GL_STREAM_DRAW)
allow to update the vertex data of the VBO when declared as dynamic (with GL_STREAM_DRAW) ...
void drawInstanced(GLenum _n) const
draw the VOA _n times using instanced methods from GL (use transform feedback)
#define glEnableVertexAttribArray
Definition: glew.h:1921
#define glMapBuffer
Definition: glew.h:1719
#define GL_ELEMENT_ARRAY_BUFFER
Definition: glew.h:1649
void setVertexAttributeIPointer(GLuint _id, GLint _size, GLenum _type, GLsizei _stride, unsigned int _dataOffset)
set the vertex attribute pointer as an Integer this will not be normalised etc
#define glUnmapBuffer
Definition: glew.h:1720
unsigned short GLushort
Definition: glew.h:287
#define glDeleteVertexArrays
Definition: glew.h:7446
GLenum m_drawMode
the draw mode of the VAO e.g. GL_TRIANGLES
#define GL_BUFFER_SIZE
Definition: glew.h:1642
int getSize() const
get the size in bytes of the VAO
#define GL_UNSIGNED_BYTE
Definition: glew.h:637
unsigned int GLenum
Definition: glew.h:278
implementation files for RibExport class
Definition: AABB.cpp:22
#define glBindVertexArray
Definition: glew.h:7445
float GLfloat
Definition: glew.h:289
PRECISION Real
create a variable called Real which is the main data type we use (GLfloat for most cases) ...
Definition: Types.h:127
GLdouble GLdouble GLdouble b
Definition: glew.h:9162
void setData(size_t _size, const GLfloat &_data, GLenum _mode=GL_STATIC_DRAW)
allocate our data using raw face values (for example tri&#39;s) data, attributes must be bound to match a...
void freeDataPointer()
unmap the data pointer
bool m_bound
flag to indicate if we are bound
void setRawIndexedData(size_t _size, const GLvoid *_data, unsigned int _indexSize, const GLvoid *_indexData, GLenum _indexType, GLenum _mode=GL_STATIC_DRAW)
allocate our data using raw face values (for example tri&#39;s) data, attributes must be bound to match a...
#define glDrawArraysInstanced
Definition: glew.h:2327
GLuint id
Definition: glew.h:1682
GLAPI void GLAPIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
VertexArrayObject()
hide the ctor as we want to create static factory only
#define glGenBuffers
Definition: glew.h:1709
void draw() const
draw the VOA
bool m_allocated
flag to indicate if we have allocated the data to the VAO
#define GL_UNSIGNED_INT
Definition: glew.h:641
#define GL_UNSIGNED_SHORT
Definition: glew.h:639
#define glGetBufferParameteriv
Definition: glew.h:1711
void updateIndexedData(size_t _size, const GLfloat &_data, GLenum _mode=GL_STREAM_DRAW)
allow to update the vertex data of the VBO when declared as dynamic (with GL_STREAM_DRAW) ...
GLuint m_id
the id of the VAO allocated by OpenGL
std::vector< GLuint > m_vboIDs
an array of VBO associated with this VAO
#define glDrawElementsInstanced
Definition: glew.h:2328
void setIndexedData(size_t _size, const GLfloat &_data, unsigned int _indexSize, const GLvoid *_indexData, GLenum _indexType, GLenum _mode=GL_STATIC_DRAW)
allocate our data using raw face values (for example tri&#39;s) data, attributes must be bound to match a...
void removeVOA()
delete the VOA (using OpenGL calls to clear data etc)
void unbind()
unbind the VOA and set 0 to be the active VOA
GLsizeiptr size
Definition: glew.h:1684
GLuint m_indicesCount
the number of faces to draw
GLuint getVBOid(unsigned int _index)
get the VBO id for the data mapped at index _index basically this will be the vbo for the setData cal...
#define glDeleteBuffers
Definition: glew.h:1706
GLuint m_iboID
the id of the index bufffer object
#define glBindBuffer
Definition: glew.h:1703
#define GL_ARRAY_BUFFER
Definition: glew.h:1648
int GLint
Definition: glew.h:281
a class to store an OpenGL VAO
Real * getDataPointer(unsigned int _vbo, GLenum _accessMode=GL_READ_WRITE)
grab a pointer to the first block of the data
void bind()
bind this VOA to make it active
GLenum m_indexType
Specifies the type of the values in the indices buffer. Must be one of GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, or GL_UNSIGNED_INT.
#define glBufferData
Definition: glew.h:1704
int GLsizei
Definition: glew.h:282
GLAPI void GLAPIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
unsigned char GLubyte
Definition: glew.h:286