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]
DepthSortCallback.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 DepthSortCallback_INCLUDE_ONCE
33 #define DepthSortCallback_INCLUDE_ONCE
34 
35 #include <vlGraphics/Actor.hpp>
36 #include <vlGraphics/Geometry.hpp>
37 #include <vlGraphics/Camera.hpp>
38 
39 namespace vl
40 {
74  {
76 
77  template<typename T>
78  class Point
79  {
80  public:
81  T A;
82  };
83  template<typename T>
84  class Line
85  {
86  public:
87  T A,B;
88  };
89  template<typename T>
90  class Triangle
91  {
92  public:
93  T A,B,C;
94  };
95  template<typename T>
96  class Quad
97  {
98  public:
99  T A,B,C,D;
100  };
101  typedef Point<unsigned int> PointUInt;
102  typedef Line<unsigned int> LineUInt;
103  typedef Triangle<unsigned int> TriangleUInt;
104  typedef Quad<unsigned int> QuadUInt;
105 
106  typedef Point<unsigned short> PointUShort;
107  typedef Line<unsigned short> LineUShort;
108  typedef Triangle<unsigned short> TriangleUShort;
109  typedef Quad<unsigned short> QuadUShort;
110 
111  typedef Point<unsigned char> PointUByte;
112  typedef Line<unsigned char> LineUByte;
113  typedef Triangle<unsigned char> TriangleUByte;
114  typedef Quad<unsigned char> QuadUByte;
115 
116  class PrimitiveZ
117  {
118  public:
119  PrimitiveZ(int tri=0, float z=0.0f): mPrimitiveIndex(tri), mZ(z) {}
120  unsigned int mPrimitiveIndex;
121  float mZ;
122  };
123  class Sorter_Back_To_Front
124  {
125  public:
126  bool operator()(const PrimitiveZ& t1, const PrimitiveZ& t2) const { return t1.mZ < t2.mZ; }
127  };
128  class Sorter_Front_To_Back
129  {
130  public:
131  bool operator()(const PrimitiveZ& t1, const PrimitiveZ& t2) const { return t1.mZ > t2.mZ; }
132  };
133 
134  public:
137  {
138  VL_DEBUG_SET_OBJECT_NAME()
140  }
141 
143 
145  virtual void onActorRenderStarted(Actor* actor, real /*frame_clock*/, const Camera* cam, Renderable* renderable, const Shader*, int pass)
146  {
147  // need to sort only for the first pass
148  if (pass > 0)
149  return;
150 
151  vl::mat4 matrix = cam->viewMatrix();
152  if (actor && actor->transform())
153  matrix *= actor->transform()->worldMatrix();
154 
155  if (matrix == mCacheMatrix)
156  return;
157  else
158  mCacheMatrix = matrix;
159 
160  // this works well with LOD
161  Geometry* geometry = renderable->as<Geometry>();
162 
163  if (!geometry)
164  return;
165 
166  const ArrayAbstract* verts = geometry->vertexArray();
167 
168  if (!verts)
169  return;
170 
171  // computes eye-space vertex positions
172  mat4 m;
173  if (actor->transform())
174  m = cam->viewMatrix() * actor->transform()->worldMatrix();
175  else
176  m = cam->viewMatrix();
177  mEyeSpaceVerts.resize( verts->size() );
178  // would be nice to optimize this with SEE2
179  for(size_t i=0; i<verts->size(); ++i)
180  mEyeSpaceVerts[i] = m * verts->getAsVec3(i);
181 
182  geometry->setBufferObjectDirty(true);
183  geometry->setDisplayListDirty(true);
184 
185  for(int idraw=0; idraw<geometry->drawCalls().size(); ++idraw)
186  {
187  DrawCall* dc = geometry->drawCalls().at(idraw);
188  if (dc->classType() == DrawElementsUInt::Type())
189  sort<unsigned int, DrawElementsUInt>(dc->as<DrawElementsUInt>(), mSortedPointsUInt, mSortedLinesUInt, mSortedTrianglesUInt, mSortedQuadsUInt);
190  else
191  if (dc->classType() == DrawElementsUShort::Type())
192  sort<unsigned short, DrawElementsUShort>(dc->as<DrawElementsUShort>(), mSortedPointsUShort, mSortedLinesUShort, mSortedTrianglesUShort, mSortedQuadsUShort);
193  else
194  if (dc->classType() == DrawElementsUByte::Type())
195  sort<unsigned char, DrawElementsUByte>(dc->as<DrawElementsUByte>(), mSortedPointsUByte, mSortedLinesUByte, mSortedTrianglesUByte, mSortedQuadsUByte);
196  }
197  }
198 
199  template<typename T, typename deT>
200  void sort(deT* polys, std::vector<Point<T> >& sorted_points, std::vector<Line<T> >& sorted_lines, std::vector<Triangle<T> >& sorted_triangles, std::vector<Quad<T> >& sorted_quads)
201  {
202  if (polys->primitiveType() == PT_QUADS)
203  {
204  // compute zetas
205  mPrimitiveZ.resize( polys->indexBuffer()->size() / 4 );
206  if (mPrimitiveZ.empty())
207  return;
208 
209  const typename deT::index_type* it = polys->indexBuffer()->begin();
210  const typename deT::index_type* end = polys->indexBuffer()->end();
211  for(unsigned iz=0; it != end; it+=4, ++iz)
212  {
213  mPrimitiveZ[iz].mZ = (float)(mEyeSpaceVerts[it[0]].z() + mEyeSpaceVerts[it[1]].z() + mEyeSpaceVerts[it[2]].z() + mEyeSpaceVerts[it[3]].z());
214  mPrimitiveZ[iz].mPrimitiveIndex = iz;
215  }
216 
217  // sort based on mPrimitiveZ
218  if (sortMode() == SM_SortBackToFront)
219  std::sort( mPrimitiveZ.begin(), mPrimitiveZ.end(), Sorter_Back_To_Front() );
220  else
221  std::sort( mPrimitiveZ.begin(), mPrimitiveZ.end(), Sorter_Front_To_Back() );
222 
223  // regenerate the sorted indices
224  sorted_quads.resize( polys->indexBuffer()->size() / 4 );
225  Quad<T>* tris = (Quad<T>*)polys->indexBuffer()->ptr();
226  for(unsigned int i=0; i<mPrimitiveZ.size(); ++i)
227  sorted_quads[i] = tris[ mPrimitiveZ[i].mPrimitiveIndex ];
228  memcpy(&tris[0], &sorted_quads[0], sizeof(sorted_quads[0])*sorted_quads.size() );
229  }
230  else
231  if (polys->primitiveType() == PT_TRIANGLES)
232  {
233  // compute zetas
234  mPrimitiveZ.resize( polys->indexBuffer()->size() / 3 );
235  if (mPrimitiveZ.empty())
236  return;
237 
238  const typename deT::index_type* it = polys->indexBuffer()->begin();
239  const typename deT::index_type* end = polys->indexBuffer()->end();
240  for(unsigned iz=0; it != end; it+=3, ++iz)
241  {
242  mPrimitiveZ[iz].mZ = (float)(mEyeSpaceVerts[it[0]].z() + mEyeSpaceVerts[it[1]].z() + mEyeSpaceVerts[it[2]].z());
243  mPrimitiveZ[iz].mPrimitiveIndex = iz;
244  }
245 
246  // sort based on mPrimitiveZ
247  if (sortMode() == SM_SortBackToFront)
248  std::sort( mPrimitiveZ.begin(), mPrimitiveZ.end(), Sorter_Back_To_Front() );
249  else
250  std::sort( mPrimitiveZ.begin(), mPrimitiveZ.end(), Sorter_Front_To_Back() );
251 
252  // regenerate the sorted indices
253  sorted_triangles.resize( polys->indexBuffer()->size() / 3 );
254  Triangle<T>* tris = (Triangle<T>*)polys->indexBuffer()->ptr();
255  for(unsigned int i=0; i<mPrimitiveZ.size(); ++i)
256  sorted_triangles[i] = tris[ mPrimitiveZ[i].mPrimitiveIndex ];
257  memcpy(&tris[0], &sorted_triangles[0], sizeof(sorted_triangles[0])*sorted_triangles.size() );
258  }
259  else
260  if (polys->primitiveType() == PT_LINES)
261  {
262  // compute zetas
263  mPrimitiveZ.resize( polys->indexBuffer()->size() / 2 );
264  if (mPrimitiveZ.empty())
265  return;
266 
267  const typename deT::index_type* it = polys->indexBuffer()->begin();
268  const typename deT::index_type* end = polys->indexBuffer()->end();
269  for(unsigned iz=0; it != end; it+=2, ++iz)
270  {
271  mPrimitiveZ[iz].mZ = (float)(mEyeSpaceVerts[it[0]].z() + mEyeSpaceVerts[it[1]].z());
272  mPrimitiveZ[iz].mPrimitiveIndex = iz;
273  }
274 
275  // sort based on mPrimitiveZ
276  if (sortMode() == SM_SortBackToFront)
277  std::sort( mPrimitiveZ.begin(), mPrimitiveZ.end(), Sorter_Back_To_Front() );
278  else
279  std::sort( mPrimitiveZ.begin(), mPrimitiveZ.end(), Sorter_Front_To_Back() );
280 
281  // regenerate the sorted indices
282  sorted_lines.resize( polys->indexBuffer()->size() / 2 );
283  Line<T>* tris = (Line<T>*)polys->indexBuffer()->ptr();
284  for(unsigned int i=0; i<mPrimitiveZ.size(); ++i)
285  sorted_lines[i] = tris[ mPrimitiveZ[i].mPrimitiveIndex ];
286  memcpy(&tris[0], &sorted_lines[0], sizeof(sorted_lines[0])*sorted_lines.size() );
287  }
288  else
289  if (polys->primitiveType() == PT_POINTS)
290  {
291  // compute zetas
292  mPrimitiveZ.resize( polys->indexBuffer()->size() );
293  if (mPrimitiveZ.empty())
294  return;
295 
296  const typename deT::index_type* it = polys->indexBuffer()->begin();
297  const typename deT::index_type* end = polys->indexBuffer()->end();
298  for(unsigned iz=0; it != end; ++it, ++iz)
299  {
300  mPrimitiveZ[iz].mZ = (float)mEyeSpaceVerts[it[0]].z();
301  mPrimitiveZ[iz].mPrimitiveIndex = iz;
302  }
303 
304  // sort based on mPrimitiveZ
305  if (sortMode() == SM_SortBackToFront)
306  std::sort( mPrimitiveZ.begin(), mPrimitiveZ.end(), Sorter_Back_To_Front() );
307  else
308  std::sort( mPrimitiveZ.begin(), mPrimitiveZ.end(), Sorter_Front_To_Back() );
309 
310  // regenerate the sorted indices
311  sorted_points.resize( polys->indexBuffer()->size() );
312  Point<T>* tris = (Point<T>*)polys->indexBuffer()->ptr();
313  for(unsigned int i=0; i<mPrimitiveZ.size(); ++i)
314  sorted_points[i] = tris[ mPrimitiveZ[i].mPrimitiveIndex ];
315  memcpy(&tris[0], &sorted_points[0], sizeof(sorted_points[0])*sorted_points.size() );
316  }
317 
318  if (Has_BufferObject)
319  {
320  if (polys->indexBuffer()->bufferObject()->handle())
321  {
322  if (polys->indexBuffer()->bufferObject()->usage() != vl::BU_DYNAMIC_DRAW)
323  {
324  polys->indexBuffer()->bufferObject()->setBufferData(vl::BU_DYNAMIC_DRAW);
325  polys->indexBuffer()->setBufferObjectDirty(false);
326  }
327  else
328  polys->indexBuffer()->setBufferObjectDirty(true);
329  }
330  }
331  }
332 
333  ESortMode sortMode() const { return mSortMode; }
334  void setSortMode(ESortMode sort_mode) { mSortMode = sort_mode; }
335 
340 
341  protected:
342  std::vector<vec3> mEyeSpaceVerts;
343  std::vector<PrimitiveZ> mPrimitiveZ;
344 
345  std::vector<PointUInt> mSortedPointsUInt;
346  std::vector<LineUInt> mSortedLinesUInt;
347  std::vector<TriangleUInt> mSortedTrianglesUInt;
348  std::vector<QuadUInt> mSortedQuadsUInt;
349 
350  std::vector<PointUShort> mSortedPointsUShort;
351  std::vector<LineUShort> mSortedLinesUShort;
352  std::vector<TriangleUShort> mSortedTrianglesUShort;
353  std::vector<QuadUShort> mSortedQuadsUShort;
354 
355  std::vector<PointUByte> mSortedPointsUByte;
356  std::vector<LineUByte> mSortedLinesUByte;
357  std::vector<TriangleUByte> mSortedTrianglesUByte;
358  std::vector<QuadUByte> mSortedQuadsUByte;
359 
361 
363  };
364 }
365 
366 #endif
The ArrayAbstract class defines an abstract interface to conveniently manipulate data stored in a Buf...
Definition: Array.hpp:58
Associates a Renderable object to an Effect and Transform.
Definition: Actor.hpp:130
See DrawElements.
const mat4 & viewMatrix() const
Returns the Camera&#39;s view matrix (inverse of the modeling matrix).
Definition: Camera.hpp:161
virtual void onActorRenderStarted(Actor *actor, real, const Camera *cam, Renderable *renderable, const Shader *, int pass)
Performs the actual sorting.
std::vector< vec3 > mEyeSpaceVerts
Transform * transform()
Returns the Transform bound tho an Actor.
Definition: Actor.hpp:190
void setBufferObjectDirty(bool dirty=true)
Whether BufferObjects associated to a Renderable should be recomputed on the next rendering...
Definition: Renderable.hpp:210
std::vector< QuadUInt > mSortedQuadsUInt
const ArrayAbstract * vertexArray() const
Conventional vertex array.
Definition: Geometry.hpp:248
void sort(deT *polys, std::vector< Point< T > > &sorted_points, std::vector< Line< T > > &sorted_lines, std::vector< Triangle< T > > &sorted_triangles, std::vector< Quad< T > > &sorted_quads)
std::vector< LineUByte > mSortedLinesUByte
See DrawElements.
Data is specified many times and used many times as the source of drawing and image specification com...
#define VL_INSTRUMENT_CLASS(ClassName, BaseClass)
Definition: TypeInfo.hpp:122
virtual vec3 getAsVec3(size_t vector_index) const =0
Returns a vector from the buffer as a vec3 value.
The Geometry class is a Renderable that implements a polygonal mesh made of polygons, lines and points.
Definition: Geometry.hpp:66
Visualization Library main namespace.
void setDisplayListDirty(bool dirty)
Whether the display list associated to a Renderable should be recompiled at the next rendering...
Definition: Renderable.hpp:198
DepthSortCallback sorts the primitives of the Geometry bound to the Actor in which the callback is in...
std::vector< TriangleUByte > mSortedTrianglesUByte
bool Has_BufferObject
Definition: OpenGL.cpp:82
See DrawElements.
An abstract class that represents all the objects that can be rendered.
Definition: Renderable.hpp:58
void setSortMode(ESortMode sort_mode)
void onActorDelete(Actor *)
Event notifying that an Actor is being deleted.
std::vector< PointUByte > mSortedPointsUByte
T * as()
Casts an Object to the specified class.
Definition: Object.hpp:282
std::vector< TriangleUInt > mSortedTrianglesUInt
std::vector< LineUInt > mSortedLinesUInt
The ActorEventCallback class defines a callback object to react to Actor-related events.
Definition: Actor.hpp:75
const mat4 & worldMatrix() const
Returns the world matrix used for rendering.
Definition: Transform.hpp:168
Manages most of the OpenGL rendering states responsible of the final aspect of the rendered objects...
Definition: Shader.hpp:1830
The base class of DrawArrays, DrawElements, MultiDrawElements and DrawRangeElements.
Definition: DrawCall.hpp:90
fmat4 mat4
Defined as: &#39;typedef fmat4 mat4&#39;. See also VL_PIPELINE_PRECISION.
Definition: Matrix4.hpp:1240
virtual size_t size() const =0
Returns the number of elements of an array.
std::vector< PrimitiveZ > mPrimitiveZ
std::vector< PointUInt > mSortedPointsUInt
Represents a virtual camera defining, among other things, the point of view from which scenes can be ...
Definition: Camera.hpp:50
ESortMode sortMode() const
void invalidateCache()
Forces sorting at the next rendering.
std::vector< QuadUShort > mSortedQuadsUShort
std::vector< QuadUByte > mSortedQuadsUByte
std::vector< PointUShort > mSortedPointsUShort
std::vector< TriangleUShort > mSortedTrianglesUShort
std::vector< LineUShort > mSortedLinesUShort
Collection< DrawCall > & drawCalls()
Returns the list of DrawCall objects bound to a Geometry.
Definition: Geometry.hpp:102
DepthSortCallback()
Constructor.