openscenegraph
PrimitiveSetIndirect
Go to the documentation of this file.
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version. The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * OpenSceneGraph Public License for more details.
12 *
13 * osg/PrimitiveSetIndirect
14 * Author: Julien Valentin 2016-2017
15*/
16
17#ifndef OSG_INDIRECTPRIMITIVESET
18#define OSG_INDIRECTPRIMITIVESET 1
19
20#include <osg/PrimitiveSet>
21
22
23namespace osg {
24
25///common interface for IndirectCommandDrawArrayss
26class OSG_EXPORT IndirectCommandDrawArrays: public BufferData
27{
28public:
29 IndirectCommandDrawArrays() : BufferData() { setBufferObject(new DrawIndirectBufferObject()); }
30
31 IndirectCommandDrawArrays(const IndirectCommandDrawArrays& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/) :
32 BufferData(copy, copyop) {}
33
34 virtual unsigned int getTotalDataSize() const { return getNumElements()*getElementSize(); }
35
36 virtual unsigned int & count(const unsigned int&index)=0;
37 virtual unsigned int & instanceCount(const unsigned int&index)=0;
38 virtual unsigned int & first(const unsigned int&index)=0;
39 virtual unsigned int & baseInstance(const unsigned int&index)=0;
40
41 virtual unsigned int getElementSize() const = 0;
42 virtual unsigned int getNumElements() const = 0;
43 virtual void reserveElements(const unsigned int) = 0;
44 virtual void resizeElements(const unsigned int) = 0;
45};
46
47class OSG_EXPORT IndirectCommandDrawElements: public BufferData
48{
49public:
50 IndirectCommandDrawElements() : BufferData() { setBufferObject(new DrawIndirectBufferObject()); }
51
52 IndirectCommandDrawElements(const IndirectCommandDrawElements& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/)
53 : BufferData(copy, copyop) {}
54
55 virtual unsigned int getTotalDataSize() const { return getNumElements()*getElementSize(); }
56
57 virtual unsigned int & count(const unsigned int&index)=0;
58 virtual unsigned int & instanceCount(const unsigned int&index)=0;
59 virtual unsigned int & firstIndex(const unsigned int&index)=0;
60 virtual unsigned int & baseVertex(const unsigned int&index)=0;
61 virtual unsigned int & baseInstance(const unsigned int&index)=0;
62
63 virtual unsigned int getElementSize()const = 0;
64 virtual unsigned int getNumElements() const = 0;
65 virtual void reserveElements(const unsigned int) = 0;
66 virtual void resizeElements(const unsigned int) = 0;
67};
68
69
70
71/// DrawArraysCommand
72struct DrawArraysIndirectCommand
73{
74 DrawArraysIndirectCommand(unsigned int pcount = 0, unsigned int pinstanceCount = 0, unsigned int pfirst = 0, unsigned int pbaseInstance = 0) :
75 count(pcount), instanceCount(pinstanceCount), first(pfirst), baseInstance(pbaseInstance) {}
76
77 unsigned int count;
78 unsigned int instanceCount;
79 unsigned int first;
80 unsigned int baseInstance;
81};
82
83/// default implementation of IndirectCommandDrawArrays
84/// DefaultIndirectCommandDrawArrays to be hosted on GPU
85class DefaultIndirectCommandDrawArrays: public IndirectCommandDrawArrays, public MixinVector<DrawArraysIndirectCommand>
86{
87public:
88 META_Object(osg,DefaultIndirectCommandDrawArrays)
89
90 DefaultIndirectCommandDrawArrays() : IndirectCommandDrawArrays(), MixinVector<DrawArraysIndirectCommand>() {}
91 DefaultIndirectCommandDrawArrays(const DefaultIndirectCommandDrawArrays& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/) :
92 IndirectCommandDrawArrays(copy, copyop),MixinVector<DrawArraysIndirectCommand>() {}
93
94 virtual const GLvoid* getDataPointer() const { return empty()?0:&front(); }
95 virtual unsigned int getElementSize()const { return 16u; };
96 virtual unsigned int getNumElements() const { return static_cast<unsigned int>(size()); }
97 virtual void reserveElements(const unsigned int n) {reserve(n);}
98 virtual void resizeElements(const unsigned int n) {resize(n);}
99
100 virtual unsigned int & count(const unsigned int&index) { return at(index).count; }
101 virtual unsigned int & instanceCount(const unsigned int&index) { return at(index).instanceCount; }
102 virtual unsigned int & first(const unsigned int&index) { return at(index).first; }
103 virtual unsigned int & baseInstance(const unsigned int&index) { return at(index).baseInstance; }
104
105};
106
107
108/// default implementation of IndirectCommandDrawElements
109/// DrawElementsCommand
110struct DrawElementsIndirectCommand
111{
112 DrawElementsIndirectCommand(unsigned int pcount = 0, unsigned int pinstanceCount = 0, unsigned int pfirstIndex = 0, unsigned int pbaseVertex = 0, unsigned int pbaseInstance = 0) :
113 count(pcount), instanceCount(pinstanceCount), firstIndex(pfirstIndex), baseVertex(pbaseVertex), baseInstance(pbaseInstance) {}
114
115 unsigned int count;
116 unsigned int instanceCount;
117 unsigned int firstIndex;
118 unsigned int baseVertex;
119 unsigned int baseInstance;
120};
121
122/// vector of DrawElementsCommand to be hosted on GPU
123class DefaultIndirectCommandDrawElements: public IndirectCommandDrawElements, public MixinVector<DrawElementsIndirectCommand>
124{
125public:
126 META_Object(osg,DefaultIndirectCommandDrawElements)
127
128 DefaultIndirectCommandDrawElements() : IndirectCommandDrawElements(), MixinVector<DrawElementsIndirectCommand>() {}
129
130 DefaultIndirectCommandDrawElements(const DefaultIndirectCommandDrawElements& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/) :
131 IndirectCommandDrawElements(copy, copyop), MixinVector<DrawElementsIndirectCommand>() {}
132
133 virtual const GLvoid* getDataPointer() const { return empty()?0:&front(); }
134 virtual unsigned int getNumElements() const { return static_cast<unsigned int>(size()); }
135 virtual unsigned int getElementSize()const { return 20u; };
136 virtual void reserveElements(const unsigned int n) {reserve(n);}
137 virtual void resizeElements(const unsigned int n) {resize(n);}
138
139 virtual unsigned int & count(const unsigned int&index) { return at(index).count; }
140 virtual unsigned int & instanceCount(const unsigned int&index) { return at(index).instanceCount; }
141 virtual unsigned int & firstIndex(const unsigned int&index) { return at(index).firstIndex; }
142 virtual unsigned int & baseVertex(const unsigned int&index) { return at(index).baseVertex; }
143 virtual unsigned int & baseInstance(const unsigned int&index) { return at(index).baseInstance; }
144
145
146};
147
148///////////////////////////////////////////////////////////////////////////////////////
149/// \brief The DrawElementsIndirect base PrimitiveSet
150///
151class OSG_EXPORT DrawElementsIndirect : public DrawElements
152{
153public:
154
155 DrawElementsIndirect(Type primType=PrimitiveType, GLenum mode = 0,unsigned int firstCommand = 0, GLsizei stride = 0) :
156 DrawElements(primType,mode, 0),_firstCommand(firstCommand),_stride(stride) { setIndirectCommandArray(new DefaultIndirectCommandDrawElements()); }
157
158 DrawElementsIndirect(const DrawElementsIndirect& rhs,const CopyOp& copyop=CopyOp::SHALLOW_COPY) :
159 DrawElements(rhs,copyop),_firstCommand(rhs._firstCommand), _stride(rhs._stride) { _indirectCommandArray=(DefaultIndirectCommandDrawElements*)copyop(rhs._indirectCommandArray.get()); }
160
161 /// set command array of this indirect primitive set
162 inline void setIndirectCommandArray(IndirectCommandDrawElements*idc)
163 {
164 _indirectCommandArray = idc;
165 //ensure bo of idc is of the correct type
166 if(!dynamic_cast<DrawIndirectBufferObject* >(_indirectCommandArray->getBufferObject()))
167 _indirectCommandArray->setBufferObject(new DrawIndirectBufferObject());
168 }
169
170 /// get command array of this indirect primitive set
171 inline IndirectCommandDrawElements* getIndirectCommandArray() { return _indirectCommandArray.get(); }
172 inline const IndirectCommandDrawElements* getIndirectCommandArray() const { return _indirectCommandArray.get(); }
173
174 ///Further methods are for advanced DI when you plan to use your own IndirectCommandElement (stride)
175 ///or if you want to draw a particular command index of the IndirectCommandElement(FirstCommandToDraw)
176
177 /// set offset of the first command to draw in the IndirectCommandDrawArrays
178 inline void setFirstCommandToDraw( unsigned int i) { _firstCommand = i; }
179
180 /// get offset of the first command in the IndirectCommandDrawArrays
181 inline unsigned int getFirstCommandToDraw() const { return _firstCommand; }
182
183 /// stride (to set if you use custom CommandArray)
184 inline void setStride( GLsizei i) { _stride=i; }
185
186 /// stride (to set if you use custom CommandArray)
187 inline GLsizei getStride() const { return _stride; }
188
189 virtual unsigned int getNumPrimitives() const=0;
190
191protected:
192 virtual ~DrawElementsIndirect() {}
193
194 unsigned int _firstCommand;
195 GLsizei _stride;
196 ref_ptr<IndirectCommandDrawElements> _indirectCommandArray;
197};
198
199///////////////////////////////////////////////////////////////////////////////////////
200/// \brief The DrawElementsIndirectUByte PrimitiveSet
201///
202class OSG_EXPORT DrawElementsIndirectUByte : public DrawElementsIndirect, public VectorGLubyte
203{
204public:
205
206 typedef VectorGLubyte vector_type;
207
208 DrawElementsIndirectUByte(GLenum mode = 0/*,unsigned int firstCommand = 0, GLsizei stride = 0*/) :
209 DrawElementsIndirect(DrawElementsUByteIndirectPrimitiveType,mode) {}
210
211 DrawElementsIndirectUByte(const DrawElementsIndirectUByte& array, const CopyOp& copyop=CopyOp::SHALLOW_COPY) :
212 DrawElementsIndirect(array,copyop),
213 vector_type(array) {}
214
215 /**
216 * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used.
217 * \param no Number of intended elements. This will be the size of the underlying vector.
218 * \param ptr Pointer to a GLubyte to copy index data from.
219 */
220 DrawElementsIndirectUByte(GLenum mode, unsigned int no, const GLubyte* ptr) :
221 DrawElementsIndirect(DrawElementsUByteIndirectPrimitiveType,mode),
222 vector_type(ptr,ptr+no) {}
223
224 /**
225 * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used.
226 * \param no Number of intended elements. This will be the size of the underlying vector.
227 */
228 DrawElementsIndirectUByte(GLenum mode, unsigned int no) :
229 DrawElementsIndirect(DrawElementsUByteIndirectPrimitiveType,mode),
230 vector_type(no) {}
231
232 virtual Object* cloneType() const { return new DrawElementsIndirectUByte(); }
233 virtual Object* clone(const CopyOp& copyop) const { return new DrawElementsIndirectUByte(*this,copyop); }
234 virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const DrawElementsIndirectUByte*>(obj)!=NULL; }
235 virtual const char* libraryName() const { return "osg"; }
236 virtual const char* className() const { return "DrawElementsIndirectUByte"; }
237
238 virtual const GLvoid* getDataPointer() const { return empty()?0:&front(); }
239 virtual unsigned int getTotalDataSize() const { return static_cast<unsigned int>(size()); }
240 virtual bool supportsBufferObject() const { return false; }
241
242 virtual void draw(State& state, bool useVertexBufferObjects) const;
243
244 virtual void accept(PrimitiveFunctor& functor) const;
245 virtual void accept(PrimitiveIndexFunctor& functor) const;
246
247 virtual unsigned int getNumIndices() const { return static_cast<unsigned int>(size()); }
248 virtual unsigned int index(unsigned int pos) const { return (*this)[pos]; }
249 virtual void offsetIndices(int offset);
250
251 virtual GLenum getDataType() { return GL_UNSIGNED_BYTE; }
252
253 virtual void resizeElements(unsigned int numIndices) { resize(numIndices); }
254 virtual void reserveElements(unsigned int numIndices) { reserve(numIndices); }
255
256 virtual void setElement(unsigned int i, unsigned int v) { (*this)[i] = v; }
257 virtual unsigned int getElement(unsigned int i) { return (*this)[i]; }
258
259 virtual void addElement(unsigned int v) { push_back(GLubyte(v)); }
260 virtual unsigned int getNumPrimitives() const;
261
262protected:
263
264 virtual ~DrawElementsIndirectUByte();
265};
266
267
268///////////////////////////////////////////////////////////////////////////////////////
269/// \brief The DrawElementsIndirectUShort PrimitiveSet
270///
271class OSG_EXPORT DrawElementsIndirectUShort : public DrawElementsIndirect, public VectorGLushort
272{
273public:
274
275 typedef VectorGLushort vector_type;
276
277 DrawElementsIndirectUShort(GLenum mode = 0/*,unsigned int firstCommand = 0, GLsizei stride = 0*/) :
278 DrawElementsIndirect(DrawElementsUShortIndirectPrimitiveType,mode) {}
279
280 DrawElementsIndirectUShort(const DrawElementsIndirectUShort& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY) :
281 DrawElementsIndirect(array,copyop),
282 vector_type(array) {}
283
284 /**
285 * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used.
286 * \param no Number of intended elements. This will be the size of the underlying vector.
287 * \param ptr Pointer to a GLushort to copy index data from.
288 */
289 DrawElementsIndirectUShort(GLenum mode, unsigned int no, const GLushort* ptr) :
290 DrawElementsIndirect(DrawElementsUShortIndirectPrimitiveType,mode),
291 vector_type(ptr,ptr+no) {}
292
293 /**
294 * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used.
295 * \param no Number of intended elements. This will be the size of the underlying vector.
296 */
297 DrawElementsIndirectUShort(GLenum mode, unsigned int no) :
298 DrawElementsIndirect(DrawElementsUShortIndirectPrimitiveType,mode),
299 vector_type(no) {}
300
301 template <class InputIterator>
302 DrawElementsIndirectUShort(GLenum mode, InputIterator first,InputIterator last) :
303 DrawElementsIndirect(DrawElementsUShortIndirectPrimitiveType,mode),
304 vector_type(first,last) {}
305
306 virtual Object* cloneType() const { return new DrawElementsIndirectUShort(); }
307 virtual Object* clone(const CopyOp& copyop) const { return new DrawElementsIndirectUShort(*this,copyop); }
308 virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const DrawElementsIndirectUShort*>(obj)!=NULL; }
309 virtual const char* libraryName() const { return "osg"; }
310 virtual const char* className() const { return "DrawElementsIndirectUShort"; }
311
312 virtual const GLvoid* getDataPointer() const { return empty()?0:&front(); }
313 virtual unsigned int getTotalDataSize() const { return 2u*static_cast<unsigned int>(size()); }
314 virtual bool supportsBufferObject() const { return false; }
315
316 virtual void draw(State& state, bool useVertexBufferObjects) const;
317
318 virtual void accept(PrimitiveFunctor& functor) const;
319 virtual void accept(PrimitiveIndexFunctor& functor) const;
320
321 virtual unsigned int getNumIndices() const { return static_cast<unsigned int>(size()); }
322 virtual unsigned int index(unsigned int pos) const { return (*this)[pos]; }
323 virtual void offsetIndices(int offset);
324
325 virtual GLenum getDataType() { return GL_UNSIGNED_SHORT; }
326 virtual void resizeElements(unsigned int numIndices) { resize(numIndices); }
327 virtual void reserveElements(unsigned int numIndices) { reserve(numIndices); }
328
329 virtual void setElement(unsigned int i, unsigned int v) { (*this)[i] = v; }
330 virtual unsigned int getElement(unsigned int i) { return (*this)[i]; }
331
332 virtual void addElement(unsigned int v) { push_back(GLushort(v)); }
333 virtual unsigned int getNumPrimitives() const;
334
335protected:
336
337 virtual ~DrawElementsIndirectUShort();
338};
339
340///////////////////////////////////////////////////////////////////////////////////////
341/// \brief The DrawElementsIndirectUInt PrimitiveSet
342///
343class OSG_EXPORT DrawElementsIndirectUInt : public DrawElementsIndirect, public VectorGLuint
344{
345public:
346
347 typedef VectorGLuint vector_type;
348
349 DrawElementsIndirectUInt(GLenum mode = 0/*,unsigned int firstCommand = 0, GLsizei stride = 0*/) :
350 DrawElementsIndirect(DrawElementsUIntIndirectPrimitiveType,mode) {}
351
352 DrawElementsIndirectUInt(const DrawElementsIndirectUInt& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY) :
353 DrawElementsIndirect(array,copyop),
354 vector_type(array) {}
355
356 /**
357 * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used.
358 * \param no Number of intended elements. This will be the size of the underlying vector.
359 * \param ptr Pointer to a GLunsigned int to copy index data from.
360 */
361 DrawElementsIndirectUInt(GLenum mode, unsigned int no, const GLuint* ptr) :
362 DrawElementsIndirect(DrawElementsUIntIndirectPrimitiveType,mode),
363 vector_type(ptr,ptr+no) {}
364
365 /**
366 * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used.
367 * \param no Number of intended elements. This will be the size of the underlying vector.
368 */
369 DrawElementsIndirectUInt(GLenum mode, unsigned int no) :
370 DrawElementsIndirect(DrawElementsUIntIndirectPrimitiveType,mode),
371 vector_type(no) {}
372
373 template <class InputIterator>
374 DrawElementsIndirectUInt(GLenum mode, InputIterator first,InputIterator last) :
375 DrawElementsIndirect(DrawElementsUIntIndirectPrimitiveType,mode),
376 vector_type(first,last) {}
377
378 virtual Object* cloneType() const { return new DrawElementsIndirectUInt(); }
379 virtual Object* clone(const CopyOp& copyop) const { return new DrawElementsIndirectUInt(*this,copyop); }
380 virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const DrawElementsIndirectUInt*>(obj)!=NULL; }
381 virtual const char* libraryName() const { return "osg"; }
382 virtual const char* className() const { return "DrawElementsIndirectUInt"; }
383
384 virtual const GLvoid* getDataPointer() const { return empty()?0:&front(); }
385 virtual unsigned int getTotalDataSize() const { return 4u*static_cast<unsigned int>(size()); }
386 virtual bool supportsBufferObject() const { return false; }
387
388 virtual void draw(State& state, bool useVertexBufferObjects) const;
389
390 virtual void accept(PrimitiveFunctor& functor) const;
391 virtual void accept(PrimitiveIndexFunctor& functor) const;
392
393 virtual unsigned int getNumIndices() const { return static_cast<unsigned int>(size()); }
394 virtual unsigned int index(unsigned int pos) const { return (*this)[pos]; }
395 virtual void offsetIndices(int offset);
396
397 virtual GLenum getDataType() { return GL_UNSIGNED_INT; }
398 virtual void resizeElements(unsigned int numIndices) { resize(numIndices); }
399 virtual void reserveElements(unsigned int numIndices) { reserve(numIndices); }
400 virtual void setElement(unsigned int i, unsigned int v) { (*this)[i] = v; }
401 virtual unsigned int getElement(unsigned int i) { return (*this)[i]; }
402 virtual void addElement(unsigned int v) { push_back(GLuint(v)); }
403
404 virtual unsigned int getNumPrimitives() const;
405
406protected:
407
408 virtual ~DrawElementsIndirectUInt();
409};
410
411///////////////////////////////////////////////////////////////////////////////////////
412/// \brief The MultiDrawElementsIndirect PrimitiveSets
413///
414class OSG_EXPORT MultiDrawElementsIndirectUShort : public DrawElementsIndirectUShort
415{
416public:
417 MultiDrawElementsIndirectUShort(GLenum mode = 0/*,unsigned int firstCommand = 0, GLsizei stride = 0*/) :
418 DrawElementsIndirectUShort(mode),
419 _count(0)
420 {
421 _primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType));
422 }
423
424 MultiDrawElementsIndirectUShort(const MultiDrawElementsIndirectUShort& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY) :
425 DrawElementsIndirectUShort(mdi,copyop),
426 _count(mdi._count)
427 {
428 }
429
430 /**
431 * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used.
432 * \param no Number of intended elements. This will be the size of the underlying vector.
433 * \param ptr Pointer to a GLunsigned int to copy index data from.
434 */
435 MultiDrawElementsIndirectUShort(GLenum mode, unsigned int no, const GLushort* ptr) :
436 DrawElementsIndirectUShort(mode,no,ptr),
437 _count(0)
438 {
439 _primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType));
440 }
441
442 /**
443 * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used.
444 * \param no Number of intended elements. This will be the size of the underlying vector.
445 */
446 MultiDrawElementsIndirectUShort(GLenum mode, unsigned int no) :
447 DrawElementsIndirectUShort(mode,no),
448 _count(0)
449 {
450 _primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType));
451 }
452
453 template <class InputIterator>
454 MultiDrawElementsIndirectUShort(GLenum mode, InputIterator first,InputIterator last) :
455 DrawElementsIndirectUShort(mode,first,last),
456 _count(0)
457 {
458 _primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType));
459 }
460
461 virtual osg::Object* cloneType() const { return new MultiDrawElementsIndirectUShort(); }
462 virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new MultiDrawElementsIndirectUShort(*this,copyop); }
463 virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const MultiDrawElementsIndirectUShort*>(obj)!=NULL; }
464 virtual const char* className() const { return "MultiDrawElementsIndirectUShort"; }
465
466 virtual void draw(State& state, bool useVertexBufferObjects) const;
467 virtual void accept(PrimitiveFunctor& functor) const;
468 virtual void accept(PrimitiveIndexFunctor& functor) const;
469 virtual unsigned int getNumPrimitives() const;
470
471 ///if you want to draw a subset of the IndirectCommandElement(FirstCommandToDraw,NumCommandsToDraw)
472
473 /// count of Indirect Command to execute
474 inline void setNumCommandsToDraw( unsigned int i) { _count=i; }
475 /// count of Indirect Command to execute
476 inline unsigned int getNumCommandsToDraw()const { return _count; }
477
478protected:
479 unsigned int _count;
480 virtual ~MultiDrawElementsIndirectUShort();
481};
482
483class OSG_EXPORT MultiDrawElementsIndirectUByte : public DrawElementsIndirectUByte
484{
485public:
486 MultiDrawElementsIndirectUByte(GLenum mode = 0) :
487 DrawElementsIndirectUByte(mode),
488 _count(0)
489 {
490 _primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType));
491
492 }
493
494 MultiDrawElementsIndirectUByte(const MultiDrawElementsIndirectUByte& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY) :
495 DrawElementsIndirectUByte(mdi,copyop),
496 _count(mdi._count)
497 {
498 }
499
500 /**
501 * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used.
502 * \param no Number of intended elements. This will be the size of the underlying vector.
503 * \param ptr Pointer to a GLunsigned int to copy index data from.
504 */
505 MultiDrawElementsIndirectUByte(GLenum mode, unsigned int no, const GLubyte* ptr) :
506 DrawElementsIndirectUByte(mode,no,ptr),
507 _count(0)
508 {
509 _primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType));
510 }
511
512 /**
513 * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used.
514 * \param no Number of intended elements. This will be the size of the underlying vector.
515 */
516 MultiDrawElementsIndirectUByte(GLenum mode, unsigned int no) :
517 DrawElementsIndirectUByte(mode,no),
518 _count(0)
519 {
520 _primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType));
521 }
522
523 template <class InputIterator>
524 MultiDrawElementsIndirectUByte(GLenum mode, InputIterator first,InputIterator last) :
525 DrawElementsIndirectUByte(mode,first,last),
526 _count(0)
527 {
528 _primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType));
529 }
530
531 virtual osg::Object* cloneType() const { return new MultiDrawElementsIndirectUByte(); }
532 virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new MultiDrawElementsIndirectUByte(*this,copyop); }
533 virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const MultiDrawElementsIndirectUByte*>(obj)!=NULL; }
534 virtual const char* className() const { return "MultiDrawElementsIndirectUByte"; }
535
536 virtual void draw(State& state, bool useVertexBufferObjects) const;
537 virtual void accept(PrimitiveFunctor& functor) const;
538 virtual void accept(PrimitiveIndexFunctor& functor) const;
539 virtual unsigned int getNumPrimitives() const;
540
541 /// count of Indirect Command to execute
542 inline void setNumCommandsToDraw( unsigned int i) { _count=i; }
543 /// count of Indirect Command to execute
544 inline unsigned int getNumCommandsToDraw()const { return _count; }
545
546protected:
547 unsigned int _count;
548 virtual ~MultiDrawElementsIndirectUByte();
549};
550
551class OSG_EXPORT MultiDrawElementsIndirectUInt : public DrawElementsIndirectUInt
552{
553public:
554 MultiDrawElementsIndirectUInt(GLenum mode = 0) :
555 DrawElementsIndirectUInt(mode),
556 _count(0)
557 {
558 _primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType));
559 }
560
561 MultiDrawElementsIndirectUInt(const MultiDrawElementsIndirectUInt& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY) :
562 DrawElementsIndirectUInt(mdi,copyop),
563 _count(mdi._count)
564 {}
565
566 /**
567 * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used.
568 * \param no Number of intended elements. This will be the size of the underlying vector.
569 * \param ptr Pointer to a GLunsigned int to copy index data from.
570 */
571 MultiDrawElementsIndirectUInt(GLenum mode, unsigned int no, const GLuint* ptr) :
572 DrawElementsIndirectUInt(mode,no,ptr),
573 _count(0)
574 {
575 _primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType));
576 }
577
578 /**
579 * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used.
580 * \param no Number of intended elements. This will be the size of the underlying vector.
581 */
582 MultiDrawElementsIndirectUInt(GLenum mode, unsigned int no) :
583 DrawElementsIndirectUInt(mode,no),
584 _count(0)
585 {
586 _primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType));
587 }
588
589 template <class InputIterator>
590 MultiDrawElementsIndirectUInt(GLenum mode, InputIterator first,InputIterator last) :
591 DrawElementsIndirectUInt(mode,first,last),
592 _count(0)
593 {
594 _primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType));
595 }
596
597 virtual osg::Object* cloneType() const { return new MultiDrawElementsIndirectUInt(); }
598 virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new MultiDrawElementsIndirectUInt(*this,copyop); }
599 virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const MultiDrawElementsIndirectUInt*>(obj)!=NULL; }
600 virtual const char* className() const { return "MultiDrawElementsIndirectUInt"; }
601
602 virtual void draw(State& state, bool useVertexBufferObjects) const;
603 virtual void accept(PrimitiveFunctor& functor) const;
604 virtual void accept(PrimitiveIndexFunctor& functor) const;
605 virtual unsigned int getNumPrimitives() const;
606
607 /// count of Indirect Command to execute
608 inline void setNumCommandsToDraw( unsigned int i) { _count=i; }
609 /// count of Indirect Command to execute
610 inline unsigned int getNumCommandsToDraw()const { return _count; }
611
612protected:
613 unsigned int _count;
614 virtual ~MultiDrawElementsIndirectUInt();
615};
616
617///////////////////////////////////////////////////////////////////////////////////////
618/// \brief The MultiDrawArraysIndirect PrimitiveSet
619///
620class OSG_EXPORT DrawArraysIndirect : public osg::PrimitiveSet
621{
622public:
623
624 DrawArraysIndirect(GLenum mode=0, unsigned int firstcommand = 0, GLsizei stride = 0) :
625 osg::PrimitiveSet(Type(DrawArraysIndirectPrimitiveType), mode),
626 _firstCommand(firstcommand),
627 _stride(stride)
628 {
629 setIndirectCommandArray(new DefaultIndirectCommandDrawArrays);
630 }
631
632 DrawArraysIndirect(const DrawArraysIndirect& dal,const CopyOp& copyop=CopyOp::SHALLOW_COPY) :
633 osg::PrimitiveSet(dal,copyop),
634 _firstCommand(dal._firstCommand),
635 _stride(dal._stride),
636 _indirectCommandArray((DefaultIndirectCommandDrawArrays*)copyop( dal._indirectCommandArray.get()))
637 {
638 }
639
640 virtual osg::Object* cloneType() const { return new DrawArraysIndirect(); }
641 virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new DrawArraysIndirect(*this,copyop); }
642 virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const DrawArraysIndirect*>(obj)!=NULL; }
643 virtual const char* libraryName() const { return "osg"; }
644 virtual const char* className() const { return "DrawArraysIndirect"; }
645
646 virtual void draw(State& state, bool useVertexBufferObjects) const;
647
648 virtual void accept(PrimitiveFunctor& functor) const;
649 virtual void accept(PrimitiveIndexFunctor& functor) const;
650
651 virtual unsigned int getNumIndices() const;
652 virtual unsigned int index(unsigned int pos) const;
653 virtual void offsetIndices(int offset);
654
655 virtual unsigned int getNumPrimitives() const;
656
657 /// stride (to set if you use custom CommandArray)
658 inline void setStride( GLsizei i) { _stride=i; }
659
660 /// stride (to set if you use custom CommandArray)
661 inline GLsizei getStride()const { return _stride; }
662
663 /// set offset of the first command in the IndirectCommandDrawArrays
664 inline void setFirstCommandToDraw( unsigned int i) { _firstCommand=i; }
665
666 /// get offset of the first command in the IndirectCommandDrawArrays
667 inline unsigned int getFirstCommandToDraw() const { return _firstCommand; }
668
669 inline void setIndirectCommandArray(IndirectCommandDrawArrays*idc)
670 {
671 _indirectCommandArray = idc;
672 //ensure bo of idc is of the correct type
673 if(!dynamic_cast<DrawIndirectBufferObject* >(_indirectCommandArray->getBufferObject()))
674 _indirectCommandArray->setBufferObject(new DrawIndirectBufferObject());
675 }
676 inline const IndirectCommandDrawArrays* getIndirectCommandArray() const { return _indirectCommandArray.get(); }
677 inline IndirectCommandDrawArrays* getIndirectCommandArray() { return _indirectCommandArray.get(); }
678
679protected:
680
681 unsigned int _firstCommand;
682 GLsizei _stride;
683 ref_ptr<IndirectCommandDrawArrays> _indirectCommandArray;
684
685};
686
687///////////////////////////////////////////////////////////////////////////////////////
688/// \brief The MultiDrawArraysIndirect PrimitiveSet
689///
690class OSG_EXPORT MultiDrawArraysIndirect : public DrawArraysIndirect
691{
692public:
693
694 MultiDrawArraysIndirect(GLenum mode=0, unsigned int firstcommand = 0, unsigned int count = 0, GLsizei stride = 0) :
695 osg::DrawArraysIndirect(mode, firstcommand, stride),
696 _count(count)
697 {
698 _primitiveType=Type(MultiDrawArraysIndirectPrimitiveType);
699 }
700
701 MultiDrawArraysIndirect(const MultiDrawArraysIndirect& dal,const CopyOp& copyop=CopyOp::SHALLOW_COPY) :
702 osg::DrawArraysIndirect(dal,copyop),
703 _count(dal._count)
704 {}
705
706 virtual osg::Object* cloneType() const { return new MultiDrawArraysIndirect(); }
707 virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new MultiDrawArraysIndirect(*this,copyop); }
708 virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const MultiDrawArraysIndirect*>(obj)!=NULL; }
709 virtual const char* className() const { return "MultiDrawArraysIndirect"; }
710
711 virtual void draw(State& state, bool useVertexBufferObjects) const;
712
713 virtual void accept(PrimitiveFunctor& functor) const;
714 virtual void accept(PrimitiveIndexFunctor& functor) const;
715
716 virtual unsigned int getNumIndices() const;
717 virtual unsigned int index(unsigned int pos) const;
718 virtual void offsetIndices(int offset);
719
720 virtual unsigned int getNumPrimitives() const;
721
722 /// count of Indirect Command to execute
723 inline void setNumCommandsToDraw( unsigned int i) { _count=i; }
724 /// count of Indirect Command to execute
725 inline unsigned int getNumCommandsToDraw()const { return _count; }
726
727protected:
728 unsigned int _count;
729
730};
731
732}
733
734#endif