1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
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.
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.
13 * osg/PrimitiveSetIndirect
14 * Author: Julien Valentin 2016-2017
17#ifndef OSG_INDIRECTPRIMITIVESET
18#define OSG_INDIRECTPRIMITIVESET 1
20#include <osg/PrimitiveSet>
25///common interface for IndirectCommandDrawArrayss
26class OSG_EXPORT IndirectCommandDrawArrays: public BufferData
29 IndirectCommandDrawArrays() : BufferData() { setBufferObject(new DrawIndirectBufferObject()); }
31 IndirectCommandDrawArrays(const IndirectCommandDrawArrays& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/) :
32 BufferData(copy, copyop) {}
34 virtual unsigned int getTotalDataSize() const { return getNumElements()*getElementSize(); }
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;
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;
47class OSG_EXPORT IndirectCommandDrawElements: public BufferData
50 IndirectCommandDrawElements() : BufferData() { setBufferObject(new DrawIndirectBufferObject()); }
52 IndirectCommandDrawElements(const IndirectCommandDrawElements& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/)
53 : BufferData(copy, copyop) {}
55 virtual unsigned int getTotalDataSize() const { return getNumElements()*getElementSize(); }
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;
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;
72struct DrawArraysIndirectCommand
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) {}
78 unsigned int instanceCount;
80 unsigned int baseInstance;
83/// default implementation of IndirectCommandDrawArrays
84/// DefaultIndirectCommandDrawArrays to be hosted on GPU
85class DefaultIndirectCommandDrawArrays: public IndirectCommandDrawArrays, public MixinVector<DrawArraysIndirectCommand>
88 META_Object(osg,DefaultIndirectCommandDrawArrays)
90 DefaultIndirectCommandDrawArrays() : IndirectCommandDrawArrays(), MixinVector<DrawArraysIndirectCommand>() {}
91 DefaultIndirectCommandDrawArrays(const DefaultIndirectCommandDrawArrays& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/) :
92 IndirectCommandDrawArrays(copy, copyop),MixinVector<DrawArraysIndirectCommand>() {}
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);}
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; }
108/// default implementation of IndirectCommandDrawElements
109/// DrawElementsCommand
110struct DrawElementsIndirectCommand
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) {}
116 unsigned int instanceCount;
117 unsigned int firstIndex;
118 unsigned int baseVertex;
119 unsigned int baseInstance;
122/// vector of DrawElementsCommand to be hosted on GPU
123class DefaultIndirectCommandDrawElements: public IndirectCommandDrawElements, public MixinVector<DrawElementsIndirectCommand>
126 META_Object(osg,DefaultIndirectCommandDrawElements)
128 DefaultIndirectCommandDrawElements() : IndirectCommandDrawElements(), MixinVector<DrawElementsIndirectCommand>() {}
130 DefaultIndirectCommandDrawElements(const DefaultIndirectCommandDrawElements& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/) :
131 IndirectCommandDrawElements(copy, copyop), MixinVector<DrawElementsIndirectCommand>() {}
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);}
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; }
148///////////////////////////////////////////////////////////////////////////////////////
149/// \brief The DrawElementsIndirect base PrimitiveSet
151class OSG_EXPORT DrawElementsIndirect : public DrawElements
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()); }
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()); }
161 /// set command array of this indirect primitive set
162 inline void setIndirectCommandArray(IndirectCommandDrawElements*idc)
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());
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(); }
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)
177 /// set offset of the first command to draw in the IndirectCommandDrawArrays
178 inline void setFirstCommandToDraw( unsigned int i) { _firstCommand = i; }
180 /// get offset of the first command in the IndirectCommandDrawArrays
181 inline unsigned int getFirstCommandToDraw() const { return _firstCommand; }
183 /// stride (to set if you use custom CommandArray)
184 inline void setStride( GLsizei i) { _stride=i; }
186 /// stride (to set if you use custom CommandArray)
187 inline GLsizei getStride() const { return _stride; }
189 virtual unsigned int getNumPrimitives() const=0;
192 virtual ~DrawElementsIndirect() {}
194 unsigned int _firstCommand;
196 ref_ptr<IndirectCommandDrawElements> _indirectCommandArray;
199///////////////////////////////////////////////////////////////////////////////////////
200/// \brief The DrawElementsIndirectUByte PrimitiveSet
202class OSG_EXPORT DrawElementsIndirectUByte : public DrawElementsIndirect, public VectorGLubyte
206 typedef VectorGLubyte vector_type;
208 DrawElementsIndirectUByte(GLenum mode = 0/*,unsigned int firstCommand = 0, GLsizei stride = 0*/) :
209 DrawElementsIndirect(DrawElementsUByteIndirectPrimitiveType,mode) {}
211 DrawElementsIndirectUByte(const DrawElementsIndirectUByte& array, const CopyOp& copyop=CopyOp::SHALLOW_COPY) :
212 DrawElementsIndirect(array,copyop),
213 vector_type(array) {}
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.
220 DrawElementsIndirectUByte(GLenum mode, unsigned int no, const GLubyte* ptr) :
221 DrawElementsIndirect(DrawElementsUByteIndirectPrimitiveType,mode),
222 vector_type(ptr,ptr+no) {}
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.
228 DrawElementsIndirectUByte(GLenum mode, unsigned int no) :
229 DrawElementsIndirect(DrawElementsUByteIndirectPrimitiveType,mode),
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"; }
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; }
242 virtual void draw(State& state, bool useVertexBufferObjects) const;
244 virtual void accept(PrimitiveFunctor& functor) const;
245 virtual void accept(PrimitiveIndexFunctor& functor) const;
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);
251 virtual GLenum getDataType() { return GL_UNSIGNED_BYTE; }
253 virtual void resizeElements(unsigned int numIndices) { resize(numIndices); }
254 virtual void reserveElements(unsigned int numIndices) { reserve(numIndices); }
256 virtual void setElement(unsigned int i, unsigned int v) { (*this)[i] = v; }
257 virtual unsigned int getElement(unsigned int i) { return (*this)[i]; }
259 virtual void addElement(unsigned int v) { push_back(GLubyte(v)); }
260 virtual unsigned int getNumPrimitives() const;
264 virtual ~DrawElementsIndirectUByte();
268///////////////////////////////////////////////////////////////////////////////////////
269/// \brief The DrawElementsIndirectUShort PrimitiveSet
271class OSG_EXPORT DrawElementsIndirectUShort : public DrawElementsIndirect, public VectorGLushort
275 typedef VectorGLushort vector_type;
277 DrawElementsIndirectUShort(GLenum mode = 0/*,unsigned int firstCommand = 0, GLsizei stride = 0*/) :
278 DrawElementsIndirect(DrawElementsUShortIndirectPrimitiveType,mode) {}
280 DrawElementsIndirectUShort(const DrawElementsIndirectUShort& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY) :
281 DrawElementsIndirect(array,copyop),
282 vector_type(array) {}
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.
289 DrawElementsIndirectUShort(GLenum mode, unsigned int no, const GLushort* ptr) :
290 DrawElementsIndirect(DrawElementsUShortIndirectPrimitiveType,mode),
291 vector_type(ptr,ptr+no) {}
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.
297 DrawElementsIndirectUShort(GLenum mode, unsigned int no) :
298 DrawElementsIndirect(DrawElementsUShortIndirectPrimitiveType,mode),
301 template <class InputIterator>
302 DrawElementsIndirectUShort(GLenum mode, InputIterator first,InputIterator last) :
303 DrawElementsIndirect(DrawElementsUShortIndirectPrimitiveType,mode),
304 vector_type(first,last) {}
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"; }
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; }
316 virtual void draw(State& state, bool useVertexBufferObjects) const;
318 virtual void accept(PrimitiveFunctor& functor) const;
319 virtual void accept(PrimitiveIndexFunctor& functor) const;
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);
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); }
329 virtual void setElement(unsigned int i, unsigned int v) { (*this)[i] = v; }
330 virtual unsigned int getElement(unsigned int i) { return (*this)[i]; }
332 virtual void addElement(unsigned int v) { push_back(GLushort(v)); }
333 virtual unsigned int getNumPrimitives() const;
337 virtual ~DrawElementsIndirectUShort();
340///////////////////////////////////////////////////////////////////////////////////////
341/// \brief The DrawElementsIndirectUInt PrimitiveSet
343class OSG_EXPORT DrawElementsIndirectUInt : public DrawElementsIndirect, public VectorGLuint
347 typedef VectorGLuint vector_type;
349 DrawElementsIndirectUInt(GLenum mode = 0/*,unsigned int firstCommand = 0, GLsizei stride = 0*/) :
350 DrawElementsIndirect(DrawElementsUIntIndirectPrimitiveType,mode) {}
352 DrawElementsIndirectUInt(const DrawElementsIndirectUInt& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY) :
353 DrawElementsIndirect(array,copyop),
354 vector_type(array) {}
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.
361 DrawElementsIndirectUInt(GLenum mode, unsigned int no, const GLuint* ptr) :
362 DrawElementsIndirect(DrawElementsUIntIndirectPrimitiveType,mode),
363 vector_type(ptr,ptr+no) {}
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.
369 DrawElementsIndirectUInt(GLenum mode, unsigned int no) :
370 DrawElementsIndirect(DrawElementsUIntIndirectPrimitiveType,mode),
373 template <class InputIterator>
374 DrawElementsIndirectUInt(GLenum mode, InputIterator first,InputIterator last) :
375 DrawElementsIndirect(DrawElementsUIntIndirectPrimitiveType,mode),
376 vector_type(first,last) {}
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"; }
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; }
388 virtual void draw(State& state, bool useVertexBufferObjects) const;
390 virtual void accept(PrimitiveFunctor& functor) const;
391 virtual void accept(PrimitiveIndexFunctor& functor) const;
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);
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)); }
404 virtual unsigned int getNumPrimitives() const;
408 virtual ~DrawElementsIndirectUInt();
411///////////////////////////////////////////////////////////////////////////////////////
412/// \brief The MultiDrawElementsIndirect PrimitiveSets
414class OSG_EXPORT MultiDrawElementsIndirectUShort : public DrawElementsIndirectUShort
417 MultiDrawElementsIndirectUShort(GLenum mode = 0/*,unsigned int firstCommand = 0, GLsizei stride = 0*/) :
418 DrawElementsIndirectUShort(mode),
421 _primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType));
424 MultiDrawElementsIndirectUShort(const MultiDrawElementsIndirectUShort& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY) :
425 DrawElementsIndirectUShort(mdi,copyop),
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.
435 MultiDrawElementsIndirectUShort(GLenum mode, unsigned int no, const GLushort* ptr) :
436 DrawElementsIndirectUShort(mode,no,ptr),
439 _primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType));
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.
446 MultiDrawElementsIndirectUShort(GLenum mode, unsigned int no) :
447 DrawElementsIndirectUShort(mode,no),
450 _primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType));
453 template <class InputIterator>
454 MultiDrawElementsIndirectUShort(GLenum mode, InputIterator first,InputIterator last) :
455 DrawElementsIndirectUShort(mode,first,last),
458 _primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType));
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"; }
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;
471 ///if you want to draw a subset of the IndirectCommandElement(FirstCommandToDraw,NumCommandsToDraw)
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; }
480 virtual ~MultiDrawElementsIndirectUShort();
483class OSG_EXPORT MultiDrawElementsIndirectUByte : public DrawElementsIndirectUByte
486 MultiDrawElementsIndirectUByte(GLenum mode = 0) :
487 DrawElementsIndirectUByte(mode),
490 _primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType));
494 MultiDrawElementsIndirectUByte(const MultiDrawElementsIndirectUByte& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY) :
495 DrawElementsIndirectUByte(mdi,copyop),
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.
505 MultiDrawElementsIndirectUByte(GLenum mode, unsigned int no, const GLubyte* ptr) :
506 DrawElementsIndirectUByte(mode,no,ptr),
509 _primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType));
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.
516 MultiDrawElementsIndirectUByte(GLenum mode, unsigned int no) :
517 DrawElementsIndirectUByte(mode,no),
520 _primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType));
523 template <class InputIterator>
524 MultiDrawElementsIndirectUByte(GLenum mode, InputIterator first,InputIterator last) :
525 DrawElementsIndirectUByte(mode,first,last),
528 _primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType));
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"; }
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;
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; }
548 virtual ~MultiDrawElementsIndirectUByte();
551class OSG_EXPORT MultiDrawElementsIndirectUInt : public DrawElementsIndirectUInt
554 MultiDrawElementsIndirectUInt(GLenum mode = 0) :
555 DrawElementsIndirectUInt(mode),
558 _primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType));
561 MultiDrawElementsIndirectUInt(const MultiDrawElementsIndirectUInt& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY) :
562 DrawElementsIndirectUInt(mdi,copyop),
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.
571 MultiDrawElementsIndirectUInt(GLenum mode, unsigned int no, const GLuint* ptr) :
572 DrawElementsIndirectUInt(mode,no,ptr),
575 _primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType));
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.
582 MultiDrawElementsIndirectUInt(GLenum mode, unsigned int no) :
583 DrawElementsIndirectUInt(mode,no),
586 _primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType));
589 template <class InputIterator>
590 MultiDrawElementsIndirectUInt(GLenum mode, InputIterator first,InputIterator last) :
591 DrawElementsIndirectUInt(mode,first,last),
594 _primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType));
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"; }
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;
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; }
614 virtual ~MultiDrawElementsIndirectUInt();
617///////////////////////////////////////////////////////////////////////////////////////
618/// \brief The MultiDrawArraysIndirect PrimitiveSet
620class OSG_EXPORT DrawArraysIndirect : public osg::PrimitiveSet
624 DrawArraysIndirect(GLenum mode=0, unsigned int firstcommand = 0, GLsizei stride = 0) :
625 osg::PrimitiveSet(Type(DrawArraysIndirectPrimitiveType), mode),
626 _firstCommand(firstcommand),
629 setIndirectCommandArray(new DefaultIndirectCommandDrawArrays);
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()))
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"; }
646 virtual void draw(State& state, bool useVertexBufferObjects) const;
648 virtual void accept(PrimitiveFunctor& functor) const;
649 virtual void accept(PrimitiveIndexFunctor& functor) const;
651 virtual unsigned int getNumIndices() const;
652 virtual unsigned int index(unsigned int pos) const;
653 virtual void offsetIndices(int offset);
655 virtual unsigned int getNumPrimitives() const;
657 /// stride (to set if you use custom CommandArray)
658 inline void setStride( GLsizei i) { _stride=i; }
660 /// stride (to set if you use custom CommandArray)
661 inline GLsizei getStride()const { return _stride; }
663 /// set offset of the first command in the IndirectCommandDrawArrays
664 inline void setFirstCommandToDraw( unsigned int i) { _firstCommand=i; }
666 /// get offset of the first command in the IndirectCommandDrawArrays
667 inline unsigned int getFirstCommandToDraw() const { return _firstCommand; }
669 inline void setIndirectCommandArray(IndirectCommandDrawArrays*idc)
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());
676 inline const IndirectCommandDrawArrays* getIndirectCommandArray() const { return _indirectCommandArray.get(); }
677 inline IndirectCommandDrawArrays* getIndirectCommandArray() { return _indirectCommandArray.get(); }
681 unsigned int _firstCommand;
683 ref_ptr<IndirectCommandDrawArrays> _indirectCommandArray;
687///////////////////////////////////////////////////////////////////////////////////////
688/// \brief The MultiDrawArraysIndirect PrimitiveSet
690class OSG_EXPORT MultiDrawArraysIndirect : public DrawArraysIndirect
694 MultiDrawArraysIndirect(GLenum mode=0, unsigned int firstcommand = 0, unsigned int count = 0, GLsizei stride = 0) :
695 osg::DrawArraysIndirect(mode, firstcommand, stride),
698 _primitiveType=Type(MultiDrawArraysIndirectPrimitiveType);
701 MultiDrawArraysIndirect(const MultiDrawArraysIndirect& dal,const CopyOp& copyop=CopyOp::SHALLOW_COPY) :
702 osg::DrawArraysIndirect(dal,copyop),
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"; }
711 virtual void draw(State& state, bool useVertexBufferObjects) const;
713 virtual void accept(PrimitiveFunctor& functor) const;
714 virtual void accept(PrimitiveIndexFunctor& functor) const;
716 virtual unsigned int getNumIndices() const;
717 virtual unsigned int index(unsigned int pos) const;
718 virtual void offsetIndices(int offset);
720 virtual unsigned int getNumPrimitives() const;
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; }