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]
DrawRangeElements.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 DrawRangeElements_INCLUDE_ONCE
33 #define DrawRangeElements_INCLUDE_ONCE
34 
35 #include <vlGraphics/DrawCall.hpp>
37 #include <vlGraphics/Array.hpp>
38 #include <vlCore/Log.hpp>
39 #include <vlCore/Say.hpp>
40 #include <algorithm>
41 
42 namespace vl
43 {
44 
45  //------------------------------------------------------------------------------
46  // DrawRangeElementsBase
47  //------------------------------------------------------------------------------
54  {
56 
57  public:
59  void setRangeStart(int rstart) { mRangeStart = rstart; }
60 
62  int rangeStart() const { return mRangeStart; }
63 
65  void setRangeEnd(int rend) { mRangeEnd = rend; }
66 
68  int rangeEnd() const { return mRangeEnd; }
69 
71  virtual bool primitiveRestartEnabled() const { return mPrimitiveRestartEnabled; }
72 
74  void setPrimitiveRestartEnabled(bool enabled) { mPrimitiveRestartEnabled = enabled; }
75 
80  void setBaseVertex(int base_vertex) { mBaseVertex = base_vertex; }
81 
84  int baseVertex() const { return mBaseVertex; }
85 
86  protected:
88  int mRangeEnd;
89  GLuint mBaseVertex;
91  };
92  //------------------------------------------------------------------------------
93  // DrawRangeElements
94  //------------------------------------------------------------------------------
119  template <class arr_type>
121  {
123 
124  public:
125  typedef typename arr_type::scalar_type index_type;
127  static const index_type primitive_restart_index = index_type(~0);
128  virtual unsigned int primitiveRestartIndex() { return (unsigned int)primitive_restart_index; }
129 
130  private:
131  template<typename T>
132  class Triangle
133  {
134  public:
135  T ABC[3];
136  bool operator<(const Triangle<index_type>& b) const
137  {
138  if (ABC[0] != b.ABC[0])
139  return ABC[0] < b.ABC[0];
140  else
141  if (ABC[1] != b.ABC[1])
142  return ABC[1] < b.ABC[1];
143  else
144  return ABC[2] < b.ABC[2];
145  }
146  void rotate()
147  {
148  if (ABC[0] > ABC[1])
149  { T tmp = ABC[0]; ABC[0] = ABC[1]; ABC[1] = ABC[2]; ABC[2] = tmp; }
150  if (ABC[0] > ABC[1])
151  { T tmp = ABC[0]; ABC[0] = ABC[1]; ABC[1] = ABC[2]; ABC[2] = tmp; }
152  }
153  };
154 
155  public:
156  DrawRangeElements(EPrimitiveType primitive = PT_TRIANGLES, int r_start=0, int r_end=primitive_restart_index)
157  {
158  VL_DEBUG_SET_OBJECT_NAME()
159  mType = primitive;
160  mRangeStart = r_start;
161  mRangeEnd = r_end;
162  mIndexBuffer = new arr_type;
163  mPrimitiveRestartEnabled = false;
164  mBaseVertex = 0;
165  mCount = -1; // till the end of the indexBuffer()
166  mOffset = 0; // from the beginning of the indexBuffer()
167  }
168 
170  {
171  super::operator=(other);
172  *indexBuffer() = *other.indexBuffer();
173  mRangeStart = other.mRangeStart;
174  mRangeEnd = other.mRangeEnd;
176  mBaseVertex = other.mBaseVertex;
177  mCount = other.mCount;
178  mOffset = other.mOffset;
179  return *this;
180  }
181 
182  virtual ref<DrawCall> clone() const
183  {
185  *de = *this;
186  return de;
187  }
188 
190  void setCount(i32 count) { mCount = count; }
191 
193  i32 count() const { return mCount; }
194 
196  void setOffset(u32 offset) { mOffset = offset; }
197 
199  u32 offset() const { return mOffset; }
200 
202  void setIndexBuffer(arr_type* index_buffer) { mIndexBuffer = index_buffer; }
203 
205  arr_type* indexBuffer() { return mIndexBuffer.get(); }
206 
208  const arr_type* indexBuffer() const { return mIndexBuffer.get(); }
209 
211  {
212  if (indexBuffer()->isBufferObjectDirty() || (mode & BUF_ForceUpdate))
213  indexBuffer()->updateBufferObject(mode);
214  }
215 
216  virtual void deleteBufferObject()
217  {
218  indexBuffer()->bufferObject()->deleteBufferObject();
219  }
220 
221  virtual void render(bool use_bo) const
222  {
223  VL_CHECK_OGL()
224  VL_CHECK(!use_bo || (use_bo && Has_BufferObject))
225  use_bo &= Has_BufferObject; // && indexBuffer()->bufferObject()->handle() && indexBuffer()->sizeBufferObject();
226  if ( !use_bo && !indexBuffer()->size() )
227  return;
228 
229  // apply patch parameters if any and if using PT_PATCHES
231 
232  // primitive restart enable
234  {
236  glEnable(GL_PRIMITIVE_RESTART); VL_CHECK_OGL();
237  glPrimitiveRestartIndex(primitive_restart_index); VL_CHECK_OGL();
238  }
239 
240  // compute base pointer
241 
242  const GLvoid* ptr = indexBuffer()->bufferObject()->ptr();
243  if (use_bo && indexBuffer()->bufferObject()->handle())
244  {
245  VL_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer()->bufferObject()->handle()); VL_CHECK_OGL()
246  ptr = 0;
247  }
248  else
249  {
250  VL_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); VL_CHECK_OGL()
251  }
252 
253  // compute final pointer and count
254 
255  const char*ptr_end = NULL;
256  if(mCount < 0)
257  {
258  // compute the end of the index buffer
259  ptr_end = (char*)ptr + sizeof(index_type)*(use_bo ? indexBuffer()->sizeBufferObject() : indexBuffer()->size());
260 
261  // offset in the index buffer
262  ptr = (char*)ptr + mOffset;
263  }
264  else
265  {
266  // offset in the index buffer
267  ptr = (char*)ptr + mOffset;
268 
269  // compute the end of the indices
270  ptr_end = (char*)ptr + sizeof(index_type)*mCount;
271  }
272 
273  // compute the remaining indices
274  const GLsizei count = (GLsizei)((index_type*)ptr_end - (index_type*)ptr);
275 
276  if (mBaseVertex == 0)
277  {
278  glDrawRangeElements( primitiveType(), mRangeStart, mRangeEnd, count, arr_type::gl_type, ptr ); VL_CHECK_OGL()
279  }
280  else
281  {
283  VL_glDrawRangeElementsBaseVertex( primitiveType(), mRangeStart, mRangeEnd, count, arr_type::gl_type, ptr, mBaseVertex ); VL_CHECK_OGL()
284  }
285 
286  // primitive restart disable
287 
289  {
290  glDisable(GL_PRIMITIVE_RESTART); VL_CHECK_OGL()
291  }
292  }
293 
295  {
297  new TriangleIteratorIndexed<arr_type>( mIndexBuffer.get(), primitiveType(),
298  baseVertex(), primitiveRestartEnabled(), primitive_restart_index );
299  it->initialize();
300  return TriangleIterator(it.get());
301  }
302 
304  {
306  iie->initialize( mIndexBuffer.get(), NULL, NULL, mBaseVertex, mPrimitiveRestartEnabled, primitive_restart_index );
307  IndexIterator iit;
308  iit.initialize( iie.get() );
309  return iit;
310  }
311 
313  {
314  mRangeStart = primitive_restart_index;
315  mRangeEnd = 0;
316 
317  for(IndexIterator it=indexIterator(); it.hasNext(); it.next())
318  {
319  if (it.index() < mRangeStart)
320  mRangeStart = it.index();
321  if (it.index() > mRangeEnd)
322  mRangeEnd = it.index();
323  }
324 
325  if (mRangeEnd < mRangeStart)
326  {
327  mRangeStart = 0;
328  mRangeEnd = primitive_restart_index;
329  }
330  }
331 
332  protected:
336  };
337  //------------------------------------------------------------------------------
338  // typedefs
339  //------------------------------------------------------------------------------
341  class DrawRangeElementsUInt: public DrawRangeElements<ArrayUInt1>
342  {
344 
345  public:
346  DrawRangeElementsUInt(EPrimitiveType primitive = PT_TRIANGLES, int r_start=0, int r_end=GLuint(~0))
347  :DrawRangeElements<ArrayUInt1>(primitive, r_start, r_end)
348  {
349  VL_DEBUG_SET_OBJECT_NAME();
350  }
351  };
352  //------------------------------------------------------------------------------
354  class DrawRangeElementsUShort: public DrawRangeElements<ArrayUShort1>
355  {
357 
358  public:
359  DrawRangeElementsUShort(EPrimitiveType primitive = PT_TRIANGLES, int r_start=0, int r_end=GLushort(~0))
360  :DrawRangeElements<ArrayUShort1>(primitive, r_start, r_end)
361  {
362  VL_DEBUG_SET_OBJECT_NAME();
363  }
364  };
365  //------------------------------------------------------------------------------
367  class DrawRangeElementsUByte: public DrawRangeElements<ArrayUByte1>
368  {
370 
371  public:
372  DrawRangeElementsUByte(EPrimitiveType primitive = PT_TRIANGLES, int r_start=0, int r_end=GLubyte(~0))
373  :DrawRangeElements<ArrayUByte1>(primitive, r_start, r_end)
374  {
375  VL_DEBUG_SET_OBJECT_NAME();
376  }
377  };
378  //------------------------------------------------------------------------------
379 }
380 
381 #endif
ref< arr_type > mIndexBuffer
void setBaseVertex(int base_vertex)
If base_vertx is != 0 glDrawRangeElementsBaseVertex/glDrawRangeElementsInstancedBaseVertex will be us...
An array of GLubyte.
Definition: Array.hpp:455
const T * get() const
Definition: Object.hpp:128
virtual unsigned int primitiveRestartIndex()
Returns the primitive restart index used by the draw call or 0 if primitive restart is not supported...
Index iterator operating over DrawElements, DrawRangeElements and MultiDrawElements.
void setIndexBuffer(arr_type *index_buffer)
The BufferObject containing the indices used to render.
See DrawRangeElements.
See DrawRangeElements.
An array of GLuint.
Definition: Array.hpp:437
IndexIterator indexIterator() const
Returns a IndexIterator used to iterate through the virtual indices of a DrawCall.
int i32
32 bits signed integer
Definition: std_types.hpp:49
virtual void deleteBufferObject()
Deletes the index buffer&#39;s BufferObject.
DrawRangeElements(EPrimitiveType primitive=PT_TRIANGLES, int r_start=0, int r_end=primitive_restart_index)
#define VL_INSTRUMENT_CLASS(ClassName, BaseClass)
Definition: TypeInfo.hpp:122
Wrapper for the OpenGL function glDrawRangeElements().
u32 offset() const
The offset in bytes from which the index buffer will be read.
void setRangeStart(int rstart)
Sets the range start.
int rangeEnd() const
Returns the range end.
EPrimitiveType
virtual bool primitiveRestartEnabled() const
Returns whether the primitive-restart functionality is enabled or not.
Visualization Library main namespace.
void initialize(IndexIteratorAbstract *iterator)
void applyPatchParameters() const
Definition: DrawCall.hpp:178
i32 count() const
The number of indices to render, default is -1 which means &#39;till the end of the indexBuffer() from of...
bool Has_BufferObject
Definition: OpenGL.cpp:82
For internal use only.
const arr_type * indexBuffer() const
The BufferObject containing the indices used to render.
An array of GLushort.
Definition: Array.hpp:473
virtual ref< DrawCall > clone() const
Returns a clone of the draw call.
unsigned int u32
32 bits unsigned integer
Definition: std_types.hpp:51
arr_type::scalar_type index_type
arr_type * indexBuffer()
The BufferObject containing the indices used to render.
EPrimitiveType mType
Definition: DrawCall.hpp:196
Iterator used to extract the indices of every single triangle of a DrawCall regardless of the primiti...
DrawRangeElementsUShort(EPrimitiveType primitive=PT_TRIANGLES, int r_start=0, int r_end=GLushort(~0))
EBufferObjectUpdateMode
#define NULL
Definition: OpenGLDefs.hpp:81
void setOffset(u32 offset)
The offset in bytes from which the index buffer will be read.
virtual void updateDirtyBufferObject(EBufferObjectUpdateMode mode)
Updates the index buffer&#39;s BufferObject if marked as dirty.
Base interface for all DrawRangeElements* sub classes.
void setRangeEnd(int rend)
Sets the range end.
int rangeStart() const
Returns the range start.
#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
See DrawRangeElements.
DrawRangeElementsUInt(EPrimitiveType primitive=PT_TRIANGLES, int r_start=0, int r_end=GLuint(~0))
void setCount(i32 count)
The number of indices to render, default is -1 which means &#39;till the end of the indexBuffer() from of...
virtual IndexIterator indexIterator() const =0
Returns a IndexIterator used to iterate through the virtual indices of a DrawCall.
DrawRangeElements & operator=(const DrawRangeElements &other)
virtual void render(bool use_bo) const
Executes the draw call.
bool Has_Base_Vertex
Definition: OpenGL.cpp:99
bool Has_Primitive_Restart
Definition: OpenGL.cpp:93
The ref<> class is used to reference-count an Object.
Definition: Object.hpp:55
Wraps a IndexIteratorAbstract to iterate over the indices of a DrawCall.
void setPrimitiveRestartEnabled(bool enabled)
Enables the primitive-restart functionality.
TriangleIterator triangleIterator() const
Returns a TriangleIterator used to iterate through the triangles of a DrawCall.
EPrimitiveType primitiveType() const
Returns the draw call&#39;s primitive type.
Definition: DrawCall.hpp:110
int baseVertex() const
Returns the currently used base vertex.
#define VL_CHECK(expr)
Definition: checks.hpp:73
DrawRangeElementsUByte(EPrimitiveType primitive=PT_TRIANGLES, int r_start=0, int r_end=GLubyte(~0))