OGLplus (0.52.0) a C++ wrapper for OpenGL

draw.hpp
Go to the documentation of this file.
1 
12 #pragma once
13 #ifndef OGLPLUS_SHAPES_DRAW_1107121519_HPP
14 #define OGLPLUS_SHAPES_DRAW_1107121519_HPP
15 
16 #include <oglplus/config/basic.hpp>
18 #include <oglplus/data_type.hpp>
19 
20 #include <vector>
21 #include <cassert>
22 
23 namespace oglplus {
24 namespace shapes {
25 
27 
31 {
32 private:
33  const size_t _sizeof_index;
34  const oglplus::DataType _index_data_type;
35 
36  template <typename IT>
37  static size_t _do_get_sizeof_index(const std::vector<IT>*)
38  {
39  return sizeof(IT);
40  }
41 
42  template <class ShapeBuilder>
43  static size_t _get_sizeof_index(const ShapeBuilder&)
44  {
45  return _do_get_sizeof_index(
46  (typename ShapeBuilder::IndexArray*)nullptr
47  );
48  }
49 
50  template <typename IT>
51  static oglplus::DataType _do_get_index_data_type(const std::vector<IT>*)
52  {
53  return oglplus::GetDataType<IT>();
54  }
55 
56  template <class ShapeBuilder>
57  static oglplus::DataType _get_index_data_type(const ShapeBuilder&)
58  {
59  return _do_get_index_data_type(
60  (typename ShapeBuilder::IndexArray*)nullptr
61  );
62  }
63 public:
64  template <class ShapeBuilder>
65  ElementIndexInfo(const ShapeBuilder& builder)
66  : _sizeof_index(_get_sizeof_index(builder))
67  , _index_data_type(_get_index_data_type(builder))
68  { }
69 
71  size_t Size(void) const
72  {
73  return _sizeof_index;
74  }
75 
78  {
79  return _index_data_type;
80  }
81 };
82 
83 } // namespace shapes
84 
86 OGLPLUS_ENUM_CLASS_BEGIN(ShapeDrawOperationMethod, GLuint)
87  OGLPLUS_ENUM_CLASS_VALUE(DrawArrays, 0)
88  OGLPLUS_ENUM_CLASS_COMMA
89  OGLPLUS_ENUM_CLASS_VALUE(DrawElements, 1)
90  // TODO
91 OGLPLUS_ENUM_CLASS_END(ShapeDrawOperationMethod)
92 
93 namespace shapes {
94 
96 
101 {
104 
109 
111  GLuint first;
112 
114  GLuint count;
115 
117  static GLuint NoRestartIndex(void)
118  {
119  return ~GLuint(0);
120  }
121 
123 
127 
129 
135  GLuint phase;
136 
137  void Draw(
138  const ElementIndexInfo& index_info,
139  GLuint inst_count = 1,
140  GLuint base_inst = 0
141  ) const
142  {
143  this->Draw_(
144  IndexPtr_(index_info),
145  index_info.DataType(),
146  inst_count,
147  base_inst
148  );
149  }
150 
152  template <typename IT>
153  void Draw(
154  const std::vector<IT>& indices,
155  GLuint inst_count = 1,
156  GLuint base_inst = 0
157  ) const
158  {
159  this->Draw_(
160  IndexPtr_(indices),
161  IndexDataType_(indices),
162  inst_count,
163  base_inst
164  );
165  }
166 private:
167 
168  template <typename IT>
169  static DataType IndexDataType_(const std::vector<IT>&)
170  {
171  return GetDataType<IT>();
172  }
173 
174  template <typename IT>
175  void* IndexPtr_(const std::vector<IT>& indices) const
176  {
177  const IT* base = indices.empty() ? nullptr : indices.data();
178  return (void*)(base + first);
179  }
180 
181  void* IndexPtr_(const ElementIndexInfo& index_info) const
182  {
183  return (void*)(first * index_info.Size());
184  }
185 
186  void SetupPrimitiveRestart_(void) const;
187  void CleanupPrimitiveRestart_(void) const;
188 
189  void Draw_(
190  void* indices,
191  DataType index_data_type,
192  GLuint inst_count,
193  GLuint base_inst
194  ) const;
195 
196  void DrawArrays_(GLuint inst_count, GLuint base_inst) const;
197 
198  void DrawElements_(
199  void* indices,
200  DataType index_data_type,
201  GLuint inst_count,
202  GLuint base_inst
203  ) const;
204 };
205 
206 class DrawingInstructionWriter;
207 
209 
220 {
221 private:
222 
223  typedef std::vector<DrawOperation> DrawOperationSeq;
224  DrawOperationSeq _ops;
225 
226  DrawingInstructions(void)
227  { }
228 
229  DrawingInstructions(DrawOperationSeq&& ops)
230  : _ops(std::move(ops))
231  { }
232 
233  friend class DrawingInstructionWriter;
234 
235  // helper functor used as DrawFun in Draw_
236  template <class IndexArray>
237  struct DrawFromIndices_
238  {
239  const IndexArray& _indices;
240 
241  DrawFromIndices_(const IndexArray& indices)
242  : _indices(indices)
243  { }
244 
245  void operator()(
246  const DrawOperation& op,
247  GLuint inst_count,
248  GLuint base_inst
249  ) const
250  {
251  op.Draw(_indices, inst_count, base_inst);
252  }
253  };
254 
255  // helper functor used as DrawFun in Draw_
256  struct DrawFromIndexInfo_
257  {
258  ElementIndexInfo _index_info;
259 
260  DrawFromIndexInfo_(const ElementIndexInfo& index_info)
261  : _index_info(index_info)
262  { }
263 
264  void operator()(
265  const DrawOperation& op,
266  GLuint inst_count,
267  GLuint base_inst
268  ) const
269  {
270  op.Draw(_index_info, inst_count, base_inst);
271  }
272  };
273 
275  template <typename DrawFun, typename Driver>
276  void Draw_(
277  const DrawFun& draw_fun,
278  const GLuint inst_count,
279  const GLuint base_inst,
280  const Driver& driver
281  ) const
282  {
283  auto i=_ops.begin(),e=_ops.end();
284  if(i != e)
285  {
286  bool do_draw;
287  if(driver(i->phase))
288  {
289  do_draw = true;
290  draw_fun(*i, inst_count, base_inst);
291  }
292  else do_draw = false;
293  GLuint prev_phase = i->phase;
294  ++i;
295 
296  while(i!=e)
297  {
298  if(prev_phase != i->phase)
299  {
300  do_draw = driver(i->phase);
301  prev_phase = i->phase;
302  }
303  if(do_draw) draw_fun(*i, inst_count, base_inst);
304  ++i;
305  }
306  }
307  }
308 public:
310  : _ops(std::move(temp._ops))
311  { }
312 
314  : _ops(other._ops)
315  { }
316 
317  const std::vector<DrawOperation>& Operations(void) const
318  {
319  return _ops;
320  }
321 
322  struct DefaultDriver
323  {
324  inline bool operator()(GLuint /*phase*/) const
325  {
326  return true;
327  }
328  };
329 
330  template <typename IT, typename Driver>
331  void Draw(
332  const std::vector<IT>& indices,
333  GLuint inst_count,
334  GLuint base_inst,
335  Driver driver
336  ) const
337  {
338  this->Draw_(
339  DrawFromIndices_<std::vector<IT>>(indices),
340  inst_count,
341  base_inst,
342  driver
343  );
344  }
345 
346  template <typename IT>
347  void Draw(
348  const std::vector<IT>& indices,
349  GLuint inst_count = 1,
350  GLuint base_inst = 0
351  ) const
352  {
353  this->Draw_(
354  DrawFromIndices_<std::vector<IT>>(indices),
355  inst_count,
356  base_inst,
357  DefaultDriver()
358  );
359  }
360 
361  template <typename Driver>
362  void Draw(
363  const ElementIndexInfo& index_info,
364  GLuint inst_count,
365  GLuint base_inst,
366  Driver driver
367  ) const
368  {
369  this->Draw_(
370  DrawFromIndexInfo_(index_info),
371  inst_count,
372  base_inst,
373  driver
374  );
375  }
376 
377  void Draw(
378  const ElementIndexInfo& index_info,
379  GLuint inst_count = 1,
380  GLuint base_inst = 0
381  ) const
382  {
383  this->Draw_(
384  DrawFromIndexInfo_(index_info),
385  inst_count,
386  base_inst,
387  DefaultDriver()
388  );
389  }
390 
391 
392 };
393 
394 // Helper base class for shape builder classes making the drawing instructions
395 class DrawingInstructionWriter
396 {
397 private:
398  typedef DrawingInstructions::DrawOperationSeq Operations;
399 protected:
400  static DrawingInstructions MakeInstructions(void)
401  {
402  return DrawingInstructions();
403  }
404 
405  static void AddInstruction(
406  DrawingInstructions& instr,
407  const DrawOperation& operation
408  )
409  {
410  instr._ops.push_back(operation);
411  }
412 
413  static DrawingInstructions MakeInstructions(const DrawOperation& operation)
414  {
415  DrawingInstructions instr;
416  instr._ops.push_back(operation);
417  return instr;
418  }
419 
420  static DrawingInstructions MakeInstructions(Operations&& ops)
421  {
422  return DrawingInstructions(std::forward<Operations>(ops));
423  }
424 };
425 
426 struct DrawMode
427 {
428  struct Default { };
429  struct WithAdjacency { };
430  struct Quads { };
431  struct Patches { };
432  struct Edges { };
433 };
434 
435 
436 } // shapes
437 } // oglplus
438 
439 #if !OGLPLUS_LINK_LIBRARY || defined(OGLPLUS_IMPLEMENTING_LIBRARY)
440 #include <oglplus/shapes/draw.ipp>
441 #endif // OGLPLUS_LINK_LIBRARY
442 
443 #endif // include guard
DataType
OpenGL data type enumeration.
Definition: data_type.hpp:34
PrimitiveType
Primitive type enumeration.
Definition: primitive_type.hpp:29
GLuint first
The first element.
Definition: draw.hpp:111
OpenGL primitive type-related declarations.
Helper class storing information about shape element index datatype.
Definition: draw.hpp:30
oglplus::ShapeDrawOperationMethod Method
Enumeration of drawing methods.
Definition: draw.hpp:103
size_t Size(void) const
Returns the size (in bytes) of index type used by ShapeBuilder.
Definition: draw.hpp:71
PrimitiveType mode
The primitive type to be used to draw.
Definition: draw.hpp:108
GLuint restart_index
Primitive restart index.
Definition: draw.hpp:126
Data type-related declarations.
static GLuint NoRestartIndex(void)
Special constant for disabling primitive restart.
Definition: draw.hpp:117
Structure containing information about how to draw a part of a shape.
Definition: draw.hpp:100
void Draw(const std::vector< IT > &indices, GLuint inst_count=1, GLuint base_inst=0) const
Draw the part of a shape.
Definition: draw.hpp:153
oglplus::DataType DataType(void) const
Returns the GL datatype of index type used by ShapeBuilder.
Definition: draw.hpp:77
GLuint count
Count of elements.
Definition: draw.hpp:114
ShapeDrawOperationMethod
Enumeration of drawing methods.
Definition: draw.hpp:86
Method method
The method to be used to draw.
Definition: draw.hpp:106
GLuint phase
The phase of the drawing process.
Definition: draw.hpp:135
Class encapsulating the instructions for drawing of a shape.
Definition: draw.hpp:219

Copyright © 2010-2014 Matúš Chochlík, University of Žilina, Žilina, Slovakia.
<matus.chochlik -at- fri.uniza.sk>
<chochlik -at -gmail.com>
Documentation generated on Mon Sep 22 2014 by Doxygen (version 1.8.6).