Visualization Library 2.0.0

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
MultiDrawElements.hpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2020, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
32 #ifndef MultiDrawElements_INCLUDE_ONCE
33 #define MultiDrawElements_INCLUDE_ONCE
34 
35 #include <vlGraphics/DrawCall.hpp>
36 #include <vlGraphics/Array.hpp>
38 #include <vlCore/Log.hpp>
39 #include <vlCore/Say.hpp>
40 #include <algorithm>
41 
42 namespace vl
43 {
44  //------------------------------------------------------------------------------
45  // MultiDrawElementsBase
46  //------------------------------------------------------------------------------
53  {
55 
56  public:
58  virtual bool primitiveRestartEnabled() const { return mPrimitiveRestartEnabled; }
59 
61  void setPrimitiveRestartEnabled(bool enabled) { mPrimitiveRestartEnabled = enabled; }
62 
66  {
67  // update pointers
70  // set default base vertices to 0
71  if (mBaseVertices.size() != mCountVector.size())
72  mBaseVertices.resize(mCountVector.size());
73  }
74 
77  void setCountVector(const std::vector<GLsizei>& vcount)
78  {
79  mCountVector = vcount;
80  finalizeSetup();
81  }
82 
85  void setCountVector(const GLsizei* vcount, size_t size)
86  {
87  mCountVector.resize(size);
88  for(size_t i=0; i<size; ++i)
89  mCountVector[i] = vcount[i];
90  finalizeSetup();
91  }
92 
94  const std::vector<GLsizei>& countVector() const { return mCountVector; }
95 
97  std::vector<GLsizei>& countVector() { return mCountVector; }
98 
102  void setBaseVertices(const std::vector<GLint>& base_verts) { mBaseVertices = base_verts; }
103 
105  const std::vector<GLint>& baseVertices() const { return mBaseVertices; }
106 
108  std::vector<GLint>& baseVertices() { return mBaseVertices; }
109 
112  virtual void computePointerVector() = 0;
113 
116  virtual void computeBufferObjectPointerVector() = 0;
117 
118  protected:
120  std::vector<GLsizei> mCountVector;
121  std::vector<GLint> mBaseVertices;
122  };
123  //------------------------------------------------------------------------------
124  // MultiDrawElements
125  //------------------------------------------------------------------------------
150  template <class arr_type>
152  {
154 
155  public:
156  typedef typename arr_type::scalar_type index_type;
158  static const index_type primitive_restart_index = index_type(~0);
159  virtual unsigned int primitiveRestartIndex() { return (unsigned int)primitive_restart_index; }
160 
161  public:
163  {
164  VL_DEBUG_SET_OBJECT_NAME()
165  mType = primitive;
166  mIndexBuffer = new arr_type;
167  mPrimitiveRestartEnabled = false;
168  }
169 
171  {
172  super::operator=(other);
173  *indexBuffer() = *other.indexBuffer();
176  return *this;
177  }
178 
179  virtual ref<DrawCall> clone() const
180  {
182  *de = *this;
183  return de;
184  }
185 
186  void setIndexBuffer(arr_type* index_buffer) { mIndexBuffer = index_buffer; }
187 
188  arr_type* indexBuffer() { return mIndexBuffer.get(); }
189 
190  const arr_type* indexBuffer() const { return mIndexBuffer.get(); }
191 
193  {
194  if (indexBuffer()->isBufferObjectDirty() || (mode & BUF_ForceUpdate))
195  indexBuffer()->updateBufferObject(mode);
196  }
197 
198  virtual void deleteBufferObject()
199  {
200  indexBuffer()->bufferObject()->deleteBufferObject();
201  }
202 
203  virtual void render(bool use_bo) const
204  {
205  VL_CHECK_OGL()
206  VL_CHECK(Has_GL_EXT_multi_draw_arrays||Has_GL_Version_1_4||Has_GL_Version_3_0||Has_GL_Version_4_0);
207  VL_CHECK(!use_bo || (use_bo && Has_BufferObject))
208  use_bo &= Has_BufferObject; // && indexBuffer()->bufferObject()->handle() && indexBuffer()->sizeBufferObject();
209  if ( !use_bo && !indexBuffer()->size() )
210  return;
211 
212  // apply patch parameters if any and if using PT_PATCHES
214 
215  // primitive restart enable
217  {
219  glEnable(GL_PRIMITIVE_RESTART); VL_CHECK_OGL();
220  glPrimitiveRestartIndex(primitive_restart_index); VL_CHECK_OGL();
221  }
222 
223  const GLvoid **indices_ptr = NULL;
224  if (use_bo && indexBuffer()->bufferObject()->handle())
225  {
226  VL_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer()->bufferObject()->handle()); VL_CHECK_OGL()
227  VL_CHECK(!mBufferObjectPointerVector.empty())
228  indices_ptr = (const GLvoid**)&mBufferObjectPointerVector[0];
229  }
230  else
231  {
232  VL_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
233  VL_CHECK(!mPointerVector.empty())
234  indices_ptr = (const GLvoid**)&mPointerVector[0];
235  }
236 
237  if (baseVertices().size())
238  {
239  VL_CHECK( baseVertices().size() == pointerVector().size() )
240  VL_CHECK( baseVertices().size() == countVector().size() )
241  if (Has_GL_ARB_draw_elements_base_vertex||Has_GL_Version_3_1||Has_GL_Version_4_0)
242  {
243  glMultiDrawElementsBaseVertex( primitiveType(), (GLsizei*)&mCountVector[0], indexBuffer()->glType(), indices_ptr, (GLsizei)mCountVector.size(), (GLint*)&mBaseVertices[0] ); VL_CHECK_OGL()
244  }
245  else
246  {
247  vl::Log::error("MultiDrawElements::render(): glMultiDrawElementsBaseVertex() not supported!\n"
248  "OpenGL 3.1 or GL_ARB_draw_elements_base_vertex extension required.\n"
249  );
250  }
251  }
252  else
253  {
254  glMultiDrawElements( primitiveType(), (GLsizei*)&mCountVector[0], indexBuffer()->glType(), (const GLvoid**)indices_ptr, (GLsizei)mCountVector.size() ); VL_CHECK_OGL()
255  }
256 
257  // primitive restart disable
259  {
260  glDisable(GL_PRIMITIVE_RESTART); VL_CHECK_OGL()
261  }
262  }
263 
265 
267  {
269  iie->initialize( mIndexBuffer.get(), &mBaseVertices, &mCountVector, 0, mPrimitiveRestartEnabled, primitive_restart_index );
270  IndexIterator iit;
271  iit.initialize( iie.get() );
272  return iit;
273  }
274 
277  const std::vector<const index_type*>& pointerVector() const { return mPointerVector; }
278 
280  std::vector<const index_type*>& pointerVector() { return mPointerVector; }
281 
283  const std::vector<const index_type*>& bufferObjectPointerVector() const { return mBufferObjectPointerVector; }
284 
286  std::vector<const index_type*>& bufferObjectPointerVector() { return mBufferObjectPointerVector; }
287 
290  {
291  VL_CHECK( indexBuffer() && indexBuffer()->size() )
292  mPointerVector.resize( mCountVector.size() );
293  const index_type* ptr = (const index_type*)indexBuffer()->bufferObject()->ptr();
294  for(size_t i=0; i<mCountVector.size(); ++i)
295  {
296  mPointerVector[i] = ptr;
297  ptr += mCountVector[i];
298  }
299  }
300 
303  {
304  VL_CHECK( indexBuffer() && indexBuffer()->size() )
305  mBufferObjectPointerVector.resize( mPointerVector.size() );
306  const index_type* base_ptr = (const index_type*)indexBuffer()->ptr();
307  VL_CHECK(base_ptr)
308  for(size_t i=0; i<mPointerVector.size(); ++i)
309  {
310  size_t offset = mPointerVector[i] - base_ptr;
311  mBufferObjectPointerVector[i] = (const index_type*)0 + offset;
312  }
313  }
314 
315  protected:
317  std::vector<const index_type*> mPointerVector;
318  std::vector<const index_type*> mBufferObjectPointerVector;
319  };
320  //------------------------------------------------------------------------------
321  // typedefs
322  //------------------------------------------------------------------------------
324  class MultiDrawElementsUInt: public MultiDrawElements<ArrayUInt1>
325  {
327 
328  public:
330  :MultiDrawElements<ArrayUInt1>(primitive)
331  {
332  VL_DEBUG_SET_OBJECT_NAME();
333  }
334  };
335  //------------------------------------------------------------------------------
337  class MultiDrawElementsUShort: public MultiDrawElements<ArrayUShort1>
338  {
340 
341  public:
343  :MultiDrawElements<ArrayUShort1>(primitive)
344  {
345  VL_DEBUG_SET_OBJECT_NAME();
346  }
347  };
348  //------------------------------------------------------------------------------
350  class MultiDrawElementsUByte: public MultiDrawElements<ArrayUByte1>
351  {
353 
354  public:
356  :MultiDrawElements<ArrayUByte1>(primitive)
357  {
358  VL_DEBUG_SET_OBJECT_NAME();
359  }
360  };
361 //-----------------------------------------------------------------------------
362  template <class arr_type>
364  {
367  primitiveRestartEnabled(), primitive_restart_index );
368  it->initialize();
369  return TriangleIterator(it.get());
370  }
371 //-----------------------------------------------------------------------------
372 }
373 
374 #endif
Wrapper for the OpenGL function glMultiDrawElements().
MultiDrawElements(EPrimitiveType primitive=PT_TRIANGLES)
TriangleIterator triangleIterator() const
Returns a TriangleIterator used to iterate through the triangles of a DrawCall.
bool Has_GL_Version_1_4
Definition: OpenGL.cpp:52
void finalizeSetup()
Calls computePointerVector(), computeBufferObjectPointerVector() and resizes the base vertex array to...
std::vector< GLint > & baseVertices()
Returns the list of base vertices, one for each primitive.
See MultiDrawElements.
An array of GLubyte.
Definition: Array.hpp:455
void setIndexBuffer(arr_type *index_buffer)
const T * get() const
Definition: Object.hpp:128
std::vector< const index_type * > & pointerVector()
The pointer vector used as &#39;indices&#39; parameter of glMultiDrawElements when NOT using BufferObjects...
For internal use only.
const std::vector< GLint > & baseVertices() const
Returns the list of base vertices, one for each primitive.
Index iterator operating over DrawElements, DrawRangeElements and MultiDrawElements.
std::vector< GLsizei > & countVector()
The count vector used as &#39;count&#39; parameter of glMultiDrawElements.
const std::vector< GLsizei > & countVector() const
The count vector used as &#39;count&#39; parameter of glMultiDrawElements.
MultiDrawElementsUByte(EPrimitiveType primitive=PT_TRIANGLES)
MultiDrawElementsUInt(EPrimitiveType primitive=PT_TRIANGLES)
Base interface for all MultiDrawElements* sub classes.
void setCountVector(const GLsizei *vcount, size_t size)
Sets the vector defining the length of each primitive and automatically computes the pointer vectors ...
std::vector< GLint > mBaseVertices
An array of GLuint.
Definition: Array.hpp:437
static void error(const String &message)
Use this function to provide information about run-time errors: file not found, out of memory...
Definition: Log.cpp:165
IndexIterator indexIterator() const
Returns a IndexIterator used to iterate through the virtual indices of a DrawCall.
std::vector< const index_type * > mBufferObjectPointerVector
See MultiDrawElements.
MultiDrawElements & operator=(const MultiDrawElements &other)
bool Has_GL_Version_4_0
Definition: OpenGL.cpp:60
bool Has_GL_Version_3_0
Definition: OpenGL.cpp:56
#define VL_INSTRUMENT_CLASS(ClassName, BaseClass)
Definition: TypeInfo.hpp:122
EPrimitiveType
Visualization Library main namespace.
void initialize(IndexIteratorAbstract *iterator)
virtual bool primitiveRestartEnabled() const
Returns whether the primitive-restart functionality is enabled or not.
void applyPatchParameters() const
Definition: DrawCall.hpp:178
bool Has_BufferObject
Definition: OpenGL.cpp:82
const std::vector< const index_type * > & pointerVector() const
The pointer vector used as &#39;indices&#39; parameter of glMultiDrawElements when NOT using BufferObjects...
virtual void computePointerVector()=0
Computes the pointer vector to be used when BufferObjects are DISABLED.
std::vector< GLsizei > mCountVector
An array of GLushort.
Definition: Array.hpp:473
virtual void render(bool use_bo) const
Executes the draw call.
virtual void deleteBufferObject()
Deletes the index buffer&#39;s BufferObject.
virtual TriangleIterator triangleIterator() const =0
Returns a TriangleIterator used to iterate through the triangles of a DrawCall.
std::vector< const index_type * > & bufferObjectPointerVector()
The pointer vector used as &#39;indices&#39; parameter of glMultiDrawElements when using BufferObjects.
virtual ref< DrawCall > clone() const
Returns a clone of the draw call.
virtual void computeBufferObjectPointerVector()=0
Computes the pointer vector to be used when BufferObjects are ENABLED.
EPrimitiveType mType
Definition: DrawCall.hpp:196
void setCountVector(const std::vector< GLsizei > &vcount)
Sets the vector defining the length of each primitive and automatically computes the pointer vectors ...
Iterator used to extract the indices of every single triangle of a DrawCall regardless of the primiti...
void computeBufferObjectPointerVector()
Computes bufferObjectPointerVector() based on the values contained in pointerVector().
EBufferObjectUpdateMode
#define NULL
Definition: OpenGLDefs.hpp:81
virtual unsigned int primitiveRestartIndex()
Returns the primitive restart index used by the draw call or 0 if primitive restart is not supported...
void setPrimitiveRestartEnabled(bool enabled)
Enables the primitive-restart functionality.
MultiDrawElementsUShort(EPrimitiveType primitive=PT_TRIANGLES)
See MultiDrawElements.
bool Has_GL_Version_3_1
Definition: OpenGL.cpp:57
#define VL_CHECK_OGL()
Definition: OpenGL.hpp:156
#define VL_INSTRUMENT_ABSTRACT_CLASS(ClassName, BaseClass)
Definition: TypeInfo.hpp:145
The base class of DrawArrays, DrawElements, MultiDrawElements and DrawRangeElements.
Definition: DrawCall.hpp:90
const std::vector< const index_type * > & bufferObjectPointerVector() const
The pointer vector used as &#39;indices&#39; parameter of glMultiDrawElements when using BufferObjects.
const arr_type * indexBuffer() const
std::vector< const index_type * > mPointerVector
void computePointerVector()
Computes pointerVector() based on the values contained on countVector().
bool Has_Primitive_Restart
Definition: OpenGL.cpp:93
The ref<> class is used to reference-count an Object.
Definition: Object.hpp:55
ref< arr_type > mIndexBuffer
Wraps a IndexIteratorAbstract to iterate over the indices of a DrawCall.
void setBaseVertices(const std::vector< GLint > &base_verts)
Returns the list of base vertices, one for each primitive.
EPrimitiveType primitiveType() const
Returns the draw call&#39;s primitive type.
Definition: DrawCall.hpp:110
arr_type::scalar_type index_type
#define VL_CHECK(expr)
Definition: checks.hpp:73
virtual void updateDirtyBufferObject(EBufferObjectUpdateMode mode)
Updates the index buffer&#39;s BufferObject if marked as dirty.