From 5be14bc2ba319ff395c1b191fd29bf5edaf237a5 Mon Sep 17 00:00:00 2001 From: mp3butcher Date: Wed, 26 Jul 2017 20:25:41 +0200 Subject: [PATCH 01/19] first commit for Indirect Draw integration in osg users will have to implement interfaces for their custom drawcommandarrays add a lot of new primitive set + few defines integration is made in osggpucull --- examples/osggpucull/CMakeLists.txt | 2 - .../osggpucull/DrawIndirectPrimitiveSet.cpp | 41 -- .../osggpucull/DrawIndirectPrimitiveSet.h | 63 -- examples/osggpucull/osggpucull.cpp | 58 +- include/osg/GLDefines | 18 +- include/osg/PrimitiveSet | 10 +- include/osg/PrimitiveSetIndirect | 697 ++++++++++++++++++ src/osg/CMakeLists.txt | 2 + src/osg/PrimitiveSetIndirect.cpp | 585 +++++++++++++++ 9 files changed, 1332 insertions(+), 144 deletions(-) delete mode 100644 examples/osggpucull/DrawIndirectPrimitiveSet.cpp delete mode 100644 examples/osggpucull/DrawIndirectPrimitiveSet.h create mode 100644 include/osg/PrimitiveSetIndirect create mode 100644 src/osg/PrimitiveSetIndirect.cpp diff --git a/examples/osggpucull/CMakeLists.txt b/examples/osggpucull/CMakeLists.txt index 11d3b0463..6cfe7a646 100644 --- a/examples/osggpucull/CMakeLists.txt +++ b/examples/osggpucull/CMakeLists.txt @@ -1,13 +1,11 @@ SET(TARGET_SRC ShapeToGeometry.cpp - DrawIndirectPrimitiveSet.cpp AggregateGeometryVisitor.cpp osggpucull.cpp ) SET(TARGET_H ShapeToGeometry.h - DrawIndirectPrimitiveSet.h AggregateGeometryVisitor.h GpuCullShaders.h ) diff --git a/examples/osggpucull/DrawIndirectPrimitiveSet.cpp b/examples/osggpucull/DrawIndirectPrimitiveSet.cpp deleted file mode 100644 index bbb5ff45b..000000000 --- a/examples/osggpucull/DrawIndirectPrimitiveSet.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2014 Robert Osfield - * Copyright (C) 2014 Pawel Ksiezopolski - * - * This library is open source and may be redistributed and/or modified under - * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or - * (at your option) any later version. The full license is in LICENSE file - * included with this distribution, and on the openscenegraph.org website. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * OpenSceneGraph Public License for more details. - * -*/ -#include "DrawIndirectPrimitiveSet.h" -#include -#include -#include -#include -#include - -void DrawArraysIndirect::draw(osg::State& state, bool /*useVertexBufferObjects*/) const -{ -// if you want to see how many primitives were rendered - uncomment code below, but -// be warned : it is a serious performance killer ( because of GPU->CPU roundtrip ) - -// osg::Drawable::Extensions *dext = osg::Drawable::getExtensions( state.getContextID(),true ); -// int* tab = (int*)dext->glMapBuffer(GL_DRAW_INDIRECT_BUFFER,GL_READ_ONLY); -// int val = _indirect/sizeof(int); -// OSG_WARN<<"DrawArraysIndirect ("<glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER); - - state.get()->glDrawArraysIndirect( _mode, reinterpret_cast(_indirect) ); - -} - -void MultiDrawArraysIndirect::draw(osg::State& state, bool /*useVertexBufferObjects*/) const -{ - // DrawIndirectGLExtensions *ext = DrawIndirectGLExtensions::getExtensions( state.getContextID(),true ); - state.get()->glMultiDrawArraysIndirect( _mode, reinterpret_cast(_indirect), _drawcount, _stride ); -} diff --git a/examples/osggpucull/DrawIndirectPrimitiveSet.h b/examples/osggpucull/DrawIndirectPrimitiveSet.h deleted file mode 100644 index 8a6c7b777..000000000 --- a/examples/osggpucull/DrawIndirectPrimitiveSet.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2014 Robert Osfield - * Copyright (C) 2014 Pawel Ksiezopolski - * - * This library is open source and may be redistributed and/or modified under - * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or - * (at your option) any later version. The full license is in LICENSE file - * included with this distribution, and on the openscenegraph.org website. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * OpenSceneGraph Public License for more details. - * -*/ - -#ifndef OSG_DRAWINDIRECTPRIMITIVESET -#define OSG_DRAWINDIRECTPRIMITIVESET 1 - -#include -#include -#include - - -class DrawArraysIndirect : public osg::DrawArrays -{ -public: - DrawArraysIndirect(GLenum mode=0, unsigned int indirect=0) - : osg::DrawArrays(mode), _indirect(indirect) - { - } - virtual osg::Object* cloneType() const { return new DrawArraysIndirect(); } - virtual osg::Object* clone(const osg::CopyOp& /*copyop*/) const { return NULL; } - virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } - virtual const char* libraryName() const { return "osg"; } - virtual const char* className() const { return "DrawArraysIndirect"; } - - virtual void draw(osg::State& state, bool useVertexBufferObjects) const; -protected: - unsigned int _indirect; -}; - -class MultiDrawArraysIndirect : public osg::DrawArrays -{ -public: - MultiDrawArraysIndirect(GLenum mode=0, unsigned int indirect=0, GLsizei drawcount=0, GLsizei stride=0) - : osg::DrawArrays(mode), _indirect(indirect), _drawcount(drawcount), _stride(stride) - { - } - virtual osg::Object* cloneType() const { return new MultiDrawArraysIndirect(); } - virtual osg::Object* clone(const osg::CopyOp& /*copyop*/) const { return NULL; } - virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } - virtual const char* libraryName() const { return "osg"; } - virtual const char* className() const { return "MultiDrawArraysIndirect"; } - - virtual void draw(osg::State& state, bool useVertexBufferObjects) const; -protected: - unsigned int _indirect; - GLsizei _drawcount; - GLsizei _stride; -}; - - -#endif diff --git a/examples/osggpucull/osggpucull.cpp b/examples/osggpucull/osggpucull.cpp index b091a4921..52d272db5 100644 --- a/examples/osggpucull/osggpucull.cpp +++ b/examples/osggpucull/osggpucull.cpp @@ -38,12 +38,14 @@ #include #include "ShapeToGeometry.h" #include "AggregateGeometryVisitor.h" +#if 0 #include "DrawIndirectPrimitiveSet.h" +#else +#include +#endif #include "GpuCullShaders.h" -#ifndef GL_RASTERIZER_DISCARD - #define GL_RASTERIZER_DISCARD 0x8C89 -#endif + // each instance type may have max 8 LODs ( if you change // this value, don't forget to change it in vertex shaders accordingly ) @@ -178,23 +180,20 @@ struct IndirectTarget IndirectTarget() : maxTargetQuantity(0) { - indirectCommands = new osg::BufferTemplate< std::vector >; + indirectCommands = new osg::DefaultIndirectCommandDrawArrays; } IndirectTarget( AggregateGeometryVisitor* agv, osg::Program* program ) : geometryAggregator(agv), drawProgram(program), maxTargetQuantity(0) { - indirectCommands = new osg::BufferTemplate< std::vector >; + indirectCommands = new osg::DefaultIndirectCommandDrawArrays; } void endRegister(unsigned int index, unsigned int rowsPerInstance, GLenum pixelFormat, GLenum type, GLint internalFormat, bool useMultiDrawArraysIndirect ) { - osg::Image* indirectCommandImage = new osg::Image; - indirectCommandImage->setImage( indirectCommands->getTotalDataSize()/sizeof(unsigned int), 1, 1, GL_R32I, GL_RED, GL_UNSIGNED_INT, (unsigned char*)indirectCommands->getDataPointer(), osg::Image::NO_DELETE ); + osg::VertexBufferObject * indirectCommandbuffer=new osg::VertexBufferObject(); + indirectCommandbuffer->setUsage(GL_DYNAMIC_DRAW); + indirectCommands->setBufferObject(indirectCommandbuffer); - osg::VertexBufferObject * indirectCommandImagebuffer=new osg::VertexBufferObject(); - indirectCommandImagebuffer->setUsage(GL_DYNAMIC_DRAW); - indirectCommandImage->setBufferObject(indirectCommandImagebuffer); - - indirectCommandTextureBuffer = new osg::TextureBuffer(indirectCommandImage); + indirectCommandTextureBuffer = new osg::TextureBuffer(indirectCommands); indirectCommandTextureBuffer->setInternalFormat( GL_R32I ); indirectCommandTextureBuffer->bindToImageUnit(index, osg::Texture::READ_WRITE); indirectCommandTextureBuffer->setUnRefImageDataAfterApply(false); @@ -203,28 +202,29 @@ struct IndirectTarget // add proper primitivesets to geometryAggregators if( !useMultiDrawArraysIndirect ) // use glDrawArraysIndirect() { - std::vector newPrimitiveSets; + std::vector newPrimitiveSets; - for(unsigned int j=0;jgetData().size(); ++j) - newPrimitiveSets.push_back( new DrawArraysIndirect( GL_TRIANGLES, j*sizeof( DrawArraysIndirectCommand ) ) ); + for(unsigned int j=0;jsize(); ++j){ + osg::DrawArraysIndirect *ipr=new osg::DrawArraysIndirect( GL_TRIANGLES, j ); + ipr->setIndirectCommandDrawArrays( indirectCommands); + newPrimitiveSets.push_back(ipr); + } geometryAggregator->getAggregatedGeometry()->removePrimitiveSet(0,geometryAggregator->getAggregatedGeometry()->getNumPrimitiveSets() ); - for(unsigned int j=0;jgetData().size(); ++j) + for(unsigned int j=0;jsize(); ++j) geometryAggregator->getAggregatedGeometry()->addPrimitiveSet( newPrimitiveSets[j] ); } else // use glMultiDrawArraysIndirect() { + osg::MultiDrawArraysIndirect *ipr=new osg::MultiDrawArraysIndirect( GL_TRIANGLES ); + ipr->setIndirectCommandDrawArrays( indirectCommands ); geometryAggregator->getAggregatedGeometry()->removePrimitiveSet(0,geometryAggregator->getAggregatedGeometry()->getNumPrimitiveSets() ); - geometryAggregator->getAggregatedGeometry()->addPrimitiveSet( new MultiDrawArraysIndirect( GL_TRIANGLES, 0, indirectCommands->getData().size(), 0 ) ); + geometryAggregator->getAggregatedGeometry()->addPrimitiveSet( ipr ); } - ///attach a DrawIndirect buffer binding to the stateset - osg::ref_ptr bb=new osg::DrawIndirectBufferBinding(); - bb->setBufferObject(indirectCommandImage->getBufferObject()); - geometryAggregator->getAggregatedGeometry()->getOrCreateStateSet()->setAttribute(bb ); geometryAggregator->getAggregatedGeometry()->setUseDisplayList(false); geometryAggregator->getAggregatedGeometry()->setUseVertexBufferObjects(true); @@ -268,7 +268,7 @@ struct IndirectTarget stateset->setAttributeAndModes( drawProgram.get(), osg::StateAttribute::ON ); } - osg::ref_ptr< osg::BufferTemplate< std::vector > > indirectCommands; + osg::ref_ptr< osg::DefaultIndirectCommandDrawArrays > indirectCommands; osg::ref_ptr indirectCommandTextureBuffer; osg::ref_ptr< AggregateGeometryVisitor > geometryAggregator; osg::ref_ptr drawProgram; @@ -318,7 +318,7 @@ struct GPUCullData // AggregateGeometryVisitor creates single osg::Geometry from all objects used by specific indirect target AggregateGeometryVisitor::AddObjectResult aoResult = target->second.geometryAggregator->addObject( node , typeID, lodNumber ); // Information about first vertex and a number of vertices is stored for later primitiveset creation - target->second.indirectCommands->getData().push_back( DrawArraysIndirectCommand( aoResult.first, aoResult.count ) ); + target->second.indirectCommands->push_back( osg::DrawArraysIndirectCommand( aoResult.count,1, aoResult.first ) ); osg::ComputeBoundsVisitor cbv; node->accept(cbv); @@ -360,10 +360,10 @@ struct GPUCullData std::map::iterator it,eit; for(it=targets.begin(), eit=targets.end(); it!=eit; ++it) { - for(unsigned j=0; jsecond.indirectCommands->getData().size(); ++j) + for(unsigned j=0; jsecond.indirectCommands->size(); ++j) { - DrawArraysIndirectCommand& iComm = it->second.indirectCommands->getData().at(j); - OSG_INFO<<"("<second.indirectCommands->at(j); + OSG_INFO<<"("<second.maxTargetQuantity * sizeof(osg::Vec4); OSG_INFO<<" => Maximum elements in target : "<< it->second.maxTargetQuantity <<" ( "<< sizeInBytes <<" bytes, " << sizeInBytes/1024<< " kB )" << std::endl; @@ -724,16 +724,16 @@ struct ResetTexturesCallback : public osg::StateSet::Callback std::vector::iterator it,eit; for(it=texUnitsDirty.begin(), eit=texUnitsDirty.end(); it!=eit; ++it) { - osg::Texture* tex = dynamic_cast( stateset->getTextureAttribute(*it,osg::StateAttribute::TEXTURE) ); + osg::TextureBuffer* tex = dynamic_cast( stateset->getTextureAttribute(*it,osg::StateAttribute::TEXTURE) ); if(tex==NULL) continue; - osg::Image* img = tex->getImage(0); + osg::BufferData* img =const_cast(tex->getBufferData()); if(img!=NULL) img->dirty(); } for(it=texUnitsDirtyParams.begin(), eit=texUnitsDirtyParams.end(); it!=eit; ++it) { - osg::Texture* tex = dynamic_cast( stateset->getTextureAttribute(*it,osg::StateAttribute::TEXTURE) ); + osg::TextureBuffer* tex = dynamic_cast( stateset->getTextureAttribute(*it,osg::StateAttribute::TEXTURE) ); if(tex!=NULL) tex->dirtyTextureParameters(); } diff --git a/include/osg/GLDefines b/include/osg/GLDefines index bebce6656..7efd433e4 100644 --- a/include/osg/GLDefines +++ b/include/osg/GLDefines @@ -435,6 +435,8 @@ typedef char GLchar; #define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D #define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E #define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 #endif // ARB_shader_atomic_counters @@ -556,14 +558,14 @@ typedef char GLchar; #define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 #endif -#define GL_INT64_ARB 0x140E -#define GL_UNSIGNED_INT64_ARB 0x140F -#define GL_INT64_VEC2_ARB 0x8FE9 -#define GL_INT64_VEC3_ARB 0x8FEA -#define GL_INT64_VEC4_ARB 0x8FEB -#define GL_UNSIGNED_INT64_VEC2_ARB 0x8FF5 -#define GL_UNSIGNED_INT64_VEC3_ARB 0x8FF6 -#define GL_UNSIGNED_INT64_VEC4_ARB 0x8FF7 +#define GL_INT64_ARB 0x140E +#define GL_UNSIGNED_INT64_ARB 0x140F +#define GL_INT64_VEC2_ARB 0x8FE9 +#define GL_INT64_VEC3_ARB 0x8FEA +#define GL_INT64_VEC4_ARB 0x8FEB +#define GL_UNSIGNED_INT64_VEC2_ARB 0x8FF5 +#define GL_UNSIGNED_INT64_VEC3_ARB 0x8FF6 +#define GL_UNSIGNED_INT64_VEC4_ARB 0x8FF7 /* ------------------------------ GL_KHR_debug ----------------------------- */ #ifndef GL_KHR_debug #define GL_KHR_debug 1 diff --git a/include/osg/PrimitiveSet b/include/osg/PrimitiveSet index aee28712b..0524de177 100644 --- a/include/osg/PrimitiveSet +++ b/include/osg/PrimitiveSet @@ -133,7 +133,15 @@ class OSG_EXPORT PrimitiveSet : public BufferData DrawElementsUBytePrimitiveType, DrawElementsUShortPrimitiveType, DrawElementsUIntPrimitiveType, - MultiDrawArraysPrimitiveType + MultiDrawArraysPrimitiveType, + DrawArraysIndirectPrimitiveType, + DrawElementsUByteIndirectPrimitiveType, + DrawElementsUShortIndirectPrimitiveType, + DrawElementsUIntIndirectPrimitiveType, + MultiDrawArraysIndirectPrimitiveType, + MultiDrawElementsUByteIndirectPrimitiveType, + MultiDrawElementsUShortIndirectPrimitiveType, + MultiDrawElementsUIntIndirectPrimitiveType }; enum Mode diff --git a/include/osg/PrimitiveSetIndirect b/include/osg/PrimitiveSetIndirect new file mode 100644 index 000000000..dcb608af7 --- /dev/null +++ b/include/osg/PrimitiveSetIndirect @@ -0,0 +1,697 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. + * + * osg/PrimitiveSetIndirect + * Author: Julien Valentin 2016-2017 +*/ + +#ifndef OSG_INDIRECTPRIMITIVESET +#define OSG_INDIRECTPRIMITIVESET 1 + +#include + + +namespace osg { +///common interface for IndirectCommandDrawArrayss +class OSG_EXPORT IndirectCommandDrawArrays: public BufferData +{ +public: + IndirectCommandDrawArrays():BufferData(){} + IndirectCommandDrawArrays(const IndirectCommandDrawArrays& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/) + :BufferData(copy, copyop){ } + + virtual unsigned int & count(const unsigned int&index)=0; + virtual unsigned int & instanceCount(const unsigned int&index)=0; + virtual unsigned int & first(const unsigned int&index)=0; + virtual unsigned int & baseInstance(const unsigned int&index)=0; + + virtual unsigned int getElementSize() const = 0; + virtual unsigned int getNumElements() const = 0; +}; +class OSG_EXPORT IndirectCommandDrawElements: public BufferData +{ +public: + IndirectCommandDrawElements():BufferData(){} + IndirectCommandDrawElements(const IndirectCommandDrawElements& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/) + :BufferData(copy, copyop){} + + virtual unsigned int & count(const unsigned int&index)=0; + virtual unsigned int & instanceCount(const unsigned int&index)=0; + virtual unsigned int & firstIndex(const unsigned int&index)=0; + virtual unsigned int & baseVertex(const unsigned int&index)=0; + virtual unsigned int & baseInstance(const unsigned int&index)=0; + + virtual unsigned int getElementSize()const = 0; + virtual unsigned int getNumElements() const = 0; + +}; + + + +/// DrawArraysCommand +struct DrawArraysIndirectCommand { + DrawArraysIndirectCommand(unsigned int pcount = 0, unsigned int pinstanceCount = 0, unsigned int pfirst = 0, unsigned int pbaseInstance = 0) + :count(pcount), instanceCount(pinstanceCount), first(pfirst), baseInstance(pbaseInstance){}; + unsigned int count; + unsigned int instanceCount; + unsigned int first; + unsigned int baseInstance; +}; + +/// default implementation of IndirectCommandDrawArrays +/// DefaultIndirectCommandDrawArrays to be hosted on GPU +class OSG_EXPORT DefaultIndirectCommandDrawArrays: public IndirectCommandDrawArrays, public MixinVector +{ +public: + META_Object(osg,DefaultIndirectCommandDrawArrays) + + DefaultIndirectCommandDrawArrays():IndirectCommandDrawArrays(), MixinVector() {} + DefaultIndirectCommandDrawArrays(const DefaultIndirectCommandDrawArrays& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/) + :IndirectCommandDrawArrays(copy, copyop),MixinVector() {} + + virtual const GLvoid* getDataPointer() const { + return empty()?0:&front(); + } + virtual unsigned int getTotalDataSize() const { + return 16u*static_cast(size()); + } + virtual unsigned int getElementSize()const {return 16u;}; + virtual unsigned int & count(const unsigned int&index){return at(index).count;} + virtual unsigned int & instanceCount(const unsigned int&index){return at(index).instanceCount;} + virtual unsigned int & first(const unsigned int&index){return at(index).first;} + virtual unsigned int & baseInstance(const unsigned int&index){return at(index).baseInstance;} + virtual unsigned int getNumElements() const {return static_cast(size());} +}; + + +/// default implementation of IndirectCommandDrawElements +/// DrawElementsCommand +struct DrawElementsIndirectCommand{ + DrawElementsIndirectCommand(unsigned int pcount = 0, unsigned int pinstanceCount = 0, unsigned int pfirstIndex = 0, unsigned int pbaseVertex = 0, unsigned int pbaseInstance = 0) + :count(pcount), instanceCount(pinstanceCount), firstIndex(pfirstIndex), baseVertex(pbaseVertex), baseInstance(pbaseInstance){}; + unsigned int count; + unsigned int instanceCount; + unsigned int firstIndex; + unsigned int baseVertex; + unsigned int baseInstance; +}; + +/// vector of DrawElementsCommand to be hosted on GPU +class OSG_EXPORT DefaultIndirectCommandDrawElements: public IndirectCommandDrawElements, public MixinVector +{ +public: + META_Object(osg,DefaultIndirectCommandDrawElements) + DefaultIndirectCommandDrawElements():IndirectCommandDrawElements(), MixinVector() {} + DefaultIndirectCommandDrawElements(const DefaultIndirectCommandDrawElements& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/) + :IndirectCommandDrawElements(copy, copyop), MixinVector(){} + virtual const GLvoid* getDataPointer() const { + return empty()?0:&front(); + } + virtual unsigned int getTotalDataSize() const { + return 20u*static_cast(size()); + } + + virtual unsigned int getElementSize()const {return 20u;}; + virtual unsigned int & count(const unsigned int&index){return at(index).count;} + virtual unsigned int & instanceCount(const unsigned int&index){return at(index).instanceCount;} + virtual unsigned int & firstIndex(const unsigned int&index){return at(index).firstIndex;} + virtual unsigned int & baseVertex(const unsigned int&index){return at(index).baseVertex;} + virtual unsigned int & baseInstance(const unsigned int&index){return at(index).baseInstance;} + virtual unsigned int getNumElements() const {return static_cast(size());} +}; + +/////////////////////////////////////////////////////////////////////////////////////// +/// \brief The DrawElementsIndirect base PrimitiveSet +/// +class OSG_EXPORT DrawElementsIndirect : public DrawElements +{ +public: + + DrawElementsIndirect(Type primType=PrimitiveType, GLenum mode = 0,unsigned int firstCommand = 0, GLsizei stride = 0): + DrawElements(primType,mode, 0),_firstCommand(firstCommand),_stride(stride){setIndirectCommandDrawArrays(new DefaultIndirectCommandDrawElements());} + + DrawElementsIndirect(const DrawElementsIndirect& rhs,const CopyOp& copyop=CopyOp::SHALLOW_COPY): + DrawElements(rhs,copyop),_firstCommand(rhs._firstCommand), _stride(rhs._stride) { + _IndirectCommandDrawArrays=(DefaultIndirectCommandDrawElements*)copyop(rhs._IndirectCommandDrawArrays.get()); + } + /// set command array of this indirect primitive set + inline void setIndirectCommandDrawArrays(IndirectCommandDrawElements*idc) { + _IndirectCommandDrawArrays = idc; + if(!_IndirectCommandDrawArrays->getBufferObject()) + _IndirectCommandDrawArrays->setBufferObject(new osg::VertexBufferObject()); + } + /// get command array of this indirect primitive set + inline IndirectCommandDrawElements* getIndirectCommandDrawArrays()const { + return _IndirectCommandDrawArrays; + } + ///Further methods are for advanced DI when you plan to use your own IndirectCommandElement (stride) + ///or if you want to draw a particular command index of the IndirectCommandElement(FirstCommandToDraw) + + /// set offset of the first command to draw in the IndirectCommandDrawArrays + inline void setFirstCommandToDraw( unsigned int i) { + _firstCommand=i; + } + /// get offset of the first command in the IndirectCommandDrawArrays + inline unsigned int getFirstCommandToDraw()const { + return _firstCommand; + } + /// stride (to set if you use custom CommandArray) + inline void setStride( GLsizei i) { + _stride=i; + } + /// stride (to set if you use custom CommandArray) + inline GLsizei getStride()const { + return _stride; + } + virtual unsigned int getNumPrimitives() const=0; + +protected: + virtual ~DrawElementsIndirect() {} + + unsigned int _firstCommand; + GLsizei _stride; + ref_ptr _IndirectCommandDrawArrays; + +}; +/////////////////////////////////////////////////////////////////////////////////////// +/// \brief The DrawElementsIndirectUByte PrimitiveSet +/// +class OSG_EXPORT DrawElementsIndirectUByte : public DrawElementsIndirect, public VectorGLubyte +{ +public: + + typedef VectorGLubyte vector_type; + + DrawElementsIndirectUByte(GLenum mode = 0,unsigned int firstCommand = 0, GLsizei stride = 0): + DrawElementsIndirect(DrawElementsUByteIndirectPrimitiveType,mode,firstCommand,stride) {} + + DrawElementsIndirectUByte(const DrawElementsIndirectUByte& array, const CopyOp& copyop=CopyOp::SHALLOW_COPY): + DrawElementsIndirect(array,copyop), + vector_type(array) {} + + /** + * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used. + * \param no Number of intended elements. This will be the size of the underlying vector. + * \param ptr Pointer to a GLubyte to copy index data from. + */ + DrawElementsIndirectUByte(GLenum mode, unsigned int no, const GLubyte* ptr) : + DrawElementsIndirect(MultiDrawElementsUByteIndirectPrimitiveType,mode), + vector_type(ptr,ptr+no) {} + + /** + * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used. + * \param no Number of intended elements. This will be the size of the underlying vector. + */ + DrawElementsIndirectUByte(GLenum mode, unsigned int no) : + DrawElementsIndirect(MultiDrawElementsUByteIndirectPrimitiveType,mode), + vector_type(no) {} + + virtual Object* cloneType() const { + return new DrawElementsIndirectUByte(); + } + virtual Object* clone(const CopyOp& copyop) const { + return new DrawElementsIndirectUByte(*this,copyop); + } + virtual bool isSameKindAs(const Object* obj) const { + return dynamic_cast(obj)!=NULL; + } + virtual const char* libraryName() const { + return "osg"; + } + virtual const char* className() const { + return "DrawElementsIndirectUByte"; + } + + virtual const GLvoid* getDataPointer() const { + return empty()?0:&front(); + } + virtual unsigned int getTotalDataSize() const { + return static_cast(size()); + } + virtual bool supportsBufferObject() const { + return false; + } + + virtual void draw(State& state, bool useVertexBufferObjects) const; + + virtual void accept(PrimitiveFunctor& functor) const; + virtual void accept(PrimitiveIndexFunctor& functor) const; + + virtual unsigned int getNumIndices() const { + return static_cast(size()); + } + virtual unsigned int index(unsigned int pos) const { + return (*this)[pos]; + } + virtual void offsetIndices(int offset); + + virtual GLenum getDataType() { + return GL_UNSIGNED_BYTE; + } + virtual void resizeElements(unsigned int numIndices) { + resize(numIndices); + } + virtual void reserveElements(unsigned int numIndices) { + reserve(numIndices); + } + virtual void setElement(unsigned int i, unsigned int v) { + (*this)[i] = v; + } + virtual unsigned int getElement(unsigned int i) { + return (*this)[i]; + } + virtual void addElement(unsigned int v) { + push_back(GLubyte(v)); + } + virtual unsigned int getNumPrimitives() const; +protected: + + virtual ~DrawElementsIndirectUByte(); +}; + + +/////////////////////////////////////////////////////////////////////////////////////// +/// \brief The DrawElementsIndirectUShort PrimitiveSet +/// +class OSG_EXPORT DrawElementsIndirectUShort : public DrawElementsIndirect, public VectorGLushort +{ +public: + + typedef VectorGLushort vector_type; + + DrawElementsIndirectUShort(GLenum mode = 0,unsigned int firstCommand = 0, GLsizei stride = 0): + DrawElementsIndirect(DrawElementsUShortIndirectPrimitiveType,mode,firstCommand,stride) {} + + DrawElementsIndirectUShort(const DrawElementsIndirectUShort& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY): + DrawElementsIndirect(array,copyop), + vector_type(array) {} + + /** + * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used. + * \param no Number of intended elements. This will be the size of the underlying vector. + * \param ptr Pointer to a GLushort to copy index data from. + */ + DrawElementsIndirectUShort(GLenum mode, unsigned int no, const GLushort* ptr) : + DrawElementsIndirect(MultiDrawElementsUShortIndirectPrimitiveType,mode), + vector_type(ptr,ptr+no) {} + + /** + * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used. + * \param no Number of intended elements. This will be the size of the underlying vector. + */ + DrawElementsIndirectUShort(GLenum mode, unsigned int no) : + DrawElementsIndirect(MultiDrawElementsUShortIndirectPrimitiveType,mode), + vector_type(no) {} + + template + DrawElementsIndirectUShort(GLenum mode, InputIterator first,InputIterator last) : + DrawElementsIndirect(MultiDrawElementsUShortIndirectPrimitiveType,mode), + vector_type(first,last) {} + + virtual Object* cloneType() const { + return new DrawElementsIndirectUShort(); + } + virtual Object* clone(const CopyOp& copyop) const { + return new DrawElementsIndirectUShort(*this,copyop); + } + virtual bool isSameKindAs(const Object* obj) const { + return dynamic_cast(obj)!=NULL; + } + virtual const char* libraryName() const { + return "osg"; + } + virtual const char* className() const { + return "DrawElementsIndirectUShort"; + } + + virtual const GLvoid* getDataPointer() const { + return empty()?0:&front(); + } + virtual unsigned int getTotalDataSize() const { + return 2u*static_cast(size()); + } + virtual bool supportsBufferObject() const { + return false; + } + + virtual void draw(State& state, bool useVertexBufferObjects) const; + + virtual void accept(PrimitiveFunctor& functor) const; + virtual void accept(PrimitiveIndexFunctor& functor) const; + + virtual unsigned int getNumIndices() const { + return static_cast(size()); + } + virtual unsigned int index(unsigned int pos) const { + return (*this)[pos]; + } + virtual void offsetIndices(int offset); + + virtual GLenum getDataType() { + return GL_UNSIGNED_SHORT; + } + virtual void resizeElements(unsigned int numIndices) { + resize(numIndices); + } + virtual void reserveElements(unsigned int numIndices) { + reserve(numIndices); + } + virtual void setElement(unsigned int i, unsigned int v) { + (*this)[i] = v; + } + virtual unsigned int getElement(unsigned int i) { + return (*this)[i]; + } + virtual void addElement(unsigned int v) { + push_back(GLushort(v)); + } + virtual unsigned int getNumPrimitives() const; +protected: + + virtual ~DrawElementsIndirectUShort(); +}; + +/////////////////////////////////////////////////////////////////////////////////////// +/// \brief The DrawElementsIndirectUInt PrimitiveSet +/// +class OSG_EXPORT DrawElementsIndirectUInt : public DrawElementsIndirect, public VectorGLuint +{ +public: + + typedef VectorGLuint vector_type; + + DrawElementsIndirectUInt(GLenum mode = 0,unsigned int firstCommand = 0, GLsizei stride = 0): + DrawElementsIndirect(DrawElementsUIntIndirectPrimitiveType,mode,firstCommand,stride) {} + + DrawElementsIndirectUInt(const DrawElementsIndirectUInt& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY): + DrawElementsIndirect(array,copyop), + vector_type(array) {} + + /** + * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used. + * \param no Number of intended elements. This will be the size of the underlying vector. + * \param ptr Pointer to a GLunsigned int to copy index data from. + */ + DrawElementsIndirectUInt(GLenum mode, unsigned int no, const GLuint* ptr) : + DrawElementsIndirect(DrawElementsUIntIndirectPrimitiveType,mode), + vector_type(ptr,ptr+no) {} + + /** + * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used. + * \param no Number of intended elements. This will be the size of the underlying vector. + */ + DrawElementsIndirectUInt(GLenum mode, unsigned int no) : + DrawElementsIndirect(MultiDrawElementsUIntIndirectPrimitiveType,mode), + vector_type(no) {} + + template + DrawElementsIndirectUInt(GLenum mode, InputIterator first,InputIterator last) : + DrawElementsIndirect(MultiDrawElementsUIntIndirectPrimitiveType,mode), + vector_type(first,last) {} + + virtual Object* cloneType() const { + return new DrawElementsIndirectUInt(); + } + virtual Object* clone(const CopyOp& copyop) const { + return new DrawElementsIndirectUInt(*this,copyop); + } + virtual bool isSameKindAs(const Object* obj) const { + return dynamic_cast(obj)!=NULL; + } + virtual const char* libraryName() const { + return "osg"; + } + virtual const char* className() const { + return "DrawElementsIndirectUInt"; + } + + virtual const GLvoid* getDataPointer() const { + return empty()?0:&front(); + } + virtual unsigned int getTotalDataSize() const { + return 4u*static_cast(size()); + } + virtual bool supportsBufferObject() const { + return false; + } + + virtual void draw(State& state, bool useVertexBufferObjects) const; + + virtual void accept(PrimitiveFunctor& functor) const; + virtual void accept(PrimitiveIndexFunctor& functor) const; + + virtual unsigned int getNumIndices() const { + return static_cast(size()); + } + virtual unsigned int index(unsigned int pos) const { + return (*this)[pos]; + } + virtual void offsetIndices(int offset); + + virtual GLenum getDataType() { + return GL_UNSIGNED_INT; + } + virtual void resizeElements(unsigned int numIndices) { + resize(numIndices); + } + virtual void reserveElements(unsigned int numIndices) { + reserve(numIndices); + } + virtual void setElement(unsigned int i, unsigned int v) { + (*this)[i] = v; + } + virtual unsigned int getElement(unsigned int i) { + return (*this)[i]; + } + virtual void addElement(unsigned int v) { + push_back(GLuint(v)); + } + + virtual unsigned int getNumPrimitives() const; +protected: + + virtual ~DrawElementsIndirectUInt(); +}; +/////////////////////////////////////////////////////////////////////////////////////// +/// \brief The MultiDrawElementsIndirect PrimitiveSets +/// +class OSG_EXPORT MultiDrawElementsIndirectUShort : public DrawElementsIndirectUShort +{ +public: + MultiDrawElementsIndirectUShort(GLenum mode = 0,unsigned int firstCommand = 0,unsigned int commandcount = 0, GLsizei stride = 0): + DrawElementsIndirectUShort(mode,firstCommand,stride),_count(commandcount){_primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType));} + MultiDrawElementsIndirectUShort(const MultiDrawElementsIndirectUShort& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY): + DrawElementsIndirectUShort(mdi,copyop),_count(mdi._count) {} + + virtual void draw(State& state, bool useVertexBufferObjects) const; + virtual void accept(PrimitiveFunctor& functor) const; + virtual void accept(PrimitiveIndexFunctor& functor) const; + virtual unsigned int getNumPrimitives() const; + + ///if you want to draw a subset of the IndirectCommandElement(FirstCommandToDraw,NumCommandsToDraw) + + /// count of Indirect Command to execute + inline void setNumCommandsToDraw( unsigned int i) { + _count=i; + } + /// count of Indirect Command to execute + inline unsigned int getNumCommandsToDraw()const { + return _count; + } +protected: + unsigned int _count; + virtual ~MultiDrawElementsIndirectUShort(); +}; + +class OSG_EXPORT MultiDrawElementsIndirectUByte : public DrawElementsIndirectUByte +{ +public: + MultiDrawElementsIndirectUByte(GLenum mode = 0,unsigned int firstCommand = 0,unsigned int commandcount = 0, GLsizei stride = 0): + DrawElementsIndirectUByte(mode,firstCommand,stride),_count(commandcount){_primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType));} + MultiDrawElementsIndirectUByte(const MultiDrawElementsIndirectUByte& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY): + DrawElementsIndirectUByte(mdi,copyop),_count(mdi._count) {} + virtual void draw(State& state, bool useVertexBufferObjects) const; + virtual void accept(PrimitiveFunctor& functor) const; + virtual void accept(PrimitiveIndexFunctor& functor) const; + virtual unsigned int getNumPrimitives() const; + /// count of Indirect Command to execute + inline void setNumCommandsToDraw( unsigned int i) { + _count=i; + } + /// count of Indirect Command to execute + inline unsigned int getNumCommandsToDraw()const { + return _count; + } +protected: + unsigned int _count; + virtual ~MultiDrawElementsIndirectUByte(); +}; +class OSG_EXPORT MultiDrawElementsIndirectUInt : public DrawElementsIndirectUInt +{ +public: + MultiDrawElementsIndirectUInt(GLenum mode = 0,unsigned int firstCommand = 0,unsigned int commandcount = 0, GLsizei stride = 0): + DrawElementsIndirectUInt(mode,firstCommand,stride),_count(commandcount){_primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType));} + MultiDrawElementsIndirectUInt(const MultiDrawElementsIndirectUInt& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY): + DrawElementsIndirectUInt(mdi,copyop),_count(mdi._count) {} + + virtual void draw(State& state, bool useVertexBufferObjects) const; + virtual void accept(PrimitiveFunctor& functor) const; + virtual void accept(PrimitiveIndexFunctor& functor) const; + virtual unsigned int getNumPrimitives() const; + /// count of Indirect Command to execute + inline void setNumCommandsToDraw( unsigned int i) { + _count=i; + } + /// count of Indirect Command to execute + inline unsigned int getNumCommandsToDraw()const { + return _count; + } +protected: + unsigned int _count; + virtual ~MultiDrawElementsIndirectUInt(); +}; +/////////////////////////////////////////////////////////////////////////////////////// +/// \brief The MultiDrawArraysIndirect PrimitiveSet +/// +class OSG_EXPORT DrawArraysIndirect : public osg::PrimitiveSet +{ +public: + + DrawArraysIndirect(GLenum mode=0, unsigned int firstcommand = 0, GLsizei stride = 0): + osg::PrimitiveSet(Type(DrawArraysIndirectPrimitiveType), mode), + _firstCommand(firstcommand), _stride(stride) {setIndirectCommandDrawArrays(new DefaultIndirectCommandDrawArrays);} + + DrawArraysIndirect(const DrawArraysIndirect& dal,const CopyOp& copyop=CopyOp::SHALLOW_COPY): + osg::PrimitiveSet(dal,copyop), + _firstCommand(dal._firstCommand), + _stride(dal._stride), + _IndirectCommandDrawArrays((DefaultIndirectCommandDrawArrays*)copyop( dal._IndirectCommandDrawArrays.get())) + {} + + virtual osg::Object* cloneType() const { + return new DrawArraysIndirect(); + } + virtual osg::Object* clone(const osg::CopyOp& copyop) const { + return new DrawArraysIndirect(*this,copyop); + } + virtual bool isSameKindAs(const osg::Object* obj) const { + return dynamic_cast(obj)!=NULL; + } + virtual const char* libraryName() const { + return "osg"; + } + virtual const char* className() const { + return "DrawArraysIndirect"; + } + + virtual void draw(State& state, bool useVertexBufferObjects) const; + + virtual void accept(PrimitiveFunctor& functor) const; + virtual void accept(PrimitiveIndexFunctor& functor) const; + + virtual unsigned int getNumIndices() const; + virtual unsigned int index(unsigned int pos) const; + virtual void offsetIndices(int offset); + + virtual unsigned int getNumPrimitives() const; + + /// stride (to set if you use custom CommandArray) + inline void setStride( GLsizei i) { + _stride=i; + } + /// stride (to set if you use custom CommandArray) + inline GLsizei getStride()const { + return _stride; + } + /// set offset of the first command in the IndirectCommandDrawArrays + inline void setFirstCommand( unsigned int i) { + _firstCommand=i; + } + /// get offset of the first command in the IndirectCommandDrawArrays + inline unsigned int getFirstCommand()const { + return _firstCommand; + } + + inline void setIndirectCommandDrawArrays(IndirectCommandDrawArrays*idc) { + _IndirectCommandDrawArrays = idc; + if(!_IndirectCommandDrawArrays->getBufferObject()) + _IndirectCommandDrawArrays->setBufferObject(new osg::VertexBufferObject()); + } + inline IndirectCommandDrawArrays* getIndirectCommandDrawArrays()const { + return _IndirectCommandDrawArrays; + } + +protected: + + unsigned int _firstCommand; + GLsizei _stride; + ref_ptr _IndirectCommandDrawArrays; + +}; + +/////////////////////////////////////////////////////////////////////////////////////// +/// \brief The MultiDrawArraysIndirect PrimitiveSet +/// +class OSG_EXPORT MultiDrawArraysIndirect : public DrawArraysIndirect +{ +public: + + MultiDrawArraysIndirect(GLenum mode=0, unsigned int firstcommand = 0, unsigned int count = 0, GLsizei stride = 0): + osg::DrawArraysIndirect(mode, firstcommand, stride), _count(count) + {_primitiveType=Type(MultiDrawArraysIndirectPrimitiveType);} + + MultiDrawArraysIndirect(const MultiDrawArraysIndirect& dal,const CopyOp& copyop=CopyOp::SHALLOW_COPY): + osg::DrawArraysIndirect(dal,copyop), _count(dal._count) + {} + + virtual osg::Object* cloneType() const { + return new MultiDrawArraysIndirect(); + } + virtual osg::Object* clone(const osg::CopyOp& copyop) const { + return new MultiDrawArraysIndirect(*this,copyop); + } + virtual bool isSameKindAs(const osg::Object* obj) const { + return dynamic_cast(obj)!=NULL; + } + + virtual const char* className() const { + return "MultiDrawArraysIndirect"; + } + + virtual void draw(State& state, bool useVertexBufferObjects) const; + + virtual void accept(PrimitiveFunctor& functor) const; + virtual void accept(PrimitiveIndexFunctor& functor) const; + + virtual unsigned int getNumIndices() const; + virtual unsigned int index(unsigned int pos) const; + virtual void offsetIndices(int offset); + + virtual unsigned int getNumPrimitives() const; + + /// count of Indirect Command to execute + inline void setNumCommandsToDraw( unsigned int i) { + _count=i; + } + /// count of Indirect Command to execute + inline unsigned int getNumCommandsToDraw()const { + return _count; + } +protected: + unsigned int _count; + +}; + +} + +#endif + diff --git a/src/osg/CMakeLists.txt b/src/osg/CMakeLists.txt index aa1561869..845306551 100644 --- a/src/osg/CMakeLists.txt +++ b/src/osg/CMakeLists.txt @@ -136,6 +136,7 @@ SET(TARGET_H ${HEADER_PATH}/Polytope ${HEADER_PATH}/PositionAttitudeTransform ${HEADER_PATH}/PrimitiveSet + ${HEADER_PATH}/PrimitiveSetIndirect ${HEADER_PATH}/PrimitiveRestartIndex ${HEADER_PATH}/Program ${HEADER_PATH}/Projection @@ -342,6 +343,7 @@ SET(TARGET_SRC Polytope.cpp PositionAttitudeTransform.cpp PrimitiveSet.cpp + PrimitiveSetIndirect.cpp PrimitiveRestartIndex.cpp Program.cpp Projection.cpp diff --git a/src/osg/PrimitiveSetIndirect.cpp b/src/osg/PrimitiveSetIndirect.cpp new file mode 100644 index 000000000..d3b10e585 --- /dev/null +++ b/src/osg/PrimitiveSetIndirect.cpp @@ -0,0 +1,585 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. + * + * osg/PrimitiveSetIndirect.cpp + * Author: Julien Valentin 2016-2017 +*/ + +#include +#include +#include +#include +#include + +using namespace osg; +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// DrawElementsIndirect +// +template inline +unsigned int getNumPrimitivesDI( const T&_this) +{ + unsigned int offset= _this.getFirstCommandToDraw(); + IndirectCommandDrawElements *cmd=_this.getIndirectCommandDrawArrays(); + unsigned int total=0; + switch(_this.getMode()) + { + case(PrimitiveSet::POINTS): + return cmd->count(offset); + case(PrimitiveSet::LINES): + return cmd->count(offset)/2; + case(PrimitiveSet::TRIANGLES): + return cmd->count(offset)/3; + case(PrimitiveSet::QUADS): + return cmd->count(offset)/4; + case(PrimitiveSet::LINE_STRIP): + case(PrimitiveSet::LINE_LOOP): + case(PrimitiveSet::TRIANGLE_STRIP): + case(PrimitiveSet::TRIANGLE_FAN): + case(PrimitiveSet::QUAD_STRIP): + case(PrimitiveSet::PATCHES): + case(PrimitiveSet::POLYGON): + { + return 1; + } + } + return total; +} + +unsigned int DrawElementsIndirectUInt::getNumPrimitives() const{return getNumPrimitivesDI(*this);} +unsigned int DrawElementsIndirectUByte::getNumPrimitives() const{return getNumPrimitivesDI(*this);} +unsigned int DrawElementsIndirectUShort::getNumPrimitives() const{return getNumPrimitivesDI(*this);} + +void DrawElementsIndirectUInt::draw(State& state, bool useVertexBufferObjects) const +{ GLBufferObject* dibo = _IndirectCommandDrawArrays->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); + state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); + + GLenum mode = _mode; +#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) + if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN; + if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP; +#endif + + GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID()); + + assert (useVertexBufferObjects && ebo); + + state.bindElementBufferObject(ebo); + + state.get()-> glDrawElementsIndirect(mode, GL_UNSIGNED_INT, + (const GLvoid *)(dibo->getOffset(_IndirectCommandDrawArrays->getBufferIndex()) //command array adress + +_firstCommand* _IndirectCommandDrawArrays->getElementSize())// runtime offset computaion can be sizeof(*_IndirectCommandDrawArrays->begin()) + ); + +} + +DrawElementsIndirectUInt::~DrawElementsIndirectUInt() +{ + releaseGLObjects(); +} +void DrawElementsIndirectUInt::offsetIndices(int offset) +{ + for(iterator itr=begin(); + itr!=end(); + ++itr) + { + *itr += offset; + } +} +void DrawElementsIndirectUInt::accept(PrimitiveFunctor& functor) const +{ + /* if (!empty() && cmd) + functor.drawElements(_mode,_IndirectCommandDrawArrays->count(_firstCommand), + &(*this)[_IndirectCommandDrawArrays->firstIndex(_firstCommand)] + _IndirectCommandDrawArrays->baseVertex(_firstCommand)); + */ +} + +void DrawElementsIndirectUInt::accept(PrimitiveIndexFunctor& functor) const +{ +/* if (!empty() && cmd) + functor.drawElements(_mode,_IndirectCommandDrawArrays->count(_firstCommand), + &(*this)[_IndirectCommandDrawArrays->firstIndex(_firstCommand)] + _IndirectCommandDrawArrays->baseVertex(_firstCommand)); + */ + +} +void DrawElementsIndirectUByte::draw(State& state, bool useVertexBufferObjects) const +{ GLBufferObject* dibo = _IndirectCommandDrawArrays->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); + state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); + + GLenum mode = _mode; +#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) + if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN; + if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP; +#endif + + GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID()); + + assert (useVertexBufferObjects && ebo); + + state.bindElementBufferObject(ebo); + + state.get()-> glDrawElementsIndirect(mode, GL_UNSIGNED_BYTE, (const GLvoid *)(dibo->getOffset(_IndirectCommandDrawArrays->getBufferIndex()) + +_firstCommand* _IndirectCommandDrawArrays->getElementSize())); + +} +DrawElementsIndirectUByte::~DrawElementsIndirectUByte() +{ + releaseGLObjects(); +} +void DrawElementsIndirectUByte::offsetIndices(int offset) +{ + for(iterator itr=begin(); + itr!=end(); + ++itr) + { + *itr += offset; + } +} +void DrawElementsIndirectUByte::accept(PrimitiveFunctor& functor) const +{ +/* if (!empty() && cmd) + functor.drawElements(_mode,_IndirectCommandDrawArrays->count(_firstCommand), + &(*this)[_IndirectCommandDrawArrays->firstIndex(_firstCommand)] + _IndirectCommandDrawArrays->baseVertex(_firstCommand)); + */ +} + +void DrawElementsIndirectUByte::accept(PrimitiveIndexFunctor& functor) const +{ +/* if (!empty() && cmd) + functor.drawElements(_mode,_IndirectCommandDrawArrays->count(_firstCommand), + &(*this)[_IndirectCommandDrawArrays->firstIndex(_firstCommand)] + _IndirectCommandDrawArrays->baseVertex(_firstCommand)); + */ + +} +void DrawElementsIndirectUShort::draw(State& state, bool useVertexBufferObjects) const +{ GLBufferObject* dibo = _IndirectCommandDrawArrays->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); + state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); + + GLenum mode = _mode; +#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) + if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN; + if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP; +#endif + + GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID()); + + assert (useVertexBufferObjects && ebo); + + state.bindElementBufferObject(ebo); + + state.get()-> glDrawElementsIndirect(mode, GL_UNSIGNED_SHORT, (const GLvoid *)(dibo->getOffset(_IndirectCommandDrawArrays->getBufferIndex()) + +_firstCommand* _IndirectCommandDrawArrays->getElementSize())); + +} +DrawElementsIndirectUShort::~DrawElementsIndirectUShort() +{ + releaseGLObjects(); +} +void DrawElementsIndirectUShort::offsetIndices(int offset) +{ + for(iterator itr=begin(); + itr!=end(); + ++itr) + { + *itr += offset; + } +} +void DrawElementsIndirectUShort::accept(PrimitiveFunctor& functor) const +{ +/* if (!empty() && cmd) + functor.drawElements(_mode,_IndirectCommandDrawArrays->count(_firstCommand), + &(*this)[_IndirectCommandDrawArrays->firstIndex(_firstCommand)] + _IndirectCommandDrawArrays->baseVertex(_firstCommand)); + */ +} + +void DrawElementsIndirectUShort::accept(PrimitiveIndexFunctor& functor) const +{ +/* if (!empty() && cmd) + functor.drawElements(_mode,_IndirectCommandDrawArrays->count(_firstCommand), + &(*this)[_IndirectCommandDrawArrays->firstIndex(_firstCommand)] + _IndirectCommandDrawArrays->baseVertex(_firstCommand)); + */ + +} +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// MultiDrawElementsIndirect +// +template inline +unsigned int getNumPrimitivesMDI( const T&_this) +{ IndirectCommandDrawElements *_IndirectCommandDrawArrays=_this.getIndirectCommandDrawArrays(); + unsigned int total=0; + switch(_this.getMode()) + { + case(PrimitiveSet::POINTS): + for(unsigned int i=0;i<_IndirectCommandDrawArrays->getNumElements();i++) + total+=_IndirectCommandDrawArrays->count(i); + case(PrimitiveSet::LINES): + for(unsigned int i=0;i<_IndirectCommandDrawArrays->getNumElements();i++) + total+=_IndirectCommandDrawArrays->count(i)/2; + case(PrimitiveSet::TRIANGLES): + for(unsigned int i=0;i<_IndirectCommandDrawArrays->getNumElements();i++) + total+=_IndirectCommandDrawArrays->count(i)/3; + case(PrimitiveSet::QUADS): + for(unsigned int i=0;i<_IndirectCommandDrawArrays->getNumElements();i++) + total+=_IndirectCommandDrawArrays->count(i)/4; + case(PrimitiveSet::LINE_STRIP): + case(PrimitiveSet::LINE_LOOP): + case(PrimitiveSet::TRIANGLE_STRIP): + case(PrimitiveSet::TRIANGLE_FAN): + case(PrimitiveSet::QUAD_STRIP): + case(PrimitiveSet::PATCHES): + case(PrimitiveSet::POLYGON): + { + unsigned int primcount = _IndirectCommandDrawArrays->getNumElements(); + return primcount; + } + } + return total; +} + +unsigned int MultiDrawElementsIndirectUInt::getNumPrimitives() const{return getNumPrimitivesMDI(*this);} +unsigned int MultiDrawElementsIndirectUByte::getNumPrimitives() const{return getNumPrimitivesMDI(*this);} +unsigned int MultiDrawElementsIndirectUShort::getNumPrimitives() const{return getNumPrimitivesMDI(*this);} + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// MultiDrawElementsIndirectUByte +// +MultiDrawElementsIndirectUByte::~MultiDrawElementsIndirectUByte() +{ + releaseGLObjects(); +} +void MultiDrawElementsIndirectUByte::draw(State& state, bool useVertexBufferObjects) const +{ + GLBufferObject* dibo = _IndirectCommandDrawArrays->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); + + state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); + GLenum mode = _mode; +#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) + if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN; + if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP; +#endif + + + GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID()); + + assert (useVertexBufferObjects && ebo); + + state.bindElementBufferObject(ebo); + + state.get()-> glMultiDrawElementsIndirect(mode, GL_UNSIGNED_BYTE, (const GLvoid *)(dibo->getOffset(_IndirectCommandDrawArrays->getBufferIndex())),_IndirectCommandDrawArrays->getNumElements(), _stride); + +} + +void MultiDrawElementsIndirectUByte::accept(PrimitiveFunctor& functor) const +{ + /* if (!empty() ) + unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; + for(unsigned int i=_firstCommand; icount(i), + &(*this)[_IndirectCommandDrawArrays->firstIndex(i)], + _IndirectCommandDrawArrays->baseVertex(i)); + */ +} + +void MultiDrawElementsIndirectUByte::accept(PrimitiveIndexFunctor& functor) const +{ + /* if (!empty() ) + unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; + for(unsigned int i=_firstCommand; icount(i), + &(*this)[_IndirectCommandDrawArrays->firstIndex(i)], + _IndirectCommandDrawArrays->baseVertex(i)); + */ +} + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// MultiDrawElementsIndirectUShort +// +MultiDrawElementsIndirectUShort::~MultiDrawElementsIndirectUShort() +{ + releaseGLObjects(); +} + +void MultiDrawElementsIndirectUShort::draw(State& state, bool useVertexBufferObjects) const +{ GLBufferObject* dibo = _IndirectCommandDrawArrays->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); + state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); + + GLenum mode = _mode; +#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) + if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN; + if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP; +#endif + + GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID()); + + assert (useVertexBufferObjects && ebo); + + state.bindElementBufferObject(ebo); + + state.get()-> glMultiDrawElementsIndirect(mode, GL_UNSIGNED_SHORT, (const GLvoid *)(dibo->getOffset(_IndirectCommandDrawArrays->getBufferIndex())), + _count>0?_count:_IndirectCommandDrawArrays->getNumElements(),_stride); + +} + +void MultiDrawElementsIndirectUShort::accept(PrimitiveFunctor& functor) const +{ + /* if (!empty() ) + unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; + for(unsigned int i=_firstCommand; icount(i), + &(*this)[_IndirectCommandDrawArrays->firstIndex(i)], + _IndirectCommandDrawArrays->baseVertex(i)); + */ +} + +void MultiDrawElementsIndirectUShort::accept(PrimitiveIndexFunctor& functor) const +{ + /* if (!empty() ) + unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; + for(unsigned int i=_firstCommand; icount(i), + &(*this)[_IndirectCommandDrawArrays->firstIndex(i)], + _IndirectCommandDrawArrays->baseVertex(i)); + */ +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// MultiDrawElementsIndirectUInt +// +MultiDrawElementsIndirectUInt::~MultiDrawElementsIndirectUInt() +{ + releaseGLObjects(); +} + +void MultiDrawElementsIndirectUInt::draw(State& state, bool useVertexBufferObjects) const +{ + GLBufferObject* dibo = _IndirectCommandDrawArrays->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); + state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); + GLenum mode = _mode; +#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) + if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN; + if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP; +#endif + + + GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID()); + + assert (useVertexBufferObjects && ebo); + + state.bindElementBufferObject(ebo); + + state.get()-> glMultiDrawElementsIndirect(mode, GL_UNSIGNED_INT, (const GLvoid *)(dibo->getOffset(_IndirectCommandDrawArrays->getBufferIndex())), + _count>0?_count:_IndirectCommandDrawArrays->getNumElements(), _stride); + +} + +void MultiDrawElementsIndirectUInt::accept(PrimitiveFunctor& functor) const +{ + /* if (!empty() ) + unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; + for(unsigned int i=_firstCommand; icount(i), + &(*this)[_IndirectCommandDrawArrays->firstIndex(i)], + _IndirectCommandDrawArrays->baseVertex(i)); + */ +} + +void MultiDrawElementsIndirectUInt::accept(PrimitiveIndexFunctor& functor) const +{ + /* if (!empty() ) + unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; + for(unsigned int i=_firstCommand; icount(i), + &(*this)[_IndirectCommandDrawArrays->firstIndex(i)], + _IndirectCommandDrawArrays->baseVertex(i)); + */ + +} + + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// MultiDrawArrays +// +void DrawArraysIndirect::draw(osg::State& state, bool) const +{ + GLBufferObject* dibo = _IndirectCommandDrawArrays->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); + state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); + + GLExtensions* ext = state.get(); + + ext->glDrawArraysIndirect(_mode, (const GLvoid *)(dibo->getOffset(_IndirectCommandDrawArrays->getBufferIndex()) + +_firstCommand* _IndirectCommandDrawArrays->getElementSize())); + +} + +void DrawArraysIndirect::accept(PrimitiveFunctor& functor) const +{ + functor.drawArrays(_mode, _IndirectCommandDrawArrays->first(_firstCommand), _IndirectCommandDrawArrays->count(_firstCommand)); +} + +void DrawArraysIndirect::accept(PrimitiveIndexFunctor& functor) const +{ + functor.drawArrays(_mode, _IndirectCommandDrawArrays->first(_firstCommand), _IndirectCommandDrawArrays->count(_firstCommand)); +} + +unsigned int DrawArraysIndirect::getNumIndices() const +{ + return _IndirectCommandDrawArrays->count(_firstCommand); +} + +unsigned int DrawArraysIndirect::index(unsigned int pos) const +{ + return _IndirectCommandDrawArrays->first(_firstCommand)+ pos; +} + +void DrawArraysIndirect::offsetIndices(int offset) +{ + _IndirectCommandDrawArrays->first(_firstCommand)+= offset; +} + +unsigned int DrawArraysIndirect::getNumPrimitives() const +{ + switch(_mode) + { + case(POINTS): + return _IndirectCommandDrawArrays->count(_firstCommand); + case(LINES): + return _IndirectCommandDrawArrays->count(_firstCommand)/2; + case(TRIANGLES): + return _IndirectCommandDrawArrays->count(_firstCommand)/3; + case(QUADS): + return _IndirectCommandDrawArrays->count(_firstCommand)/4; + case(LINE_STRIP): + case(LINE_LOOP): + case(TRIANGLE_STRIP): + case(TRIANGLE_FAN): + case(QUAD_STRIP): + case(PATCHES): + case(POLYGON): + { + return 1; + } + } + return 0; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// MultiDrawArrays +// +void MultiDrawArraysIndirect::draw(osg::State& state, bool) const +{ + GLBufferObject* dibo = _IndirectCommandDrawArrays->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); + state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); + + GLExtensions* ext = state.get(); + + ext->glMultiDrawArraysIndirect(_mode, (const GLvoid *)(dibo->getOffset(_IndirectCommandDrawArrays->getBufferIndex())+_firstCommand*_IndirectCommandDrawArrays->getElementSize()), + _count>0?_count:_IndirectCommandDrawArrays->getNumElements(), _stride); + +} + +void MultiDrawArraysIndirect::accept(PrimitiveFunctor& functor) const +{ + unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; + for(unsigned int i=_firstCommand; ifirst(i), _IndirectCommandDrawArrays->count(i)); + } +} + +void MultiDrawArraysIndirect::accept(PrimitiveIndexFunctor& functor) const +{ + unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; + for(unsigned int i=_firstCommand; ifirst(i), _IndirectCommandDrawArrays->count(i)); + } +} + +unsigned int MultiDrawArraysIndirect::getNumIndices() const +{ + unsigned int total=0; + + unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; + for(unsigned int i=_firstCommand; icount(i); + return total; +} + +unsigned int MultiDrawArraysIndirect::index(unsigned int pos) const +{ + /* unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; + for(unsigned int i=_firstCommand; icount(i); + if (posfirst(maxindex-1) + pos;*/ + return pos;//??? + +} + +void MultiDrawArraysIndirect::offsetIndices(int offset) +{ + unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; + for(unsigned int i=_firstCommand; ifirst(i) += offset; +} + +unsigned int MultiDrawArraysIndirect::getNumPrimitives() const +{ + unsigned int total=0;unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; + + switch(_mode) + { + case(POINTS): + for(unsigned int i=_firstCommand; icount(i); + case(LINES): + for(unsigned int i=_firstCommand; icount(i)/2; + case(TRIANGLES): + for(unsigned int i=_firstCommand; icount(i)/3; + case(QUADS): + for(unsigned int i=_firstCommand; icount(i)/4; + case(LINE_STRIP): + case(LINE_LOOP): + case(TRIANGLE_STRIP): + case(TRIANGLE_FAN): + case(QUAD_STRIP): + case(PATCHES): + case(POLYGON): + { + unsigned int primcount = _IndirectCommandDrawArrays->getNumElements(); + return primcount; + } + } + return total; +} + From f27c379b1e5333234f7555c8b27ccd99352c3991 Mon Sep 17 00:00:00 2001 From: mp3butcher Date: Wed, 26 Jul 2017 23:36:55 +0200 Subject: [PATCH 02/19] some renaming and harmonisations with osg metamodel convention --- examples/osggpucull/osggpucull.cpp | 4 +- include/osg/PrimitiveSetIndirect | 74 +++++++++++++++++++++--------- src/osg/PrimitiveSetIndirect.cpp | 42 ++++++++--------- 3 files changed, 76 insertions(+), 44 deletions(-) diff --git a/examples/osggpucull/osggpucull.cpp b/examples/osggpucull/osggpucull.cpp index 52d272db5..194a9a946 100644 --- a/examples/osggpucull/osggpucull.cpp +++ b/examples/osggpucull/osggpucull.cpp @@ -206,7 +206,7 @@ struct IndirectTarget for(unsigned int j=0;jsize(); ++j){ osg::DrawArraysIndirect *ipr=new osg::DrawArraysIndirect( GL_TRIANGLES, j ); - ipr->setIndirectCommandDrawArrays( indirectCommands); + ipr->setIndirectCommandArray( indirectCommands); newPrimitiveSets.push_back(ipr); } @@ -220,7 +220,7 @@ struct IndirectTarget else // use glMultiDrawArraysIndirect() { osg::MultiDrawArraysIndirect *ipr=new osg::MultiDrawArraysIndirect( GL_TRIANGLES ); - ipr->setIndirectCommandDrawArrays( indirectCommands ); + ipr->setIndirectCommandArray( indirectCommands ); geometryAggregator->getAggregatedGeometry()->removePrimitiveSet(0,geometryAggregator->getAggregatedGeometry()->getNumPrimitiveSets() ); geometryAggregator->getAggregatedGeometry()->addPrimitiveSet( ipr ); } diff --git a/include/osg/PrimitiveSetIndirect b/include/osg/PrimitiveSetIndirect index dcb608af7..f1b78dd10 100644 --- a/include/osg/PrimitiveSetIndirect +++ b/include/osg/PrimitiveSetIndirect @@ -137,39 +137,34 @@ class OSG_EXPORT DrawElementsIndirect : public DrawElements public: DrawElementsIndirect(Type primType=PrimitiveType, GLenum mode = 0,unsigned int firstCommand = 0, GLsizei stride = 0): - DrawElements(primType,mode, 0),_firstCommand(firstCommand),_stride(stride){setIndirectCommandDrawArrays(new DefaultIndirectCommandDrawElements());} + DrawElements(primType,mode, 0),_firstCommand(firstCommand),_stride(stride){setIndirectCommandArray(new DefaultIndirectCommandDrawElements());} DrawElementsIndirect(const DrawElementsIndirect& rhs,const CopyOp& copyop=CopyOp::SHALLOW_COPY): DrawElements(rhs,copyop),_firstCommand(rhs._firstCommand), _stride(rhs._stride) { _IndirectCommandDrawArrays=(DefaultIndirectCommandDrawElements*)copyop(rhs._IndirectCommandDrawArrays.get()); } /// set command array of this indirect primitive set - inline void setIndirectCommandDrawArrays(IndirectCommandDrawElements*idc) { + inline void setIndirectCommandArray(IndirectCommandDrawElements*idc) { _IndirectCommandDrawArrays = idc; if(!_IndirectCommandDrawArrays->getBufferObject()) _IndirectCommandDrawArrays->setBufferObject(new osg::VertexBufferObject()); } /// get command array of this indirect primitive set - inline IndirectCommandDrawElements* getIndirectCommandDrawArrays()const { - return _IndirectCommandDrawArrays; - } + inline IndirectCommandDrawElements* getIndirectCommandArray() { return _IndirectCommandDrawArrays; } + inline const IndirectCommandDrawElements* getIndirectCommandArray() const { return _IndirectCommandDrawArrays; } ///Further methods are for advanced DI when you plan to use your own IndirectCommandElement (stride) ///or if you want to draw a particular command index of the IndirectCommandElement(FirstCommandToDraw) /// set offset of the first command to draw in the IndirectCommandDrawArrays - inline void setFirstCommandToDraw( unsigned int i) { - _firstCommand=i; - } + inline void setFirstCommandToDraw( unsigned int i) { _firstCommand = i; } /// get offset of the first command in the IndirectCommandDrawArrays - inline unsigned int getFirstCommandToDraw()const { - return _firstCommand; - } + inline unsigned int getFirstCommandToDraw() const { return _firstCommand; } /// stride (to set if you use custom CommandArray) inline void setStride( GLsizei i) { _stride=i; } /// stride (to set if you use custom CommandArray) - inline GLsizei getStride()const { + inline GLsizei getStride() const { return _stride; } virtual unsigned int getNumPrimitives() const=0; @@ -491,7 +486,18 @@ public: DrawElementsIndirectUShort(mode,firstCommand,stride),_count(commandcount){_primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType));} MultiDrawElementsIndirectUShort(const MultiDrawElementsIndirectUShort& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY): DrawElementsIndirectUShort(mdi,copyop),_count(mdi._count) {} - + virtual osg::Object* cloneType() const { + return new MultiDrawElementsIndirectUShort(); + } + virtual osg::Object* clone(const osg::CopyOp& copyop) const { + return new MultiDrawElementsIndirectUShort(*this,copyop); + } + virtual bool isSameKindAs(const osg::Object* obj) const { + return dynamic_cast(obj)!=NULL; + } + virtual const char* className() const { + return "MultiDrawElementsIndirectUShort"; + } virtual void draw(State& state, bool useVertexBufferObjects) const; virtual void accept(PrimitiveFunctor& functor) const; virtual void accept(PrimitiveIndexFunctor& functor) const; @@ -519,6 +525,18 @@ public: DrawElementsIndirectUByte(mode,firstCommand,stride),_count(commandcount){_primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType));} MultiDrawElementsIndirectUByte(const MultiDrawElementsIndirectUByte& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY): DrawElementsIndirectUByte(mdi,copyop),_count(mdi._count) {} + virtual osg::Object* cloneType() const { + return new MultiDrawElementsIndirectUByte(); + } + virtual osg::Object* clone(const osg::CopyOp& copyop) const { + return new MultiDrawElementsIndirectUByte(*this,copyop); + } + virtual bool isSameKindAs(const osg::Object* obj) const { + return dynamic_cast(obj)!=NULL; + } + virtual const char* className() const { + return "MultiDrawElementsIndirectUByte"; + } virtual void draw(State& state, bool useVertexBufferObjects) const; virtual void accept(PrimitiveFunctor& functor) const; virtual void accept(PrimitiveIndexFunctor& functor) const; @@ -542,7 +560,18 @@ public: DrawElementsIndirectUInt(mode,firstCommand,stride),_count(commandcount){_primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType));} MultiDrawElementsIndirectUInt(const MultiDrawElementsIndirectUInt& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY): DrawElementsIndirectUInt(mdi,copyop),_count(mdi._count) {} - + virtual osg::Object* cloneType() const { + return new MultiDrawElementsIndirectUInt(); + } + virtual osg::Object* clone(const osg::CopyOp& copyop) const { + return new MultiDrawElementsIndirectUInt(*this,copyop); + } + virtual bool isSameKindAs(const osg::Object* obj) const { + return dynamic_cast(obj)!=NULL; + } + virtual const char* className() const { + return "MultiDrawElementsIndirectUInt"; + } virtual void draw(State& state, bool useVertexBufferObjects) const; virtual void accept(PrimitiveFunctor& functor) const; virtual void accept(PrimitiveIndexFunctor& functor) const; @@ -568,7 +597,7 @@ public: DrawArraysIndirect(GLenum mode=0, unsigned int firstcommand = 0, GLsizei stride = 0): osg::PrimitiveSet(Type(DrawArraysIndirectPrimitiveType), mode), - _firstCommand(firstcommand), _stride(stride) {setIndirectCommandDrawArrays(new DefaultIndirectCommandDrawArrays);} + _firstCommand(firstcommand), _stride(stride) {setIndirectCommandArray(new DefaultIndirectCommandDrawArrays);} DrawArraysIndirect(const DrawArraysIndirect& dal,const CopyOp& copyop=CopyOp::SHALLOW_COPY): osg::PrimitiveSet(dal,copyop), @@ -604,8 +633,8 @@ public: virtual unsigned int getNumPrimitives() const; - /// stride (to set if you use custom CommandArray) - inline void setStride( GLsizei i) { + /// stride (to set if you use custom CommandArray) + inline void setStride( GLsizei i) { _stride=i; } /// stride (to set if you use custom CommandArray) @@ -613,20 +642,23 @@ public: return _stride; } /// set offset of the first command in the IndirectCommandDrawArrays - inline void setFirstCommand( unsigned int i) { + inline void setFirstCommandToDraw( unsigned int i) { _firstCommand=i; } /// get offset of the first command in the IndirectCommandDrawArrays - inline unsigned int getFirstCommand()const { + inline unsigned int getFirstCommandToDraw() const { return _firstCommand; } - inline void setIndirectCommandDrawArrays(IndirectCommandDrawArrays*idc) { + inline void setIndirectCommandArray(IndirectCommandDrawArrays*idc) { _IndirectCommandDrawArrays = idc; if(!_IndirectCommandDrawArrays->getBufferObject()) _IndirectCommandDrawArrays->setBufferObject(new osg::VertexBufferObject()); } - inline IndirectCommandDrawArrays* getIndirectCommandDrawArrays()const { + inline const IndirectCommandDrawArrays* getIndirectCommandArray() const { + return _IndirectCommandDrawArrays; + } + inline IndirectCommandDrawArrays* getIndirectCommandArray(){ return _IndirectCommandDrawArrays; } diff --git a/src/osg/PrimitiveSetIndirect.cpp b/src/osg/PrimitiveSetIndirect.cpp index d3b10e585..0865f9418 100644 --- a/src/osg/PrimitiveSetIndirect.cpp +++ b/src/osg/PrimitiveSetIndirect.cpp @@ -29,7 +29,7 @@ template inline unsigned int getNumPrimitivesDI( const T&_this) { unsigned int offset= _this.getFirstCommandToDraw(); - IndirectCommandDrawElements *cmd=_this.getIndirectCommandDrawArrays(); + IndirectCommandDrawElements *cmd=const_cast(_this.getIndirectCommandArray()); unsigned int total=0; switch(_this.getMode()) { @@ -221,21 +221,21 @@ void DrawElementsIndirectUShort::accept(PrimitiveIndexFunctor& functor) const // template inline unsigned int getNumPrimitivesMDI( const T&_this) -{ IndirectCommandDrawElements *_IndirectCommandDrawArrays=_this.getIndirectCommandDrawArrays(); +{ IndirectCommandDrawElements *_IndirectCommandDrawArrays=const_cast(_this.getIndirectCommandArray()); unsigned int total=0; switch(_this.getMode()) { case(PrimitiveSet::POINTS): - for(unsigned int i=0;i<_IndirectCommandDrawArrays->getNumElements();i++) + for(unsigned int i=0;i<_IndirectCommandDrawArrays->getNumElements();++i) total+=_IndirectCommandDrawArrays->count(i); case(PrimitiveSet::LINES): - for(unsigned int i=0;i<_IndirectCommandDrawArrays->getNumElements();i++) + for(unsigned int i=0;i<_IndirectCommandDrawArrays->getNumElements();++i) total+=_IndirectCommandDrawArrays->count(i)/2; case(PrimitiveSet::TRIANGLES): - for(unsigned int i=0;i<_IndirectCommandDrawArrays->getNumElements();i++) + for(unsigned int i=0;i<_IndirectCommandDrawArrays->getNumElements();++i) total+=_IndirectCommandDrawArrays->count(i)/3; case(PrimitiveSet::QUADS): - for(unsigned int i=0;i<_IndirectCommandDrawArrays->getNumElements();i++) + for(unsigned int i=0;i<_IndirectCommandDrawArrays->getNumElements();++i) total+=_IndirectCommandDrawArrays->count(i)/4; case(PrimitiveSet::LINE_STRIP): case(PrimitiveSet::LINE_LOOP): @@ -290,7 +290,7 @@ void MultiDrawElementsIndirectUByte::accept(PrimitiveFunctor& functor) const { /* if (!empty() ) unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; - for(unsigned int i=_firstCommand; icount(i), &(*this)[_IndirectCommandDrawArrays->firstIndex(i)], _IndirectCommandDrawArrays->baseVertex(i)); @@ -301,7 +301,7 @@ void MultiDrawElementsIndirectUByte::accept(PrimitiveIndexFunctor& functor) cons { /* if (!empty() ) unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; - for(unsigned int i=_firstCommand; icount(i), &(*this)[_IndirectCommandDrawArrays->firstIndex(i)], _IndirectCommandDrawArrays->baseVertex(i)); @@ -345,7 +345,7 @@ void MultiDrawElementsIndirectUShort::accept(PrimitiveFunctor& functor) const { /* if (!empty() ) unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; - for(unsigned int i=_firstCommand; icount(i), &(*this)[_IndirectCommandDrawArrays->firstIndex(i)], _IndirectCommandDrawArrays->baseVertex(i)); @@ -356,7 +356,7 @@ void MultiDrawElementsIndirectUShort::accept(PrimitiveIndexFunctor& functor) con { /* if (!empty() ) unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; - for(unsigned int i=_firstCommand; icount(i), &(*this)[_IndirectCommandDrawArrays->firstIndex(i)], _IndirectCommandDrawArrays->baseVertex(i)); @@ -398,7 +398,7 @@ void MultiDrawElementsIndirectUInt::accept(PrimitiveFunctor& functor) const { /* if (!empty() ) unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; - for(unsigned int i=_firstCommand; icount(i), &(*this)[_IndirectCommandDrawArrays->firstIndex(i)], _IndirectCommandDrawArrays->baseVertex(i)); @@ -409,7 +409,7 @@ void MultiDrawElementsIndirectUInt::accept(PrimitiveIndexFunctor& functor) const { /* if (!empty() ) unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; - for(unsigned int i=_firstCommand; icount(i), &(*this)[_IndirectCommandDrawArrays->firstIndex(i)], _IndirectCommandDrawArrays->baseVertex(i)); @@ -504,7 +504,7 @@ void MultiDrawArraysIndirect::draw(osg::State& state, bool) const void MultiDrawArraysIndirect::accept(PrimitiveFunctor& functor) const { unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; - for(unsigned int i=_firstCommand; ifirst(i), _IndirectCommandDrawArrays->count(i)); } @@ -513,7 +513,7 @@ void MultiDrawArraysIndirect::accept(PrimitiveFunctor& functor) const void MultiDrawArraysIndirect::accept(PrimitiveIndexFunctor& functor) const { unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; - for(unsigned int i=_firstCommand; ifirst(i), _IndirectCommandDrawArrays->count(i)); } @@ -524,7 +524,7 @@ unsigned int MultiDrawArraysIndirect::getNumIndices() const unsigned int total=0; unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; - for(unsigned int i=_firstCommand; icount(i); return total; } @@ -532,7 +532,7 @@ unsigned int MultiDrawArraysIndirect::getNumIndices() const unsigned int MultiDrawArraysIndirect::index(unsigned int pos) const { /* unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; - for(unsigned int i=_firstCommand; icount(i); if (pos0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; - for(unsigned int i=_firstCommand; ifirst(i) += offset; } @@ -557,16 +557,16 @@ unsigned int MultiDrawArraysIndirect::getNumPrimitives() const switch(_mode) { case(POINTS): - for(unsigned int i=_firstCommand; icount(i); case(LINES): - for(unsigned int i=_firstCommand; icount(i)/2; case(TRIANGLES): - for(unsigned int i=_firstCommand; icount(i)/3; case(QUADS): - for(unsigned int i=_firstCommand; icount(i)/4; case(LINE_STRIP): case(LINE_LOOP): From b26fa74e7e698438d2b63dc6da8af267985c7fa2 Mon Sep 17 00:00:00 2001 From: mp3butcher Date: Wed, 26 Jul 2017 23:38:20 +0200 Subject: [PATCH 03/19] add untested serializers for PrimitiveSetIndirect --- .../serializers/osg/PrimitiveSetIndirect.cpp | 188 ++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 src/osgWrappers/serializers/osg/PrimitiveSetIndirect.cpp diff --git a/src/osgWrappers/serializers/osg/PrimitiveSetIndirect.cpp b/src/osgWrappers/serializers/osg/PrimitiveSetIndirect.cpp new file mode 100644 index 000000000..1d732cdb8 --- /dev/null +++ b/src/osgWrappers/serializers/osg/PrimitiveSetIndirect.cpp @@ -0,0 +1,188 @@ +#include +#include +#include +#include +#include + +namespace DACommandsArrays { +REGISTER_OBJECT_WRAPPER( IndirectCommandDrawArrays, + 0, + osg::IndirectCommandDrawArrays, + "osg::Object osg::BufferData osg::IndirectCommandDrawArrays" ) +{ + { + UPDATE_TO_VERSION_SCOPED( 147 ) + ADDED_ASSOCIATE("osg::BufferData") + } +} +} +namespace DECommandsArrays { +REGISTER_OBJECT_WRAPPER( IndirectCommandDrawElements, + 0, + osg::IndirectCommandDrawElements, + "osg::Object osg::BufferData osg::IndirectCommandDrawElements" ) +{ + { + UPDATE_TO_VERSION_SCOPED( 147 ) + ADDED_ASSOCIATE("osg::BufferData") + } +} +} +namespace DefaultDACommandsArrays { + + +static bool checkDACommands( const osg::DefaultIndirectCommandDrawArrays& node ) +{ + return node.size()>0; +} + +static bool readDACommands( osgDB::InputStream& is, osg::DefaultIndirectCommandDrawArrays& node ) +{ + unsigned int elmt, size = 0; is >> size >> is.BEGIN_BRACKET; + node.resize(size); + for ( unsigned int i=0; i>elmt; node.count(i) = elmt; + is >>elmt; node.instanceCount(i) = elmt; + is >>elmt; node.first(i) = elmt; + is >>elmt; node.baseInstance(i) = elmt; + } + is >> is.END_BRACKET; + return true; +} + +static bool writeDACommands( osgDB::OutputStream& os, const osg::DefaultIndirectCommandDrawArrays& node ) +{ + unsigned int size = node.getNumElements(); + osg::DefaultIndirectCommandDrawArrays& nonconstnode =const_cast(node); + os << size << os.BEGIN_BRACKET << std::endl; + for ( unsigned int i=0; i0; +} + +static bool readDECommands( osgDB::InputStream& is, osg::DefaultIndirectCommandDrawElements& node ) +{ + unsigned int elmt, size = 0; is >> size >> is.BEGIN_BRACKET; + node.resize(size); + for ( unsigned int i=0; i>elmt; node.count(i) = elmt; + is >>elmt; node.instanceCount(i) = elmt; + is >>elmt; node.firstIndex(i) = elmt; + is >>elmt; node.baseVertex(i) = elmt; + is >>elmt; node.baseInstance(i) = elmt; + } + is >> is.END_BRACKET; + return true; +} + +static bool writeDECommands( osgDB::OutputStream& os, const osg::DefaultIndirectCommandDrawElements& node ) +{ + unsigned int size = node.getNumElements(); + osg::DefaultIndirectCommandDrawElements& nonconstnode =const_cast(node); + os << size << os.BEGIN_BRACKET << std::endl; + for ( unsigned int i=0; i Date: Thu, 27 Jul 2017 01:08:37 +0200 Subject: [PATCH 04/19] fix some errors during renaming and cleanup code --- include/osg/PrimitiveSetIndirect | 31 +-- src/osg/PrimitiveSetIndirect.cpp | 315 +++++++++++++++++-------------- 2 files changed, 187 insertions(+), 159 deletions(-) diff --git a/include/osg/PrimitiveSetIndirect b/include/osg/PrimitiveSetIndirect index f1b78dd10..d8771a781 100644 --- a/include/osg/PrimitiveSetIndirect +++ b/include/osg/PrimitiveSetIndirect @@ -141,17 +141,19 @@ public: DrawElementsIndirect(const DrawElementsIndirect& rhs,const CopyOp& copyop=CopyOp::SHALLOW_COPY): DrawElements(rhs,copyop),_firstCommand(rhs._firstCommand), _stride(rhs._stride) { - _IndirectCommandDrawArrays=(DefaultIndirectCommandDrawElements*)copyop(rhs._IndirectCommandDrawArrays.get()); + _indirectCommandArray=(DefaultIndirectCommandDrawElements*)copyop(rhs._indirectCommandArray.get()); } + /// set command array of this indirect primitive set inline void setIndirectCommandArray(IndirectCommandDrawElements*idc) { - _IndirectCommandDrawArrays = idc; - if(!_IndirectCommandDrawArrays->getBufferObject()) - _IndirectCommandDrawArrays->setBufferObject(new osg::VertexBufferObject()); + _indirectCommandArray = idc; + if(!_indirectCommandArray->getBufferObject()) + _indirectCommandArray->setBufferObject(new osg::VertexBufferObject()); } /// get command array of this indirect primitive set - inline IndirectCommandDrawElements* getIndirectCommandArray() { return _IndirectCommandDrawArrays; } - inline const IndirectCommandDrawElements* getIndirectCommandArray() const { return _IndirectCommandDrawArrays; } + inline IndirectCommandDrawElements* getIndirectCommandArray() { return _indirectCommandArray; } + inline const IndirectCommandDrawElements* getIndirectCommandArray() const { return _indirectCommandArray; } + ///Further methods are for advanced DI when you plan to use your own IndirectCommandElement (stride) ///or if you want to draw a particular command index of the IndirectCommandElement(FirstCommandToDraw) @@ -159,6 +161,7 @@ public: inline void setFirstCommandToDraw( unsigned int i) { _firstCommand = i; } /// get offset of the first command in the IndirectCommandDrawArrays inline unsigned int getFirstCommandToDraw() const { return _firstCommand; } + /// stride (to set if you use custom CommandArray) inline void setStride( GLsizei i) { _stride=i; @@ -174,7 +177,7 @@ protected: unsigned int _firstCommand; GLsizei _stride; - ref_ptr _IndirectCommandDrawArrays; + ref_ptr _indirectCommandArray; }; /////////////////////////////////////////////////////////////////////////////////////// @@ -603,7 +606,7 @@ public: osg::PrimitiveSet(dal,copyop), _firstCommand(dal._firstCommand), _stride(dal._stride), - _IndirectCommandDrawArrays((DefaultIndirectCommandDrawArrays*)copyop( dal._IndirectCommandDrawArrays.get())) + _indirectCommandArray((DefaultIndirectCommandDrawArrays*)copyop( dal._indirectCommandArray.get())) {} virtual osg::Object* cloneType() const { @@ -651,22 +654,22 @@ public: } inline void setIndirectCommandArray(IndirectCommandDrawArrays*idc) { - _IndirectCommandDrawArrays = idc; - if(!_IndirectCommandDrawArrays->getBufferObject()) - _IndirectCommandDrawArrays->setBufferObject(new osg::VertexBufferObject()); + _indirectCommandArray = idc; + if(!_indirectCommandArray->getBufferObject()) + _indirectCommandArray->setBufferObject(new osg::VertexBufferObject()); } inline const IndirectCommandDrawArrays* getIndirectCommandArray() const { - return _IndirectCommandDrawArrays; + return _indirectCommandArray; } inline IndirectCommandDrawArrays* getIndirectCommandArray(){ - return _IndirectCommandDrawArrays; + return _indirectCommandArray; } protected: unsigned int _firstCommand; GLsizei _stride; - ref_ptr _IndirectCommandDrawArrays; + ref_ptr _indirectCommandArray; }; diff --git a/src/osg/PrimitiveSetIndirect.cpp b/src/osg/PrimitiveSetIndirect.cpp index 0865f9418..add1c98a4 100644 --- a/src/osg/PrimitiveSetIndirect.cpp +++ b/src/osg/PrimitiveSetIndirect.cpp @@ -20,13 +20,16 @@ #include #include +/// TODO: add base vertex feature to PrimitiveFunctor and PrimitiveIndexFunctor +//#define PRIMFUNCTORBASEVERTEX 1 + using namespace osg; //////////////////////////////////////////////////////////////////////////////////////////////////////// // // DrawElementsIndirect // -template inline -unsigned int getNumPrimitivesDI( const T&_this) +template +inline unsigned int getNumPrimitivesDI( const T&_this ) { unsigned int offset= _this.getFirstCommandToDraw(); IndirectCommandDrawElements *cmd=const_cast(_this.getIndirectCommandArray()); @@ -60,7 +63,7 @@ unsigned int DrawElementsIndirectUByte::getNumPrimitives() const{return getNumPr unsigned int DrawElementsIndirectUShort::getNumPrimitives() const{return getNumPrimitivesDI(*this);} void DrawElementsIndirectUInt::draw(State& state, bool useVertexBufferObjects) const -{ GLBufferObject* dibo = _IndirectCommandDrawArrays->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); +{ GLBufferObject* dibo = _indirectCommandArray->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); GLenum mode = _mode; @@ -76,8 +79,8 @@ void DrawElementsIndirectUInt::draw(State& state, bool useVertexBufferObjects) c state.bindElementBufferObject(ebo); state.get()-> glDrawElementsIndirect(mode, GL_UNSIGNED_INT, - (const GLvoid *)(dibo->getOffset(_IndirectCommandDrawArrays->getBufferIndex()) //command array adress - +_firstCommand* _IndirectCommandDrawArrays->getElementSize())// runtime offset computaion can be sizeof(*_IndirectCommandDrawArrays->begin()) + (const GLvoid *)(dibo->getOffset(_indirectCommandArray->getBufferIndex()) //command array adress + +_firstCommand* _indirectCommandArray->getElementSize())// runtime offset computaion can be sizeof(*_indirectCommandArray->begin()) ); } @@ -97,24 +100,28 @@ void DrawElementsIndirectUInt::offsetIndices(int offset) } void DrawElementsIndirectUInt::accept(PrimitiveFunctor& functor) const { - /* if (!empty() && cmd) - functor.drawElements(_mode,_IndirectCommandDrawArrays->count(_firstCommand), - &(*this)[_IndirectCommandDrawArrays->firstIndex(_firstCommand)] - _IndirectCommandDrawArrays->baseVertex(_firstCommand)); - */ +#ifdef PRIMFUNCTORBASEVERTEX + // TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method + if (!empty()) + functor.drawElements(_mode,_indirectCommandArray->count(_firstCommand), + &(*this)[_indirectCommandArray->firstIndex(_firstCommand)] + ,_indirectCommandArray->baseVertex(_firstCommand)); +#endif } void DrawElementsIndirectUInt::accept(PrimitiveIndexFunctor& functor) const { -/* if (!empty() && cmd) - functor.drawElements(_mode,_IndirectCommandDrawArrays->count(_firstCommand), - &(*this)[_IndirectCommandDrawArrays->firstIndex(_firstCommand)] - _IndirectCommandDrawArrays->baseVertex(_firstCommand)); - */ +#ifdef PRIMFUNCTORBASEVERTEX + // TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method + if (!empty()) + functor.drawElements(_mode,_indirectCommandArray->count(_firstCommand), + &(*this)[_indirectCommandArray->firstIndex(_firstCommand)] + ,_indirectCommandArray->baseVertex(_firstCommand)); +#endif } void DrawElementsIndirectUByte::draw(State& state, bool useVertexBufferObjects) const -{ GLBufferObject* dibo = _IndirectCommandDrawArrays->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); +{ GLBufferObject* dibo = _indirectCommandArray->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); GLenum mode = _mode; @@ -129,8 +136,8 @@ void DrawElementsIndirectUByte::draw(State& state, bool useVertexBufferObjects) state.bindElementBufferObject(ebo); - state.get()-> glDrawElementsIndirect(mode, GL_UNSIGNED_BYTE, (const GLvoid *)(dibo->getOffset(_IndirectCommandDrawArrays->getBufferIndex()) - +_firstCommand* _IndirectCommandDrawArrays->getElementSize())); + state.get()-> glDrawElementsIndirect(mode, GL_UNSIGNED_BYTE, (const GLvoid *)(dibo->getOffset(_indirectCommandArray->getBufferIndex()) + +_firstCommand* _indirectCommandArray->getElementSize())); } DrawElementsIndirectUByte::~DrawElementsIndirectUByte() @@ -148,24 +155,27 @@ void DrawElementsIndirectUByte::offsetIndices(int offset) } void DrawElementsIndirectUByte::accept(PrimitiveFunctor& functor) const { -/* if (!empty() && cmd) - functor.drawElements(_mode,_IndirectCommandDrawArrays->count(_firstCommand), - &(*this)[_IndirectCommandDrawArrays->firstIndex(_firstCommand)] - _IndirectCommandDrawArrays->baseVertex(_firstCommand)); - */ +#ifdef PRIMFUNCTORBASEVERTEX + // TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method + if (!empty()) + functor.drawElements(_mode,_indirectCommandArray->count(_firstCommand), + &(*this)[_indirectCommandArray->firstIndex(_firstCommand)] + ,_indirectCommandArray->baseVertex(_firstCommand)); +#endif } void DrawElementsIndirectUByte::accept(PrimitiveIndexFunctor& functor) const { -/* if (!empty() && cmd) - functor.drawElements(_mode,_IndirectCommandDrawArrays->count(_firstCommand), - &(*this)[_IndirectCommandDrawArrays->firstIndex(_firstCommand)] - _IndirectCommandDrawArrays->baseVertex(_firstCommand)); - */ - +#ifdef PRIMFUNCTORBASEVERTEX + // TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method + if (!empty()) + functor.drawElements(_mode,_indirectCommandArray->count(_firstCommand), + &(*this)[_indirectCommandArray->firstIndex(_firstCommand)] + ,_indirectCommandArray->baseVertex(_firstCommand)); +#endif } void DrawElementsIndirectUShort::draw(State& state, bool useVertexBufferObjects) const -{ GLBufferObject* dibo = _IndirectCommandDrawArrays->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); +{ GLBufferObject* dibo = _indirectCommandArray->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); GLenum mode = _mode; @@ -180,8 +190,8 @@ void DrawElementsIndirectUShort::draw(State& state, bool useVertexBufferObjects) state.bindElementBufferObject(ebo); - state.get()-> glDrawElementsIndirect(mode, GL_UNSIGNED_SHORT, (const GLvoid *)(dibo->getOffset(_IndirectCommandDrawArrays->getBufferIndex()) - +_firstCommand* _IndirectCommandDrawArrays->getElementSize())); + state.get()-> glDrawElementsIndirect(mode, GL_UNSIGNED_SHORT, (const GLvoid *)(dibo->getOffset(_indirectCommandArray->getBufferIndex()) + +_firstCommand* _indirectCommandArray->getElementSize())); } DrawElementsIndirectUShort::~DrawElementsIndirectUShort() @@ -199,20 +209,24 @@ void DrawElementsIndirectUShort::offsetIndices(int offset) } void DrawElementsIndirectUShort::accept(PrimitiveFunctor& functor) const { -/* if (!empty() && cmd) - functor.drawElements(_mode,_IndirectCommandDrawArrays->count(_firstCommand), - &(*this)[_IndirectCommandDrawArrays->firstIndex(_firstCommand)] - _IndirectCommandDrawArrays->baseVertex(_firstCommand)); - */ +#ifdef PRIMFUNCTORBASEVERTEX + // TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method + if (!empty()) + functor.drawElements(_mode,_indirectCommandArray->count(_firstCommand), + &(*this)[_indirectCommandArray->firstIndex(_firstCommand)] + ,_indirectCommandArray->baseVertex(_firstCommand)); +#endif } void DrawElementsIndirectUShort::accept(PrimitiveIndexFunctor& functor) const { -/* if (!empty() && cmd) - functor.drawElements(_mode,_IndirectCommandDrawArrays->count(_firstCommand), - &(*this)[_IndirectCommandDrawArrays->firstIndex(_firstCommand)] - _IndirectCommandDrawArrays->baseVertex(_firstCommand)); - */ +#ifdef PRIMFUNCTORBASEVERTEX + // TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method + if (!empty()) + functor.drawElements(_mode,_indirectCommandArray->count(_firstCommand), + &(*this)[_indirectCommandArray->firstIndex(_firstCommand)] + ,_indirectCommandArray->baseVertex(_firstCommand)); +#endif } //////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -221,22 +235,22 @@ void DrawElementsIndirectUShort::accept(PrimitiveIndexFunctor& functor) const // template inline unsigned int getNumPrimitivesMDI( const T&_this) -{ IndirectCommandDrawElements *_IndirectCommandDrawArrays=const_cast(_this.getIndirectCommandArray()); +{ IndirectCommandDrawElements *_indirectCommandArray=const_cast(_this.getIndirectCommandArray()); unsigned int total=0; switch(_this.getMode()) { case(PrimitiveSet::POINTS): - for(unsigned int i=0;i<_IndirectCommandDrawArrays->getNumElements();++i) - total+=_IndirectCommandDrawArrays->count(i); + for(unsigned int i=0;i<_indirectCommandArray->getNumElements();++i) + total+=_indirectCommandArray->count(i); case(PrimitiveSet::LINES): - for(unsigned int i=0;i<_IndirectCommandDrawArrays->getNumElements();++i) - total+=_IndirectCommandDrawArrays->count(i)/2; + for(unsigned int i=0;i<_indirectCommandArray->getNumElements();++i) + total+=_indirectCommandArray->count(i)/2; case(PrimitiveSet::TRIANGLES): - for(unsigned int i=0;i<_IndirectCommandDrawArrays->getNumElements();++i) - total+=_IndirectCommandDrawArrays->count(i)/3; + for(unsigned int i=0;i<_indirectCommandArray->getNumElements();++i) + total+=_indirectCommandArray->count(i)/3; case(PrimitiveSet::QUADS): - for(unsigned int i=0;i<_IndirectCommandDrawArrays->getNumElements();++i) - total+=_IndirectCommandDrawArrays->count(i)/4; + for(unsigned int i=0;i<_indirectCommandArray->getNumElements();++i) + total+=_indirectCommandArray->count(i)/4; case(PrimitiveSet::LINE_STRIP): case(PrimitiveSet::LINE_LOOP): case(PrimitiveSet::TRIANGLE_STRIP): @@ -245,7 +259,7 @@ unsigned int getNumPrimitivesMDI( const T&_this) case(PrimitiveSet::PATCHES): case(PrimitiveSet::POLYGON): { - unsigned int primcount = _IndirectCommandDrawArrays->getNumElements(); + unsigned int primcount = _indirectCommandArray->getNumElements(); return primcount; } } @@ -266,7 +280,7 @@ MultiDrawElementsIndirectUByte::~MultiDrawElementsIndirectUByte() } void MultiDrawElementsIndirectUByte::draw(State& state, bool useVertexBufferObjects) const { - GLBufferObject* dibo = _IndirectCommandDrawArrays->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); + GLBufferObject* dibo = _indirectCommandArray->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); GLenum mode = _mode; @@ -282,30 +296,34 @@ void MultiDrawElementsIndirectUByte::draw(State& state, bool useVertexBufferObje state.bindElementBufferObject(ebo); - state.get()-> glMultiDrawElementsIndirect(mode, GL_UNSIGNED_BYTE, (const GLvoid *)(dibo->getOffset(_IndirectCommandDrawArrays->getBufferIndex())),_IndirectCommandDrawArrays->getNumElements(), _stride); + state.get()-> glMultiDrawElementsIndirect(mode, GL_UNSIGNED_BYTE, (const GLvoid *)(dibo->getOffset(_indirectCommandArray->getBufferIndex())),_indirectCommandArray->getNumElements(), _stride); } void MultiDrawElementsIndirectUByte::accept(PrimitiveFunctor& functor) const { - /* if (!empty() ) - unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; - for(unsigned int i=_firstCommand; icount(i), - &(*this)[_IndirectCommandDrawArrays->firstIndex(i)], - _IndirectCommandDrawArrays->baseVertex(i)); - */ +#ifdef PRIMFUNCTORBASEVERTEX + //TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method + unsigned int maxindex=_count>0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + if (!empty() ) + for(unsigned int i = _firstCommand; icount(i), + &(*this)[_indirectCommandArray->firstIndex(i)] + ,_indirectCommandArray->baseVertex(i)); +#endif } void MultiDrawElementsIndirectUByte::accept(PrimitiveIndexFunctor& functor) const { - /* if (!empty() ) - unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; - for(unsigned int i=_firstCommand; icount(i), - &(*this)[_IndirectCommandDrawArrays->firstIndex(i)], - _IndirectCommandDrawArrays->baseVertex(i)); - */ +#ifdef PRIMFUNCTORBASEVERTEX + //TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method + unsigned int maxindex=_count>0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + if (!empty() ) + for(unsigned int i = _firstCommand; icount(i), + &(*this)[_indirectCommandArray->firstIndex(i)] + ,_indirectCommandArray->baseVertex(i)); +#endif } @@ -321,7 +339,7 @@ MultiDrawElementsIndirectUShort::~MultiDrawElementsIndirectUShort() } void MultiDrawElementsIndirectUShort::draw(State& state, bool useVertexBufferObjects) const -{ GLBufferObject* dibo = _IndirectCommandDrawArrays->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); +{ GLBufferObject* dibo = _indirectCommandArray->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); GLenum mode = _mode; @@ -336,31 +354,35 @@ void MultiDrawElementsIndirectUShort::draw(State& state, bool useVertexBufferObj state.bindElementBufferObject(ebo); - state.get()-> glMultiDrawElementsIndirect(mode, GL_UNSIGNED_SHORT, (const GLvoid *)(dibo->getOffset(_IndirectCommandDrawArrays->getBufferIndex())), - _count>0?_count:_IndirectCommandDrawArrays->getNumElements(),_stride); + state.get()-> glMultiDrawElementsIndirect(mode, GL_UNSIGNED_SHORT, (const GLvoid *)(dibo->getOffset(_indirectCommandArray->getBufferIndex())), + _count>0?_count:_indirectCommandArray->getNumElements(),_stride); } void MultiDrawElementsIndirectUShort::accept(PrimitiveFunctor& functor) const { - /* if (!empty() ) - unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; - for(unsigned int i=_firstCommand; icount(i), - &(*this)[_IndirectCommandDrawArrays->firstIndex(i)], - _IndirectCommandDrawArrays->baseVertex(i)); - */ +#ifdef PRIMFUNCTORBASEVERTEX + //TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method + unsigned int maxindex=_count>0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + if (!empty() ) + for(unsigned int i = _firstCommand; icount(i), + &(*this)[_indirectCommandArray->firstIndex(i)] + ,_indirectCommandArray->baseVertex(i)); +#endif } void MultiDrawElementsIndirectUShort::accept(PrimitiveIndexFunctor& functor) const { - /* if (!empty() ) - unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; - for(unsigned int i=_firstCommand; icount(i), - &(*this)[_IndirectCommandDrawArrays->firstIndex(i)], - _IndirectCommandDrawArrays->baseVertex(i)); - */ +#ifdef PRIMFUNCTORBASEVERTEX + //TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method + unsigned int maxindex=_count>0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + if (!empty() ) + for(unsigned int i = _firstCommand; icount(i), + &(*this)[_indirectCommandArray->firstIndex(i)] + ,_indirectCommandArray->baseVertex(i)); +#endif } //////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -374,7 +396,7 @@ MultiDrawElementsIndirectUInt::~MultiDrawElementsIndirectUInt() void MultiDrawElementsIndirectUInt::draw(State& state, bool useVertexBufferObjects) const { - GLBufferObject* dibo = _IndirectCommandDrawArrays->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); + GLBufferObject* dibo = _indirectCommandArray->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); GLenum mode = _mode; #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) @@ -389,32 +411,35 @@ void MultiDrawElementsIndirectUInt::draw(State& state, bool useVertexBufferObjec state.bindElementBufferObject(ebo); - state.get()-> glMultiDrawElementsIndirect(mode, GL_UNSIGNED_INT, (const GLvoid *)(dibo->getOffset(_IndirectCommandDrawArrays->getBufferIndex())), - _count>0?_count:_IndirectCommandDrawArrays->getNumElements(), _stride); + state.get()-> glMultiDrawElementsIndirect(mode, GL_UNSIGNED_INT, (const GLvoid *)(dibo->getOffset(_indirectCommandArray->getBufferIndex())), + _count>0?_count:_indirectCommandArray->getNumElements(), _stride); } void MultiDrawElementsIndirectUInt::accept(PrimitiveFunctor& functor) const { - /* if (!empty() ) - unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; - for(unsigned int i=_firstCommand; icount(i), - &(*this)[_IndirectCommandDrawArrays->firstIndex(i)], - _IndirectCommandDrawArrays->baseVertex(i)); - */ +#ifdef PRIMFUNCTORBASEVERTEX + //TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method + unsigned int maxindex=_count>0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + if (!empty() ) + for(unsigned int i = _firstCommand; icount(i), + &(*this)[_indirectCommandArray->firstIndex(i)] + ,_indirectCommandArray->baseVertex(i)); +#endif } void MultiDrawElementsIndirectUInt::accept(PrimitiveIndexFunctor& functor) const { - /* if (!empty() ) - unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; - for(unsigned int i=_firstCommand; icount(i), - &(*this)[_IndirectCommandDrawArrays->firstIndex(i)], - _IndirectCommandDrawArrays->baseVertex(i)); - */ - +#ifdef PRIMFUNCTORBASEVERTEX + //TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method + unsigned int maxindex=_count>0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + if (!empty() ) + for(unsigned int i = _firstCommand; icount(i), + &(*this)[_indirectCommandArray->firstIndex(i)] + ,_indirectCommandArray->baseVertex(i)); +#endif } @@ -424,39 +449,39 @@ void MultiDrawElementsIndirectUInt::accept(PrimitiveIndexFunctor& functor) const // void DrawArraysIndirect::draw(osg::State& state, bool) const { - GLBufferObject* dibo = _IndirectCommandDrawArrays->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); + GLBufferObject* dibo = _indirectCommandArray->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); GLExtensions* ext = state.get(); - ext->glDrawArraysIndirect(_mode, (const GLvoid *)(dibo->getOffset(_IndirectCommandDrawArrays->getBufferIndex()) - +_firstCommand* _IndirectCommandDrawArrays->getElementSize())); + ext->glDrawArraysIndirect(_mode, (const GLvoid *)(dibo->getOffset(_indirectCommandArray->getBufferIndex()) + +_firstCommand* _indirectCommandArray->getElementSize())); } void DrawArraysIndirect::accept(PrimitiveFunctor& functor) const { - functor.drawArrays(_mode, _IndirectCommandDrawArrays->first(_firstCommand), _IndirectCommandDrawArrays->count(_firstCommand)); + functor.drawArrays(_mode, _indirectCommandArray->first(_firstCommand), _indirectCommandArray->count(_firstCommand)); } void DrawArraysIndirect::accept(PrimitiveIndexFunctor& functor) const { - functor.drawArrays(_mode, _IndirectCommandDrawArrays->first(_firstCommand), _IndirectCommandDrawArrays->count(_firstCommand)); + functor.drawArrays(_mode, _indirectCommandArray->first(_firstCommand), _indirectCommandArray->count(_firstCommand)); } unsigned int DrawArraysIndirect::getNumIndices() const { - return _IndirectCommandDrawArrays->count(_firstCommand); + return _indirectCommandArray->count(_firstCommand); } unsigned int DrawArraysIndirect::index(unsigned int pos) const { - return _IndirectCommandDrawArrays->first(_firstCommand)+ pos; + return _indirectCommandArray->first(_firstCommand)+ pos; } void DrawArraysIndirect::offsetIndices(int offset) { - _IndirectCommandDrawArrays->first(_firstCommand)+= offset; + _indirectCommandArray->first(_firstCommand)+= offset; } unsigned int DrawArraysIndirect::getNumPrimitives() const @@ -464,13 +489,13 @@ unsigned int DrawArraysIndirect::getNumPrimitives() const switch(_mode) { case(POINTS): - return _IndirectCommandDrawArrays->count(_firstCommand); + return _indirectCommandArray->count(_firstCommand); case(LINES): - return _IndirectCommandDrawArrays->count(_firstCommand)/2; + return _indirectCommandArray->count(_firstCommand)/2; case(TRIANGLES): - return _IndirectCommandDrawArrays->count(_firstCommand)/3; + return _indirectCommandArray->count(_firstCommand)/3; case(QUADS): - return _IndirectCommandDrawArrays->count(_firstCommand)/4; + return _indirectCommandArray->count(_firstCommand)/4; case(LINE_STRIP): case(LINE_LOOP): case(TRIANGLE_STRIP): @@ -491,31 +516,31 @@ unsigned int DrawArraysIndirect::getNumPrimitives() const // void MultiDrawArraysIndirect::draw(osg::State& state, bool) const { - GLBufferObject* dibo = _IndirectCommandDrawArrays->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); + GLBufferObject* dibo = _indirectCommandArray->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); GLExtensions* ext = state.get(); - ext->glMultiDrawArraysIndirect(_mode, (const GLvoid *)(dibo->getOffset(_IndirectCommandDrawArrays->getBufferIndex())+_firstCommand*_IndirectCommandDrawArrays->getElementSize()), - _count>0?_count:_IndirectCommandDrawArrays->getNumElements(), _stride); + ext->glMultiDrawArraysIndirect(_mode, (const GLvoid *)(dibo->getOffset(_indirectCommandArray->getBufferIndex())+_firstCommand*_indirectCommandArray->getElementSize()), + _count>0?_count:_indirectCommandArray->getNumElements(), _stride); } void MultiDrawArraysIndirect::accept(PrimitiveFunctor& functor) const { - unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; - for(unsigned int i=_firstCommand; i0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + for(unsigned int i = _firstCommand; ifirst(i), _IndirectCommandDrawArrays->count(i)); + functor.drawArrays(_mode, _indirectCommandArray->first(i), _indirectCommandArray->count(i)); } } void MultiDrawArraysIndirect::accept(PrimitiveIndexFunctor& functor) const { - unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; - for(unsigned int i=_firstCommand; i0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + for(unsigned int i = _firstCommand; ifirst(i), _IndirectCommandDrawArrays->count(i)); + functor.drawArrays(_mode, _indirectCommandArray->first(i), _indirectCommandArray->count(i)); } } @@ -523,51 +548,51 @@ unsigned int MultiDrawArraysIndirect::getNumIndices() const { unsigned int total=0; - unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; - for(unsigned int i=_firstCommand; icount(i); + unsigned int maxindex=_count>0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + for(unsigned int i = _firstCommand; icount(i); return total; } unsigned int MultiDrawArraysIndirect::index(unsigned int pos) const { - /* unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; - for(unsigned int i=_firstCommand; i0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + for(i=_firstCommand; icount(i); + unsigned int count = _indirectCommandArray->count(i); if (posfirst(maxindex-1) + pos;*/ - return pos;//??? + if (i>=maxindex) return 0; + return _indirectCommandArray->first(maxindex-1) + pos; } void MultiDrawArraysIndirect::offsetIndices(int offset) { - unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; - for(unsigned int i=_firstCommand; ifirst(i) += offset; + unsigned int maxindex=_count>0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + for(unsigned int i = _firstCommand; ifirst(i) += offset; } unsigned int MultiDrawArraysIndirect::getNumPrimitives() const { - unsigned int total=0;unsigned int maxindex=_count>0?_firstCommand + _count : _IndirectCommandDrawArrays->getNumElements() - _firstCommand; + unsigned int total=0;unsigned int maxindex=_count>0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; switch(_mode) { case(POINTS): - for(unsigned int i=_firstCommand; icount(i); + for(unsigned int i = _firstCommand; icount(i); case(LINES): - for(unsigned int i=_firstCommand; icount(i)/2; + for(unsigned int i = _firstCommand; icount(i)/2; case(TRIANGLES): - for(unsigned int i=_firstCommand; icount(i)/3; + for(unsigned int i = _firstCommand; icount(i)/3; case(QUADS): - for(unsigned int i=_firstCommand; icount(i)/4; + for(unsigned int i = _firstCommand; icount(i)/4; case(LINE_STRIP): case(LINE_LOOP): case(TRIANGLE_STRIP): @@ -576,7 +601,7 @@ unsigned int MultiDrawArraysIndirect::getNumPrimitives() const case(PATCHES): case(POLYGON): { - unsigned int primcount = _IndirectCommandDrawArrays->getNumElements(); + unsigned int primcount = _indirectCommandArray->getNumElements(); return primcount; } } From 9b537758406f6d3313e597e1da773a9998b24102 Mon Sep 17 00:00:00 2001 From: mp3butcher Date: Thu, 27 Jul 2017 01:40:04 +0200 Subject: [PATCH 05/19] remove deprecated DrawIndirectBufferBinding --- include/osg/BufferIndexBinding | 23 --------------------- src/osg/BufferIndexBinding.cpp | 37 ---------------------------------- 2 files changed, 60 deletions(-) diff --git a/include/osg/BufferIndexBinding b/include/osg/BufferIndexBinding index 782022837..eb1d30228 100644 --- a/include/osg/BufferIndexBinding +++ b/include/osg/BufferIndexBinding @@ -201,29 +201,6 @@ class OSG_EXPORT ShaderStorageBufferBinding : public BufferIndexBinding } }; -class OSG_EXPORT DrawIndirectBufferBinding : public BufferIndexBinding -{ - public: - DrawIndirectBufferBinding(); - /** Create a binding for a uniform buffer index target. - * @param bo associated buffer object - */ - DrawIndirectBufferBinding( BufferObject* bo); - void apply(State& state) const; - DrawIndirectBufferBinding(const DrawIndirectBufferBinding& rhs, const CopyOp& copyop=CopyOp::SHALLOW_COPY); - - META_StateAttribute(osg, DrawIndirectBufferBinding, INDIRECTDRAWBUFFERBINDING); - - virtual int compare(const StateAttribute& bb) const - { - COMPARE_StateAttribute_Types(DrawIndirectBufferBinding, bb) - COMPARE_StateAttribute_Parameter(_target) - COMPARE_StateAttribute_Parameter(_bufferObject) - return 0; - } -}; - - } // namespace osg #endif diff --git a/src/osg/BufferIndexBinding.cpp b/src/osg/BufferIndexBinding.cpp index 739025fc0..ffbf451a1 100644 --- a/src/osg/BufferIndexBinding.cpp +++ b/src/osg/BufferIndexBinding.cpp @@ -18,10 +18,6 @@ #include // for memcpy -#ifndef GL_DRAW_INDIRECT_BUFFER - #define GL_DRAW_INDIRECT_BUFFER 0x8F3F -#endif - namespace osg { BufferIndexBinding::BufferIndexBinding(GLenum target, GLuint index) @@ -172,37 +168,4 @@ ShaderStorageBufferBinding::ShaderStorageBufferBinding(const ShaderStorageBuffer { } - - - - -DrawIndirectBufferBinding::DrawIndirectBufferBinding( ) - : BufferIndexBinding(GL_DRAW_INDIRECT_BUFFER, 0) -{ -} -void DrawIndirectBufferBinding::apply(State& state) const -{ - if (_bufferObject.valid()) - { - GLBufferObject* glObject - = _bufferObject->getOrCreateGLBufferObject(state.getContextID()); - if (!glObject->_extensions->isUniformBufferObjectSupported) - return; - // if (glObject->isDirty()) glObject->compileBuffer(); - glObject->_extensions->glBindBuffer (_target, glObject->getGLObjectID()); - } -} -DrawIndirectBufferBinding::DrawIndirectBufferBinding( BufferObject* bo) - : BufferIndexBinding(GL_DRAW_INDIRECT_BUFFER, 0, bo, 0, 0) -{ - -} - -DrawIndirectBufferBinding::DrawIndirectBufferBinding(const DrawIndirectBufferBinding& rhs, - const CopyOp& copyop) - : BufferIndexBinding(rhs, copyop) -{ -} - - } // namespace osg From 7606159a781feb751f47adcc5a9573822142a04c Mon Sep 17 00:00:00 2001 From: mp3butcher Date: Thu, 27 Jul 2017 01:54:25 +0200 Subject: [PATCH 06/19] add DrawIndirectBufferObject as State variable in order to minimize call to glBindBuffer(GL_DRAW_INDIRECT_BUFFER,X) TODO: Promote PrimitiveSetIndirect's VBO to target explicited DIBO (in order to benefit from BOSet queue management) --- include/osg/State | 22 ++++++++++++++++++++++ src/osg/PrimitiveSetIndirect.cpp | 16 ++++++++-------- src/osg/State.cpp | 1 + 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/include/osg/State b/include/osg/State index b79420dfd..28a2880c4 100644 --- a/include/osg/State +++ b/include/osg/State @@ -591,6 +591,27 @@ class OSG_EXPORT State : public Referenced } + inline void bindDrawIndirectBufferObject(osg::GLBufferObject* ibo) + { + if (ibo->isDirty()) + { + ibo->compileBuffer(); + _currentDIBO = ibo; + } + else if (ibo != _currentDIBO) + { + _glBindBuffer(GL_DRAW_INDIRECT_BUFFER, ibo->getGLObjectID()); + _currentDIBO = ibo; + } + } + + inline void unbindDrawIndirectBufferObject() + { + if (!_currentDIBO) return; + _glBindBuffer(GL_DRAW_INDIRECT_BUFFER,0); + _currentDIBO = 0; + } + void setCurrentVertexArrayObject(GLuint vao) { _currentVAO = vao; } GLuint getCurrentVertexArrayObject() const { return _currentVAO; } @@ -1259,6 +1280,7 @@ class OSG_EXPORT State : public Referenced unsigned int _currentActiveTextureUnit; unsigned int _currentClientActiveTextureUnit; GLBufferObject* _currentPBO; + GLBufferObject* _currentDIBO; GLuint _currentVAO; diff --git a/src/osg/PrimitiveSetIndirect.cpp b/src/osg/PrimitiveSetIndirect.cpp index add1c98a4..796769392 100644 --- a/src/osg/PrimitiveSetIndirect.cpp +++ b/src/osg/PrimitiveSetIndirect.cpp @@ -64,7 +64,7 @@ unsigned int DrawElementsIndirectUShort::getNumPrimitives() const{return getNumP void DrawElementsIndirectUInt::draw(State& state, bool useVertexBufferObjects) const { GLBufferObject* dibo = _indirectCommandArray->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); - state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); + state.bindDrawIndirectBufferObject(dibo); GLenum mode = _mode; #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) @@ -122,7 +122,7 @@ void DrawElementsIndirectUInt::accept(PrimitiveIndexFunctor& functor) const } void DrawElementsIndirectUByte::draw(State& state, bool useVertexBufferObjects) const { GLBufferObject* dibo = _indirectCommandArray->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); - state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); + state.bindDrawIndirectBufferObject(dibo); GLenum mode = _mode; #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) @@ -176,7 +176,7 @@ void DrawElementsIndirectUByte::accept(PrimitiveIndexFunctor& functor) const } void DrawElementsIndirectUShort::draw(State& state, bool useVertexBufferObjects) const { GLBufferObject* dibo = _indirectCommandArray->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); - state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); + state.bindDrawIndirectBufferObject(dibo); GLenum mode = _mode; #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) @@ -282,7 +282,7 @@ void MultiDrawElementsIndirectUByte::draw(State& state, bool useVertexBufferObje { GLBufferObject* dibo = _indirectCommandArray->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); - state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); + state.bindDrawIndirectBufferObject(dibo); GLenum mode = _mode; #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN; @@ -340,7 +340,7 @@ MultiDrawElementsIndirectUShort::~MultiDrawElementsIndirectUShort() void MultiDrawElementsIndirectUShort::draw(State& state, bool useVertexBufferObjects) const { GLBufferObject* dibo = _indirectCommandArray->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); - state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); + state.bindDrawIndirectBufferObject(dibo); GLenum mode = _mode; #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) @@ -397,7 +397,7 @@ MultiDrawElementsIndirectUInt::~MultiDrawElementsIndirectUInt() void MultiDrawElementsIndirectUInt::draw(State& state, bool useVertexBufferObjects) const { GLBufferObject* dibo = _indirectCommandArray->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); - state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); + state.bindDrawIndirectBufferObject(dibo); GLenum mode = _mode; #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN; @@ -450,7 +450,7 @@ void MultiDrawElementsIndirectUInt::accept(PrimitiveIndexFunctor& functor) const void DrawArraysIndirect::draw(osg::State& state, bool) const { GLBufferObject* dibo = _indirectCommandArray->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); - state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); + state.bindDrawIndirectBufferObject(dibo); GLExtensions* ext = state.get(); @@ -517,7 +517,7 @@ unsigned int DrawArraysIndirect::getNumPrimitives() const void MultiDrawArraysIndirect::draw(osg::State& state, bool) const { GLBufferObject* dibo = _indirectCommandArray->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); - state.get()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID()); + state.bindDrawIndirectBufferObject(dibo); GLExtensions* ext = state.get(); diff --git a/src/osg/State.cpp b/src/osg/State.cpp index e8c2446ca..c652d4cc6 100644 --- a/src/osg/State.cpp +++ b/src/osg/State.cpp @@ -89,6 +89,7 @@ State::State(): _currentClientActiveTextureUnit=0; _currentPBO = 0; + _currentDIBO = 0; _currentVAO = 0; _isSecondaryColorSupported = false; From 104b2dfc7217fe2d895d19af63cdddd339e5fb14 Mon Sep 17 00:00:00 2001 From: mp3butcher Date: Thu, 27 Jul 2017 12:00:41 +0200 Subject: [PATCH 07/19] Promote PrimitiveSetIndirect's VBO to a target explicited DIBO (in order to benefit from BOSet queue management) --- examples/osggpucull/osggpucull.cpp | 2 +- include/osg/BufferObject | 22 +++++++++++++++ include/osg/PrimitiveSetIndirect | 4 +-- include/osg/State | 2 +- src/osg/BufferObject.cpp | 44 ++++++++++++++++++++++++++++++ 5 files changed, 70 insertions(+), 4 deletions(-) diff --git a/examples/osggpucull/osggpucull.cpp b/examples/osggpucull/osggpucull.cpp index 194a9a946..0c00bbef3 100644 --- a/examples/osggpucull/osggpucull.cpp +++ b/examples/osggpucull/osggpucull.cpp @@ -189,7 +189,7 @@ struct IndirectTarget } void endRegister(unsigned int index, unsigned int rowsPerInstance, GLenum pixelFormat, GLenum type, GLint internalFormat, bool useMultiDrawArraysIndirect ) { - osg::VertexBufferObject * indirectCommandbuffer=new osg::VertexBufferObject(); + osg::DrawIndirectBufferObject * indirectCommandbuffer = new osg::DrawIndirectBufferObject(); indirectCommandbuffer->setUsage(GL_DYNAMIC_DRAW); indirectCommands->setBufferObject(indirectCommandbuffer); diff --git a/include/osg/BufferObject b/include/osg/BufferObject index c542e4121..37ae19a55 100644 --- a/include/osg/BufferObject +++ b/include/osg/BufferObject @@ -635,6 +635,28 @@ class OSG_EXPORT ElementBufferObject : public BufferObject virtual ~ElementBufferObject(); }; +class OSG_EXPORT DrawIndirectBufferObject : public BufferObject +{ + public: + + DrawIndirectBufferObject(); + + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ + DrawIndirectBufferObject(const DrawIndirectBufferObject& vbo,const CopyOp& copyop=CopyOp::SHALLOW_COPY); + + META_Object(osg,DrawIndirectBufferObject); + + unsigned int addArray(osg::Array* array); + void removeArray(osg::Array* array); + + void setArray(unsigned int i, Array* array); + Array* getArray(unsigned int i); + const Array* getArray(unsigned int i) const; + + protected: + virtual ~DrawIndirectBufferObject(); +}; + class Image; class OSG_EXPORT PixelBufferObject : public BufferObject { diff --git a/include/osg/PrimitiveSetIndirect b/include/osg/PrimitiveSetIndirect index d8771a781..6c8567c83 100644 --- a/include/osg/PrimitiveSetIndirect +++ b/include/osg/PrimitiveSetIndirect @@ -148,7 +148,7 @@ public: inline void setIndirectCommandArray(IndirectCommandDrawElements*idc) { _indirectCommandArray = idc; if(!_indirectCommandArray->getBufferObject()) - _indirectCommandArray->setBufferObject(new osg::VertexBufferObject()); + _indirectCommandArray->setBufferObject(new osg::DrawIndirectBufferObject()); } /// get command array of this indirect primitive set inline IndirectCommandDrawElements* getIndirectCommandArray() { return _indirectCommandArray; } @@ -656,7 +656,7 @@ public: inline void setIndirectCommandArray(IndirectCommandDrawArrays*idc) { _indirectCommandArray = idc; if(!_indirectCommandArray->getBufferObject()) - _indirectCommandArray->setBufferObject(new osg::VertexBufferObject()); + _indirectCommandArray->setBufferObject(new osg::DrawIndirectBufferObject()); } inline const IndirectCommandDrawArrays* getIndirectCommandArray() const { return _indirectCommandArray; diff --git a/include/osg/State b/include/osg/State index 28a2880c4..2d363105f 100644 --- a/include/osg/State +++ b/include/osg/State @@ -600,7 +600,7 @@ class OSG_EXPORT State : public Referenced } else if (ibo != _currentDIBO) { - _glBindBuffer(GL_DRAW_INDIRECT_BUFFER, ibo->getGLObjectID()); + ibo->bindBuffer(); _currentDIBO = ibo; } } diff --git a/src/osg/BufferObject.cpp b/src/osg/BufferObject.cpp index 9e2199911..46fa4e869 100644 --- a/src/osg/BufferObject.cpp +++ b/src/osg/BufferObject.cpp @@ -1358,6 +1358,50 @@ const DrawElements* ElementBufferObject::getDrawElements(unsigned int i) const return dynamic_cast(getBufferData(i)); } +////////////////////////////////////////////////////////////////////////////////// +// +// DrawIndirectBufferObject +// +DrawIndirectBufferObject::DrawIndirectBufferObject() +{ + setTarget(GL_DRAW_INDIRECT_BUFFER); + setUsage(GL_STATIC_DRAW_ARB); +// setUsage(GL_STREAM_DRAW_ARB); +} + +DrawIndirectBufferObject::DrawIndirectBufferObject(const DrawIndirectBufferObject& vbo,const CopyOp& copyop): + BufferObject(vbo,copyop) +{ +} + +DrawIndirectBufferObject::~DrawIndirectBufferObject() +{ +} + +unsigned int DrawIndirectBufferObject::addArray(osg::Array* array) +{ + return addBufferData(array); +} + +void DrawIndirectBufferObject::removeArray(osg::Array* array) +{ + removeBufferData(array); +} + +void DrawIndirectBufferObject::setArray(unsigned int i, Array* array) +{ + setBufferData(i,array); +} + +Array* DrawIndirectBufferObject::getArray(unsigned int i) +{ + return dynamic_cast(getBufferData(i)); +} + +const Array* DrawIndirectBufferObject::getArray(unsigned int i) const +{ + return dynamic_cast(getBufferData(i)); +} ////////////////////////////////////////////////////////////////////////////////// // From a45c4c8f3986f0c7a2b0680f89d5f84bc548894b Mon Sep 17 00:00:00 2001 From: mp3butcher Date: Thu, 27 Jul 2017 12:27:55 +0200 Subject: [PATCH 08/19] set DIBO of the drawcommandarray directly in their interface constructor it makes osggpu use case lighter + drawcommandarray can't exist without a BO --- examples/osggpucull/osggpucull.cpp | 6 ++---- include/osg/PrimitiveSetIndirect | 14 ++++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/osggpucull/osggpucull.cpp b/examples/osggpucull/osggpucull.cpp index 0c00bbef3..de21f0280 100644 --- a/examples/osggpucull/osggpucull.cpp +++ b/examples/osggpucull/osggpucull.cpp @@ -181,18 +181,16 @@ struct IndirectTarget : maxTargetQuantity(0) { indirectCommands = new osg::DefaultIndirectCommandDrawArrays; + indirectCommands->getBufferObject()->setUsage(GL_DYNAMIC_DRAW); } IndirectTarget( AggregateGeometryVisitor* agv, osg::Program* program ) : geometryAggregator(agv), drawProgram(program), maxTargetQuantity(0) { indirectCommands = new osg::DefaultIndirectCommandDrawArrays; + indirectCommands->getBufferObject()->setUsage(GL_DYNAMIC_DRAW); } void endRegister(unsigned int index, unsigned int rowsPerInstance, GLenum pixelFormat, GLenum type, GLint internalFormat, bool useMultiDrawArraysIndirect ) { - osg::DrawIndirectBufferObject * indirectCommandbuffer = new osg::DrawIndirectBufferObject(); - indirectCommandbuffer->setUsage(GL_DYNAMIC_DRAW); - indirectCommands->setBufferObject(indirectCommandbuffer); - indirectCommandTextureBuffer = new osg::TextureBuffer(indirectCommands); indirectCommandTextureBuffer->setInternalFormat( GL_R32I ); indirectCommandTextureBuffer->bindToImageUnit(index, osg::Texture::READ_WRITE); diff --git a/include/osg/PrimitiveSetIndirect b/include/osg/PrimitiveSetIndirect index 6c8567c83..eae239076 100644 --- a/include/osg/PrimitiveSetIndirect +++ b/include/osg/PrimitiveSetIndirect @@ -25,7 +25,7 @@ namespace osg { class OSG_EXPORT IndirectCommandDrawArrays: public BufferData { public: - IndirectCommandDrawArrays():BufferData(){} + IndirectCommandDrawArrays():BufferData(){setBufferObject(new DrawIndirectBufferObject());} IndirectCommandDrawArrays(const IndirectCommandDrawArrays& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/) :BufferData(copy, copyop){ } @@ -40,7 +40,7 @@ public: class OSG_EXPORT IndirectCommandDrawElements: public BufferData { public: - IndirectCommandDrawElements():BufferData(){} + IndirectCommandDrawElements():BufferData(){setBufferObject(new DrawIndirectBufferObject());} IndirectCommandDrawElements(const IndirectCommandDrawElements& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/) :BufferData(copy, copyop){} @@ -147,8 +147,9 @@ public: /// set command array of this indirect primitive set inline void setIndirectCommandArray(IndirectCommandDrawElements*idc) { _indirectCommandArray = idc; - if(!_indirectCommandArray->getBufferObject()) - _indirectCommandArray->setBufferObject(new osg::DrawIndirectBufferObject()); + //ensure bo of idc is of the correct type + if(!dynamic_cast(_indirectCommandArray->getBufferObject())) + _indirectCommandArray->setBufferObject(new DrawIndirectBufferObject()); } /// get command array of this indirect primitive set inline IndirectCommandDrawElements* getIndirectCommandArray() { return _indirectCommandArray; } @@ -655,8 +656,9 @@ public: inline void setIndirectCommandArray(IndirectCommandDrawArrays*idc) { _indirectCommandArray = idc; - if(!_indirectCommandArray->getBufferObject()) - _indirectCommandArray->setBufferObject(new osg::DrawIndirectBufferObject()); + //ensure bo of idc is of the correct type + if(!dynamic_cast(_indirectCommandArray->getBufferObject())) + _indirectCommandArray->setBufferObject(new DrawIndirectBufferObject()); } inline const IndirectCommandDrawArrays* getIndirectCommandArray() const { return _indirectCommandArray; From 5a946e218f552dd967c5ae12bbb42fa8518eeec8 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 28 Jul 2017 13:30:36 +0100 Subject: [PATCH 09/19] Improved the readability and consistency with the rest of the OSG by inserting/removing spaces and line spacing. --- include/osg/PrimitiveSetIndirect | 544 ++++++++++++------------------- 1 file changed, 202 insertions(+), 342 deletions(-) diff --git a/include/osg/PrimitiveSetIndirect b/include/osg/PrimitiveSetIndirect index eae239076..e18d17e1e 100644 --- a/include/osg/PrimitiveSetIndirect +++ b/include/osg/PrimitiveSetIndirect @@ -21,13 +21,15 @@ namespace osg { + ///common interface for IndirectCommandDrawArrayss class OSG_EXPORT IndirectCommandDrawArrays: public BufferData { public: - IndirectCommandDrawArrays():BufferData(){setBufferObject(new DrawIndirectBufferObject());} - IndirectCommandDrawArrays(const IndirectCommandDrawArrays& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/) - :BufferData(copy, copyop){ } + IndirectCommandDrawArrays() : BufferData() { setBufferObject(new DrawIndirectBufferObject()); } + + IndirectCommandDrawArrays(const IndirectCommandDrawArrays& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/) : + BufferData(copy, copyop) {} virtual unsigned int & count(const unsigned int&index)=0; virtual unsigned int & instanceCount(const unsigned int&index)=0; @@ -37,12 +39,14 @@ public: virtual unsigned int getElementSize() const = 0; virtual unsigned int getNumElements() const = 0; }; + class OSG_EXPORT IndirectCommandDrawElements: public BufferData { public: - IndirectCommandDrawElements():BufferData(){setBufferObject(new DrawIndirectBufferObject());} + IndirectCommandDrawElements() : BufferData() { setBufferObject(new DrawIndirectBufferObject()); } + IndirectCommandDrawElements(const IndirectCommandDrawElements& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/) - :BufferData(copy, copyop){} + : BufferData(copy, copyop) {} virtual unsigned int & count(const unsigned int&index)=0; virtual unsigned int & instanceCount(const unsigned int&index)=0; @@ -52,15 +56,16 @@ public: virtual unsigned int getElementSize()const = 0; virtual unsigned int getNumElements() const = 0; - }; /// DrawArraysCommand -struct DrawArraysIndirectCommand { - DrawArraysIndirectCommand(unsigned int pcount = 0, unsigned int pinstanceCount = 0, unsigned int pfirst = 0, unsigned int pbaseInstance = 0) - :count(pcount), instanceCount(pinstanceCount), first(pfirst), baseInstance(pbaseInstance){}; +struct DrawArraysIndirectCommand +{ + DrawArraysIndirectCommand(unsigned int pcount = 0, unsigned int pinstanceCount = 0, unsigned int pfirst = 0, unsigned int pbaseInstance = 0) : + count(pcount), instanceCount(pinstanceCount), first(pfirst), baseInstance(pbaseInstance) {} + unsigned int count; unsigned int instanceCount; unsigned int first; @@ -74,30 +79,28 @@ class OSG_EXPORT DefaultIndirectCommandDrawArrays: public IndirectCommandDrawArr public: META_Object(osg,DefaultIndirectCommandDrawArrays) - DefaultIndirectCommandDrawArrays():IndirectCommandDrawArrays(), MixinVector() {} - DefaultIndirectCommandDrawArrays(const DefaultIndirectCommandDrawArrays& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/) - :IndirectCommandDrawArrays(copy, copyop),MixinVector() {} + DefaultIndirectCommandDrawArrays() : IndirectCommandDrawArrays(), MixinVector() {} + DefaultIndirectCommandDrawArrays(const DefaultIndirectCommandDrawArrays& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/) : + IndirectCommandDrawArrays(copy, copyop),MixinVector() {} - virtual const GLvoid* getDataPointer() const { - return empty()?0:&front(); - } - virtual unsigned int getTotalDataSize() const { - return 16u*static_cast(size()); - } - virtual unsigned int getElementSize()const {return 16u;}; - virtual unsigned int & count(const unsigned int&index){return at(index).count;} - virtual unsigned int & instanceCount(const unsigned int&index){return at(index).instanceCount;} - virtual unsigned int & first(const unsigned int&index){return at(index).first;} - virtual unsigned int & baseInstance(const unsigned int&index){return at(index).baseInstance;} - virtual unsigned int getNumElements() const {return static_cast(size());} + virtual const GLvoid* getDataPointer() const { return empty()?0:&front(); } + virtual unsigned int getTotalDataSize() const { return 16u*static_cast(size()); } + virtual unsigned int getElementSize()const { return 16u; }; + virtual unsigned int & count(const unsigned int&index) { return at(index).count; } + virtual unsigned int & instanceCount(const unsigned int&index) { return at(index).instanceCount; } + virtual unsigned int & first(const unsigned int&index) { return at(index).first; } + virtual unsigned int & baseInstance(const unsigned int&index) { return at(index).baseInstance; } + virtual unsigned int getNumElements() const { return static_cast(size()); } }; /// default implementation of IndirectCommandDrawElements /// DrawElementsCommand -struct DrawElementsIndirectCommand{ - DrawElementsIndirectCommand(unsigned int pcount = 0, unsigned int pinstanceCount = 0, unsigned int pfirstIndex = 0, unsigned int pbaseVertex = 0, unsigned int pbaseInstance = 0) - :count(pcount), instanceCount(pinstanceCount), firstIndex(pfirstIndex), baseVertex(pbaseVertex), baseInstance(pbaseInstance){}; +struct DrawElementsIndirectCommand +{ + DrawElementsIndirectCommand(unsigned int pcount = 0, unsigned int pinstanceCount = 0, unsigned int pfirstIndex = 0, unsigned int pbaseVertex = 0, unsigned int pbaseInstance = 0) : + count(pcount), instanceCount(pinstanceCount), firstIndex(pfirstIndex), baseVertex(pbaseVertex), baseInstance(pbaseInstance) {} + unsigned int count; unsigned int instanceCount; unsigned int firstIndex; @@ -110,23 +113,22 @@ class OSG_EXPORT DefaultIndirectCommandDrawElements: public IndirectCommandDrawE { public: META_Object(osg,DefaultIndirectCommandDrawElements) - DefaultIndirectCommandDrawElements():IndirectCommandDrawElements(), MixinVector() {} - DefaultIndirectCommandDrawElements(const DefaultIndirectCommandDrawElements& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/) - :IndirectCommandDrawElements(copy, copyop), MixinVector(){} - virtual const GLvoid* getDataPointer() const { - return empty()?0:&front(); - } - virtual unsigned int getTotalDataSize() const { - return 20u*static_cast(size()); - } - virtual unsigned int getElementSize()const {return 20u;}; - virtual unsigned int & count(const unsigned int&index){return at(index).count;} - virtual unsigned int & instanceCount(const unsigned int&index){return at(index).instanceCount;} - virtual unsigned int & firstIndex(const unsigned int&index){return at(index).firstIndex;} - virtual unsigned int & baseVertex(const unsigned int&index){return at(index).baseVertex;} - virtual unsigned int & baseInstance(const unsigned int&index){return at(index).baseInstance;} - virtual unsigned int getNumElements() const {return static_cast(size());} + DefaultIndirectCommandDrawElements() : IndirectCommandDrawElements(), MixinVector() {} + + DefaultIndirectCommandDrawElements(const DefaultIndirectCommandDrawElements& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/) : + IndirectCommandDrawElements(copy, copyop), MixinVector() {} + + virtual const GLvoid* getDataPointer() const { return empty()?0:&front(); } + virtual unsigned int getTotalDataSize() const { return 20u*static_cast(size()); } + + virtual unsigned int getElementSize()const { return 20u; }; + virtual unsigned int & count(const unsigned int&index) { return at(index).count; } + virtual unsigned int & instanceCount(const unsigned int&index) { return at(index).instanceCount; } + virtual unsigned int & firstIndex(const unsigned int&index) { return at(index).firstIndex; } + virtual unsigned int & baseVertex(const unsigned int&index) { return at(index).baseVertex; } + virtual unsigned int & baseInstance(const unsigned int&index) { return at(index).baseInstance; } + virtual unsigned int getNumElements() const { return static_cast(size()); } }; /////////////////////////////////////////////////////////////////////////////////////// @@ -136,41 +138,40 @@ class OSG_EXPORT DrawElementsIndirect : public DrawElements { public: - DrawElementsIndirect(Type primType=PrimitiveType, GLenum mode = 0,unsigned int firstCommand = 0, GLsizei stride = 0): - DrawElements(primType,mode, 0),_firstCommand(firstCommand),_stride(stride){setIndirectCommandArray(new DefaultIndirectCommandDrawElements());} + DrawElementsIndirect(Type primType=PrimitiveType, GLenum mode = 0,unsigned int firstCommand = 0, GLsizei stride = 0) : + DrawElements(primType,mode, 0),_firstCommand(firstCommand),_stride(stride) { setIndirectCommandArray(new DefaultIndirectCommandDrawElements()); } - DrawElementsIndirect(const DrawElementsIndirect& rhs,const CopyOp& copyop=CopyOp::SHALLOW_COPY): - DrawElements(rhs,copyop),_firstCommand(rhs._firstCommand), _stride(rhs._stride) { - _indirectCommandArray=(DefaultIndirectCommandDrawElements*)copyop(rhs._indirectCommandArray.get()); - } + DrawElementsIndirect(const DrawElementsIndirect& rhs,const CopyOp& copyop=CopyOp::SHALLOW_COPY) : + DrawElements(rhs,copyop),_firstCommand(rhs._firstCommand), _stride(rhs._stride) { _indirectCommandArray=(DefaultIndirectCommandDrawElements*)copyop(rhs._indirectCommandArray.get()); } /// set command array of this indirect primitive set - inline void setIndirectCommandArray(IndirectCommandDrawElements*idc) { + inline void setIndirectCommandArray(IndirectCommandDrawElements*idc) + { _indirectCommandArray = idc; //ensure bo of idc is of the correct type if(!dynamic_cast(_indirectCommandArray->getBufferObject())) _indirectCommandArray->setBufferObject(new DrawIndirectBufferObject()); } + /// get command array of this indirect primitive set - inline IndirectCommandDrawElements* getIndirectCommandArray() { return _indirectCommandArray; } - inline const IndirectCommandDrawElements* getIndirectCommandArray() const { return _indirectCommandArray; } + inline IndirectCommandDrawElements* getIndirectCommandArray() { return _indirectCommandArray; } + inline const IndirectCommandDrawElements* getIndirectCommandArray() const { return _indirectCommandArray; } ///Further methods are for advanced DI when you plan to use your own IndirectCommandElement (stride) ///or if you want to draw a particular command index of the IndirectCommandElement(FirstCommandToDraw) /// set offset of the first command to draw in the IndirectCommandDrawArrays - inline void setFirstCommandToDraw( unsigned int i) { _firstCommand = i; } + inline void setFirstCommandToDraw( unsigned int i) { _firstCommand = i; } + /// get offset of the first command in the IndirectCommandDrawArrays - inline unsigned int getFirstCommandToDraw() const { return _firstCommand; } + inline unsigned int getFirstCommandToDraw() const { return _firstCommand; } /// stride (to set if you use custom CommandArray) - inline void setStride( GLsizei i) { - _stride=i; - } + inline void setStride( GLsizei i) { _stride=i; } + /// stride (to set if you use custom CommandArray) - inline GLsizei getStride() const { - return _stride; - } + inline GLsizei getStride() const { return _stride; } + virtual unsigned int getNumPrimitives() const=0; protected: @@ -179,8 +180,8 @@ protected: unsigned int _firstCommand; GLsizei _stride; ref_ptr _indirectCommandArray; - }; + /////////////////////////////////////////////////////////////////////////////////////// /// \brief The DrawElementsIndirectUByte PrimitiveSet /// @@ -190,10 +191,10 @@ public: typedef VectorGLubyte vector_type; - DrawElementsIndirectUByte(GLenum mode = 0,unsigned int firstCommand = 0, GLsizei stride = 0): + DrawElementsIndirectUByte(GLenum mode = 0,unsigned int firstCommand = 0, GLsizei stride = 0) : DrawElementsIndirect(DrawElementsUByteIndirectPrimitiveType,mode,firstCommand,stride) {} - DrawElementsIndirectUByte(const DrawElementsIndirectUByte& array, const CopyOp& copyop=CopyOp::SHALLOW_COPY): + DrawElementsIndirectUByte(const DrawElementsIndirectUByte& array, const CopyOp& copyop=CopyOp::SHALLOW_COPY) : DrawElementsIndirect(array,copyop), vector_type(array) {} @@ -214,64 +215,36 @@ public: DrawElementsIndirect(MultiDrawElementsUByteIndirectPrimitiveType,mode), vector_type(no) {} - virtual Object* cloneType() const { - return new DrawElementsIndirectUByte(); - } - virtual Object* clone(const CopyOp& copyop) const { - return new DrawElementsIndirectUByte(*this,copyop); - } - virtual bool isSameKindAs(const Object* obj) const { - return dynamic_cast(obj)!=NULL; - } - virtual const char* libraryName() const { - return "osg"; - } - virtual const char* className() const { - return "DrawElementsIndirectUByte"; - } + virtual Object* cloneType() const { return new DrawElementsIndirectUByte(); } + virtual Object* clone(const CopyOp& copyop) const { return new DrawElementsIndirectUByte(*this,copyop); } + virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } + virtual const char* libraryName() const { return "osg"; } + virtual const char* className() const { return "DrawElementsIndirectUByte"; } - virtual const GLvoid* getDataPointer() const { - return empty()?0:&front(); - } - virtual unsigned int getTotalDataSize() const { - return static_cast(size()); - } - virtual bool supportsBufferObject() const { - return false; - } + virtual const GLvoid* getDataPointer() const { return empty()?0:&front(); } + virtual unsigned int getTotalDataSize() const { return static_cast(size()); } + virtual bool supportsBufferObject() const { return false; } virtual void draw(State& state, bool useVertexBufferObjects) const; virtual void accept(PrimitiveFunctor& functor) const; virtual void accept(PrimitiveIndexFunctor& functor) const; - virtual unsigned int getNumIndices() const { - return static_cast(size()); - } - virtual unsigned int index(unsigned int pos) const { - return (*this)[pos]; - } + virtual unsigned int getNumIndices() const { return static_cast(size()); } + virtual unsigned int index(unsigned int pos) const { return (*this)[pos]; } virtual void offsetIndices(int offset); - virtual GLenum getDataType() { - return GL_UNSIGNED_BYTE; - } - virtual void resizeElements(unsigned int numIndices) { - resize(numIndices); - } - virtual void reserveElements(unsigned int numIndices) { - reserve(numIndices); - } - virtual void setElement(unsigned int i, unsigned int v) { - (*this)[i] = v; - } - virtual unsigned int getElement(unsigned int i) { - return (*this)[i]; - } - virtual void addElement(unsigned int v) { - push_back(GLubyte(v)); - } + virtual GLenum getDataType() { return GL_UNSIGNED_BYTE; } + + virtual void resizeElements(unsigned int numIndices) { resize(numIndices); } + virtual void reserveElements(unsigned int numIndices) { reserve(numIndices); } + + virtual void setElement(unsigned int i, unsigned int v) { (*this)[i] = v; } + virtual unsigned int getElement(unsigned int i) { return (*this)[i]; } + + virtual void addElement(unsigned int v) { push_back(GLubyte(v)); } virtual unsigned int getNumPrimitives() const; + protected: virtual ~DrawElementsIndirectUByte(); @@ -287,10 +260,10 @@ public: typedef VectorGLushort vector_type; - DrawElementsIndirectUShort(GLenum mode = 0,unsigned int firstCommand = 0, GLsizei stride = 0): + DrawElementsIndirectUShort(GLenum mode = 0,unsigned int firstCommand = 0, GLsizei stride = 0) : DrawElementsIndirect(DrawElementsUShortIndirectPrimitiveType,mode,firstCommand,stride) {} - DrawElementsIndirectUShort(const DrawElementsIndirectUShort& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY): + DrawElementsIndirectUShort(const DrawElementsIndirectUShort& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY) : DrawElementsIndirect(array,copyop), vector_type(array) {} @@ -316,64 +289,35 @@ public: DrawElementsIndirect(MultiDrawElementsUShortIndirectPrimitiveType,mode), vector_type(first,last) {} - virtual Object* cloneType() const { - return new DrawElementsIndirectUShort(); - } - virtual Object* clone(const CopyOp& copyop) const { - return new DrawElementsIndirectUShort(*this,copyop); - } - virtual bool isSameKindAs(const Object* obj) const { - return dynamic_cast(obj)!=NULL; - } - virtual const char* libraryName() const { - return "osg"; - } - virtual const char* className() const { - return "DrawElementsIndirectUShort"; - } + virtual Object* cloneType() const { return new DrawElementsIndirectUShort(); } + virtual Object* clone(const CopyOp& copyop) const { return new DrawElementsIndirectUShort(*this,copyop); } + virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } + virtual const char* libraryName() const { return "osg"; } + virtual const char* className() const { return "DrawElementsIndirectUShort"; } - virtual const GLvoid* getDataPointer() const { - return empty()?0:&front(); - } - virtual unsigned int getTotalDataSize() const { - return 2u*static_cast(size()); - } - virtual bool supportsBufferObject() const { - return false; - } + virtual const GLvoid* getDataPointer() const { return empty()?0:&front(); } + virtual unsigned int getTotalDataSize() const { return 2u*static_cast(size()); } + virtual bool supportsBufferObject() const { return false; } virtual void draw(State& state, bool useVertexBufferObjects) const; virtual void accept(PrimitiveFunctor& functor) const; virtual void accept(PrimitiveIndexFunctor& functor) const; - virtual unsigned int getNumIndices() const { - return static_cast(size()); - } - virtual unsigned int index(unsigned int pos) const { - return (*this)[pos]; - } + virtual unsigned int getNumIndices() const { return static_cast(size()); } + virtual unsigned int index(unsigned int pos) const { return (*this)[pos]; } virtual void offsetIndices(int offset); - virtual GLenum getDataType() { - return GL_UNSIGNED_SHORT; - } - virtual void resizeElements(unsigned int numIndices) { - resize(numIndices); - } - virtual void reserveElements(unsigned int numIndices) { - reserve(numIndices); - } - virtual void setElement(unsigned int i, unsigned int v) { - (*this)[i] = v; - } - virtual unsigned int getElement(unsigned int i) { - return (*this)[i]; - } - virtual void addElement(unsigned int v) { - push_back(GLushort(v)); - } + virtual GLenum getDataType() { return GL_UNSIGNED_SHORT; } + virtual void resizeElements(unsigned int numIndices) { resize(numIndices); } + virtual void reserveElements(unsigned int numIndices) { reserve(numIndices); } + + virtual void setElement(unsigned int i, unsigned int v) { (*this)[i] = v; } + virtual unsigned int getElement(unsigned int i) { return (*this)[i]; } + + virtual void addElement(unsigned int v) { push_back(GLushort(v)); } virtual unsigned int getNumPrimitives() const; + protected: virtual ~DrawElementsIndirectUShort(); @@ -388,10 +332,10 @@ public: typedef VectorGLuint vector_type; - DrawElementsIndirectUInt(GLenum mode = 0,unsigned int firstCommand = 0, GLsizei stride = 0): + DrawElementsIndirectUInt(GLenum mode = 0,unsigned int firstCommand = 0, GLsizei stride = 0) : DrawElementsIndirect(DrawElementsUIntIndirectPrimitiveType,mode,firstCommand,stride) {} - DrawElementsIndirectUInt(const DrawElementsIndirectUInt& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY): + DrawElementsIndirectUInt(const DrawElementsIndirectUInt& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY) : DrawElementsIndirect(array,copyop), vector_type(array) {} @@ -417,91 +361,56 @@ public: DrawElementsIndirect(MultiDrawElementsUIntIndirectPrimitiveType,mode), vector_type(first,last) {} - virtual Object* cloneType() const { - return new DrawElementsIndirectUInt(); - } - virtual Object* clone(const CopyOp& copyop) const { - return new DrawElementsIndirectUInt(*this,copyop); - } - virtual bool isSameKindAs(const Object* obj) const { - return dynamic_cast(obj)!=NULL; - } - virtual const char* libraryName() const { - return "osg"; - } - virtual const char* className() const { - return "DrawElementsIndirectUInt"; - } + virtual Object* cloneType() const { return new DrawElementsIndirectUInt(); } + virtual Object* clone(const CopyOp& copyop) const { return new DrawElementsIndirectUInt(*this,copyop); } + virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast(obj)!=NULL; } + virtual const char* libraryName() const { return "osg"; } + virtual const char* className() const { return "DrawElementsIndirectUInt"; } - virtual const GLvoid* getDataPointer() const { - return empty()?0:&front(); - } - virtual unsigned int getTotalDataSize() const { - return 4u*static_cast(size()); - } - virtual bool supportsBufferObject() const { - return false; - } + virtual const GLvoid* getDataPointer() const { return empty()?0:&front(); } + virtual unsigned int getTotalDataSize() const { return 4u*static_cast(size()); } + virtual bool supportsBufferObject() const { return false; } virtual void draw(State& state, bool useVertexBufferObjects) const; virtual void accept(PrimitiveFunctor& functor) const; virtual void accept(PrimitiveIndexFunctor& functor) const; - virtual unsigned int getNumIndices() const { - return static_cast(size()); - } - virtual unsigned int index(unsigned int pos) const { - return (*this)[pos]; - } + virtual unsigned int getNumIndices() const { return static_cast(size()); } + virtual unsigned int index(unsigned int pos) const { return (*this)[pos]; } virtual void offsetIndices(int offset); - virtual GLenum getDataType() { - return GL_UNSIGNED_INT; - } - virtual void resizeElements(unsigned int numIndices) { - resize(numIndices); - } - virtual void reserveElements(unsigned int numIndices) { - reserve(numIndices); - } - virtual void setElement(unsigned int i, unsigned int v) { - (*this)[i] = v; - } - virtual unsigned int getElement(unsigned int i) { - return (*this)[i]; - } - virtual void addElement(unsigned int v) { - push_back(GLuint(v)); - } + virtual GLenum getDataType() { return GL_UNSIGNED_INT; } + virtual void resizeElements(unsigned int numIndices) { resize(numIndices); } + virtual void reserveElements(unsigned int numIndices) { reserve(numIndices); } + virtual void setElement(unsigned int i, unsigned int v) { (*this)[i] = v; } + virtual unsigned int getElement(unsigned int i) { return (*this)[i]; } + virtual void addElement(unsigned int v) { push_back(GLuint(v)); } virtual unsigned int getNumPrimitives() const; + protected: virtual ~DrawElementsIndirectUInt(); }; + /////////////////////////////////////////////////////////////////////////////////////// /// \brief The MultiDrawElementsIndirect PrimitiveSets /// class OSG_EXPORT MultiDrawElementsIndirectUShort : public DrawElementsIndirectUShort { public: - MultiDrawElementsIndirectUShort(GLenum mode = 0,unsigned int firstCommand = 0,unsigned int commandcount = 0, GLsizei stride = 0): - DrawElementsIndirectUShort(mode,firstCommand,stride),_count(commandcount){_primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType));} - MultiDrawElementsIndirectUShort(const MultiDrawElementsIndirectUShort& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY): + MultiDrawElementsIndirectUShort(GLenum mode = 0,unsigned int firstCommand = 0,unsigned int commandcount = 0, GLsizei stride = 0) : + DrawElementsIndirectUShort(mode,firstCommand,stride),_count(commandcount) { _primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType)); } + + MultiDrawElementsIndirectUShort(const MultiDrawElementsIndirectUShort& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY) : DrawElementsIndirectUShort(mdi,copyop),_count(mdi._count) {} - virtual osg::Object* cloneType() const { - return new MultiDrawElementsIndirectUShort(); - } - virtual osg::Object* clone(const osg::CopyOp& copyop) const { - return new MultiDrawElementsIndirectUShort(*this,copyop); - } - virtual bool isSameKindAs(const osg::Object* obj) const { - return dynamic_cast(obj)!=NULL; - } - virtual const char* className() const { - return "MultiDrawElementsIndirectUShort"; - } + + virtual osg::Object* cloneType() const { return new MultiDrawElementsIndirectUShort(); } + virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new MultiDrawElementsIndirectUShort(*this,copyop); } + virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } + virtual const char* className() const { return "MultiDrawElementsIndirectUShort"; } + virtual void draw(State& state, bool useVertexBufferObjects) const; virtual void accept(PrimitiveFunctor& functor) const; virtual void accept(PrimitiveIndexFunctor& functor) const; @@ -510,13 +419,10 @@ public: ///if you want to draw a subset of the IndirectCommandElement(FirstCommandToDraw,NumCommandsToDraw) /// count of Indirect Command to execute - inline void setNumCommandsToDraw( unsigned int i) { - _count=i; - } + inline void setNumCommandsToDraw( unsigned int i) { _count=i; } /// count of Indirect Command to execute - inline unsigned int getNumCommandsToDraw()const { - return _count; - } + inline unsigned int getNumCommandsToDraw()const { return _count; } + protected: unsigned int _count; virtual ~MultiDrawElementsIndirectUShort(); @@ -525,73 +431,61 @@ protected: class OSG_EXPORT MultiDrawElementsIndirectUByte : public DrawElementsIndirectUByte { public: - MultiDrawElementsIndirectUByte(GLenum mode = 0,unsigned int firstCommand = 0,unsigned int commandcount = 0, GLsizei stride = 0): - DrawElementsIndirectUByte(mode,firstCommand,stride),_count(commandcount){_primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType));} - MultiDrawElementsIndirectUByte(const MultiDrawElementsIndirectUByte& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY): + MultiDrawElementsIndirectUByte(GLenum mode = 0,unsigned int firstCommand = 0,unsigned int commandcount = 0, GLsizei stride = 0) : + DrawElementsIndirectUByte(mode,firstCommand,stride),_count(commandcount) { _primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType)); } + + MultiDrawElementsIndirectUByte(const MultiDrawElementsIndirectUByte& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY) : DrawElementsIndirectUByte(mdi,copyop),_count(mdi._count) {} - virtual osg::Object* cloneType() const { - return new MultiDrawElementsIndirectUByte(); - } - virtual osg::Object* clone(const osg::CopyOp& copyop) const { - return new MultiDrawElementsIndirectUByte(*this,copyop); - } - virtual bool isSameKindAs(const osg::Object* obj) const { - return dynamic_cast(obj)!=NULL; - } - virtual const char* className() const { - return "MultiDrawElementsIndirectUByte"; - } + + virtual osg::Object* cloneType() const { return new MultiDrawElementsIndirectUByte(); } + virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new MultiDrawElementsIndirectUByte(*this,copyop); } + virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } + virtual const char* className() const { return "MultiDrawElementsIndirectUByte"; } + virtual void draw(State& state, bool useVertexBufferObjects) const; virtual void accept(PrimitiveFunctor& functor) const; virtual void accept(PrimitiveIndexFunctor& functor) const; virtual unsigned int getNumPrimitives() const; + /// count of Indirect Command to execute - inline void setNumCommandsToDraw( unsigned int i) { - _count=i; - } + inline void setNumCommandsToDraw( unsigned int i) { _count=i; } /// count of Indirect Command to execute - inline unsigned int getNumCommandsToDraw()const { - return _count; - } + inline unsigned int getNumCommandsToDraw()const { return _count; } + protected: unsigned int _count; virtual ~MultiDrawElementsIndirectUByte(); }; + class OSG_EXPORT MultiDrawElementsIndirectUInt : public DrawElementsIndirectUInt { public: - MultiDrawElementsIndirectUInt(GLenum mode = 0,unsigned int firstCommand = 0,unsigned int commandcount = 0, GLsizei stride = 0): - DrawElementsIndirectUInt(mode,firstCommand,stride),_count(commandcount){_primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType));} - MultiDrawElementsIndirectUInt(const MultiDrawElementsIndirectUInt& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY): + MultiDrawElementsIndirectUInt(GLenum mode = 0,unsigned int firstCommand = 0,unsigned int commandcount = 0, GLsizei stride = 0) : + DrawElementsIndirectUInt(mode,firstCommand,stride),_count(commandcount) { _primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType)); } + + MultiDrawElementsIndirectUInt(const MultiDrawElementsIndirectUInt& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY) : DrawElementsIndirectUInt(mdi,copyop),_count(mdi._count) {} - virtual osg::Object* cloneType() const { - return new MultiDrawElementsIndirectUInt(); - } - virtual osg::Object* clone(const osg::CopyOp& copyop) const { - return new MultiDrawElementsIndirectUInt(*this,copyop); - } - virtual bool isSameKindAs(const osg::Object* obj) const { - return dynamic_cast(obj)!=NULL; - } - virtual const char* className() const { - return "MultiDrawElementsIndirectUInt"; - } + + virtual osg::Object* cloneType() const { return new MultiDrawElementsIndirectUInt(); } + virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new MultiDrawElementsIndirectUInt(*this,copyop); } + virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } + virtual const char* className() const { return "MultiDrawElementsIndirectUInt"; } + virtual void draw(State& state, bool useVertexBufferObjects) const; virtual void accept(PrimitiveFunctor& functor) const; virtual void accept(PrimitiveIndexFunctor& functor) const; virtual unsigned int getNumPrimitives() const; + /// count of Indirect Command to execute - inline void setNumCommandsToDraw( unsigned int i) { - _count=i; - } + inline void setNumCommandsToDraw( unsigned int i) { _count=i; } /// count of Indirect Command to execute - inline unsigned int getNumCommandsToDraw()const { - return _count; - } + inline unsigned int getNumCommandsToDraw()const { return _count; } + protected: unsigned int _count; virtual ~MultiDrawElementsIndirectUInt(); }; + /////////////////////////////////////////////////////////////////////////////////////// /// \brief The MultiDrawArraysIndirect PrimitiveSet /// @@ -599,32 +493,21 @@ class OSG_EXPORT DrawArraysIndirect : public osg::PrimitiveSet { public: - DrawArraysIndirect(GLenum mode=0, unsigned int firstcommand = 0, GLsizei stride = 0): + DrawArraysIndirect(GLenum mode=0, unsigned int firstcommand = 0, GLsizei stride = 0) : osg::PrimitiveSet(Type(DrawArraysIndirectPrimitiveType), mode), - _firstCommand(firstcommand), _stride(stride) {setIndirectCommandArray(new DefaultIndirectCommandDrawArrays);} + _firstCommand(firstcommand), _stride(stride) { setIndirectCommandArray(new DefaultIndirectCommandDrawArrays); } - DrawArraysIndirect(const DrawArraysIndirect& dal,const CopyOp& copyop=CopyOp::SHALLOW_COPY): + DrawArraysIndirect(const DrawArraysIndirect& dal,const CopyOp& copyop=CopyOp::SHALLOW_COPY) : osg::PrimitiveSet(dal,copyop), _firstCommand(dal._firstCommand), _stride(dal._stride), - _indirectCommandArray((DefaultIndirectCommandDrawArrays*)copyop( dal._indirectCommandArray.get())) - {} + _indirectCommandArray((DefaultIndirectCommandDrawArrays*)copyop( dal._indirectCommandArray.get())) {} - virtual osg::Object* cloneType() const { - return new DrawArraysIndirect(); - } - virtual osg::Object* clone(const osg::CopyOp& copyop) const { - return new DrawArraysIndirect(*this,copyop); - } - virtual bool isSameKindAs(const osg::Object* obj) const { - return dynamic_cast(obj)!=NULL; - } - virtual const char* libraryName() const { - return "osg"; - } - virtual const char* className() const { - return "DrawArraysIndirect"; - } + virtual osg::Object* cloneType() const { return new DrawArraysIndirect(); } + virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new DrawArraysIndirect(*this,copyop); } + virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } + virtual const char* libraryName() const { return "osg"; } + virtual const char* className() const { return "DrawArraysIndirect"; } virtual void draw(State& state, bool useVertexBufferObjects) const; @@ -638,34 +521,26 @@ public: virtual unsigned int getNumPrimitives() const; /// stride (to set if you use custom CommandArray) - inline void setStride( GLsizei i) { - _stride=i; - } - /// stride (to set if you use custom CommandArray) - inline GLsizei getStride()const { - return _stride; - } - /// set offset of the first command in the IndirectCommandDrawArrays - inline void setFirstCommandToDraw( unsigned int i) { - _firstCommand=i; - } - /// get offset of the first command in the IndirectCommandDrawArrays - inline unsigned int getFirstCommandToDraw() const { - return _firstCommand; - } + inline void setStride( GLsizei i) { _stride=i; } - inline void setIndirectCommandArray(IndirectCommandDrawArrays*idc) { + /// stride (to set if you use custom CommandArray) + inline GLsizei getStride()const { return _stride; } + + /// set offset of the first command in the IndirectCommandDrawArrays + inline void setFirstCommandToDraw( unsigned int i) { _firstCommand=i; } + + /// get offset of the first command in the IndirectCommandDrawArrays + inline unsigned int getFirstCommandToDraw() const { return _firstCommand; } + + inline void setIndirectCommandArray(IndirectCommandDrawArrays*idc) + { _indirectCommandArray = idc; //ensure bo of idc is of the correct type if(!dynamic_cast(_indirectCommandArray->getBufferObject())) _indirectCommandArray->setBufferObject(new DrawIndirectBufferObject()); } - inline const IndirectCommandDrawArrays* getIndirectCommandArray() const { - return _indirectCommandArray; - } - inline IndirectCommandDrawArrays* getIndirectCommandArray(){ - return _indirectCommandArray; - } + inline const IndirectCommandDrawArrays* getIndirectCommandArray() const { return _indirectCommandArray; } + inline IndirectCommandDrawArrays* getIndirectCommandArray() { return _indirectCommandArray; } protected: @@ -682,27 +557,16 @@ class OSG_EXPORT MultiDrawArraysIndirect : public DrawArraysIndirect { public: - MultiDrawArraysIndirect(GLenum mode=0, unsigned int firstcommand = 0, unsigned int count = 0, GLsizei stride = 0): - osg::DrawArraysIndirect(mode, firstcommand, stride), _count(count) - {_primitiveType=Type(MultiDrawArraysIndirectPrimitiveType);} + MultiDrawArraysIndirect(GLenum mode=0, unsigned int firstcommand = 0, unsigned int count = 0, GLsizei stride = 0) : + osg::DrawArraysIndirect(mode, firstcommand, stride), _count(count) { _primitiveType=Type(MultiDrawArraysIndirectPrimitiveType); } - MultiDrawArraysIndirect(const MultiDrawArraysIndirect& dal,const CopyOp& copyop=CopyOp::SHALLOW_COPY): - osg::DrawArraysIndirect(dal,copyop), _count(dal._count) - {} + MultiDrawArraysIndirect(const MultiDrawArraysIndirect& dal,const CopyOp& copyop=CopyOp::SHALLOW_COPY) : + osg::DrawArraysIndirect(dal,copyop), _count(dal._count) {} - virtual osg::Object* cloneType() const { - return new MultiDrawArraysIndirect(); - } - virtual osg::Object* clone(const osg::CopyOp& copyop) const { - return new MultiDrawArraysIndirect(*this,copyop); - } - virtual bool isSameKindAs(const osg::Object* obj) const { - return dynamic_cast(obj)!=NULL; - } - - virtual const char* className() const { - return "MultiDrawArraysIndirect"; - } + virtual osg::Object* cloneType() const { return new MultiDrawArraysIndirect(); } + virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new MultiDrawArraysIndirect(*this,copyop); } + virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } + virtual const char* className() const { return "MultiDrawArraysIndirect"; } virtual void draw(State& state, bool useVertexBufferObjects) const; @@ -716,13 +580,10 @@ public: virtual unsigned int getNumPrimitives() const; /// count of Indirect Command to execute - inline void setNumCommandsToDraw( unsigned int i) { - _count=i; - } + inline void setNumCommandsToDraw( unsigned int i) { _count=i; } /// count of Indirect Command to execute - inline unsigned int getNumCommandsToDraw()const { - return _count; - } + inline unsigned int getNumCommandsToDraw()const { return _count; } + protected: unsigned int _count; @@ -731,4 +592,3 @@ protected: } #endif - From 3bda71ef15a3cfb7d681104d095397bf8410d0fa Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 28 Jul 2017 14:32:56 +0100 Subject: [PATCH 10/19] Improved readability and consistency with the rest OSG by adding/removing spaces and brackets where appropriate. --- src/osg/PrimitiveSetIndirect.cpp | 300 +++++++++++++++---------------- 1 file changed, 150 insertions(+), 150 deletions(-) diff --git a/src/osg/PrimitiveSetIndirect.cpp b/src/osg/PrimitiveSetIndirect.cpp index 796769392..7314dedba 100644 --- a/src/osg/PrimitiveSetIndirect.cpp +++ b/src/osg/PrimitiveSetIndirect.cpp @@ -36,31 +36,31 @@ inline unsigned int getNumPrimitivesDI( const T&_this ) unsigned int total=0; switch(_this.getMode()) { - case(PrimitiveSet::POINTS): - return cmd->count(offset); - case(PrimitiveSet::LINES): - return cmd->count(offset)/2; - case(PrimitiveSet::TRIANGLES): - return cmd->count(offset)/3; - case(PrimitiveSet::QUADS): - return cmd->count(offset)/4; - case(PrimitiveSet::LINE_STRIP): - case(PrimitiveSet::LINE_LOOP): - case(PrimitiveSet::TRIANGLE_STRIP): - case(PrimitiveSet::TRIANGLE_FAN): - case(PrimitiveSet::QUAD_STRIP): - case(PrimitiveSet::PATCHES): - case(PrimitiveSet::POLYGON): - { - return 1; - } + case(PrimitiveSet::POINTS): + return cmd->count(offset); + case(PrimitiveSet::LINES): + return cmd->count(offset)/2; + case(PrimitiveSet::TRIANGLES): + return cmd->count(offset)/3; + case(PrimitiveSet::QUADS): + return cmd->count(offset)/4; + case(PrimitiveSet::LINE_STRIP): + case(PrimitiveSet::LINE_LOOP): + case(PrimitiveSet::TRIANGLE_STRIP): + case(PrimitiveSet::TRIANGLE_FAN): + case(PrimitiveSet::QUAD_STRIP): + case(PrimitiveSet::PATCHES): + case(PrimitiveSet::POLYGON): + { + return 1; + } } return total; } -unsigned int DrawElementsIndirectUInt::getNumPrimitives() const{return getNumPrimitivesDI(*this);} -unsigned int DrawElementsIndirectUByte::getNumPrimitives() const{return getNumPrimitivesDI(*this);} -unsigned int DrawElementsIndirectUShort::getNumPrimitives() const{return getNumPrimitivesDI(*this);} +unsigned int DrawElementsIndirectUInt::getNumPrimitives() const { return getNumPrimitivesDI(*this); } +unsigned int DrawElementsIndirectUByte::getNumPrimitives() const { return getNumPrimitivesDI(*this); } +unsigned int DrawElementsIndirectUShort::getNumPrimitives() const { return getNumPrimitivesDI(*this); } void DrawElementsIndirectUInt::draw(State& state, bool useVertexBufferObjects) const { GLBufferObject* dibo = _indirectCommandArray->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); @@ -79,10 +79,9 @@ void DrawElementsIndirectUInt::draw(State& state, bool useVertexBufferObjects) c state.bindElementBufferObject(ebo); state.get()-> glDrawElementsIndirect(mode, GL_UNSIGNED_INT, - (const GLvoid *)(dibo->getOffset(_indirectCommandArray->getBufferIndex()) //command array adress - +_firstCommand* _indirectCommandArray->getElementSize())// runtime offset computaion can be sizeof(*_indirectCommandArray->begin()) - ); - + (const GLvoid *)(dibo->getOffset(_indirectCommandArray->getBufferIndex()) //command array adress + +_firstCommand* _indirectCommandArray->getElementSize())// runtime offset computaion can be sizeof(*_indirectCommandArray->begin()) + ); } DrawElementsIndirectUInt::~DrawElementsIndirectUInt() @@ -104,8 +103,8 @@ void DrawElementsIndirectUInt::accept(PrimitiveFunctor& functor) const // TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method if (!empty()) functor.drawElements(_mode,_indirectCommandArray->count(_firstCommand), - &(*this)[_indirectCommandArray->firstIndex(_firstCommand)] - ,_indirectCommandArray->baseVertex(_firstCommand)); + &(*this)[_indirectCommandArray->firstIndex(_firstCommand)], + _indirectCommandArray->baseVertex(_firstCommand)); #endif } @@ -115,11 +114,12 @@ void DrawElementsIndirectUInt::accept(PrimitiveIndexFunctor& functor) const // TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method if (!empty()) functor.drawElements(_mode,_indirectCommandArray->count(_firstCommand), - &(*this)[_indirectCommandArray->firstIndex(_firstCommand)] - ,_indirectCommandArray->baseVertex(_firstCommand)); + &(*this)[_indirectCommandArray->firstIndex(_firstCommand)], + _indirectCommandArray->baseVertex(_firstCommand)); #endif } + void DrawElementsIndirectUByte::draw(State& state, bool useVertexBufferObjects) const { GLBufferObject* dibo = _indirectCommandArray->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); state.bindDrawIndirectBufferObject(dibo); @@ -136,14 +136,15 @@ void DrawElementsIndirectUByte::draw(State& state, bool useVertexBufferObjects) state.bindElementBufferObject(ebo); - state.get()-> glDrawElementsIndirect(mode, GL_UNSIGNED_BYTE, (const GLvoid *)(dibo->getOffset(_indirectCommandArray->getBufferIndex()) - +_firstCommand* _indirectCommandArray->getElementSize())); - + state.get()-> glDrawElementsIndirect(mode, GL_UNSIGNED_BYTE, + (const GLvoid *)(dibo->getOffset(_indirectCommandArray->getBufferIndex())+_firstCommand* _indirectCommandArray->getElementSize())); } + DrawElementsIndirectUByte::~DrawElementsIndirectUByte() { releaseGLObjects(); } + void DrawElementsIndirectUByte::offsetIndices(int offset) { for(iterator itr=begin(); @@ -159,8 +160,8 @@ void DrawElementsIndirectUByte::accept(PrimitiveFunctor& functor) const // TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method if (!empty()) functor.drawElements(_mode,_indirectCommandArray->count(_firstCommand), - &(*this)[_indirectCommandArray->firstIndex(_firstCommand)] - ,_indirectCommandArray->baseVertex(_firstCommand)); + &(*this)[_indirectCommandArray->firstIndex(_firstCommand)], + _indirectCommandArray->baseVertex(_firstCommand)); #endif } @@ -170,12 +171,14 @@ void DrawElementsIndirectUByte::accept(PrimitiveIndexFunctor& functor) const // TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method if (!empty()) functor.drawElements(_mode,_indirectCommandArray->count(_firstCommand), - &(*this)[_indirectCommandArray->firstIndex(_firstCommand)] - ,_indirectCommandArray->baseVertex(_firstCommand)); + &(*this)[_indirectCommandArray->firstIndex(_firstCommand)], + _indirectCommandArray->baseVertex(_firstCommand)); #endif } + void DrawElementsIndirectUShort::draw(State& state, bool useVertexBufferObjects) const -{ GLBufferObject* dibo = _indirectCommandArray->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); +{ + GLBufferObject* dibo = _indirectCommandArray->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); state.bindDrawIndirectBufferObject(dibo); GLenum mode = _mode; @@ -190,14 +193,15 @@ void DrawElementsIndirectUShort::draw(State& state, bool useVertexBufferObjects) state.bindElementBufferObject(ebo); - state.get()-> glDrawElementsIndirect(mode, GL_UNSIGNED_SHORT, (const GLvoid *)(dibo->getOffset(_indirectCommandArray->getBufferIndex()) - +_firstCommand* _indirectCommandArray->getElementSize())); - + state.get()-> glDrawElementsIndirect(mode, GL_UNSIGNED_SHORT, + (const GLvoid *)(dibo->getOffset(_indirectCommandArray->getBufferIndex())+_firstCommand* _indirectCommandArray->getElementSize())); } + DrawElementsIndirectUShort::~DrawElementsIndirectUShort() { releaseGLObjects(); } + void DrawElementsIndirectUShort::offsetIndices(int offset) { for(iterator itr=begin(); @@ -213,8 +217,8 @@ void DrawElementsIndirectUShort::accept(PrimitiveFunctor& functor) const // TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method if (!empty()) functor.drawElements(_mode,_indirectCommandArray->count(_firstCommand), - &(*this)[_indirectCommandArray->firstIndex(_firstCommand)] - ,_indirectCommandArray->baseVertex(_firstCommand)); + &(*this)[_indirectCommandArray->firstIndex(_firstCommand)], + _indirectCommandArray->baseVertex(_firstCommand)); #endif } @@ -224,51 +228,53 @@ void DrawElementsIndirectUShort::accept(PrimitiveIndexFunctor& functor) const // TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method if (!empty()) functor.drawElements(_mode,_indirectCommandArray->count(_firstCommand), - &(*this)[_indirectCommandArray->firstIndex(_firstCommand)] - ,_indirectCommandArray->baseVertex(_firstCommand)); + &(*this)[_indirectCommandArray->firstIndex(_firstCommand)], + _indirectCommandArray->baseVertex(_firstCommand)); #endif } + //////////////////////////////////////////////////////////////////////////////////////////////////////// // // MultiDrawElementsIndirect // template inline unsigned int getNumPrimitivesMDI( const T&_this) -{ IndirectCommandDrawElements *_indirectCommandArray=const_cast(_this.getIndirectCommandArray()); +{ + IndirectCommandDrawElements *_indirectCommandArray=const_cast(_this.getIndirectCommandArray()); unsigned int total=0; switch(_this.getMode()) { - case(PrimitiveSet::POINTS): - for(unsigned int i=0;i<_indirectCommandArray->getNumElements();++i) - total+=_indirectCommandArray->count(i); - case(PrimitiveSet::LINES): - for(unsigned int i=0;i<_indirectCommandArray->getNumElements();++i) - total+=_indirectCommandArray->count(i)/2; - case(PrimitiveSet::TRIANGLES): - for(unsigned int i=0;i<_indirectCommandArray->getNumElements();++i) - total+=_indirectCommandArray->count(i)/3; - case(PrimitiveSet::QUADS): - for(unsigned int i=0;i<_indirectCommandArray->getNumElements();++i) - total+=_indirectCommandArray->count(i)/4; - case(PrimitiveSet::LINE_STRIP): - case(PrimitiveSet::LINE_LOOP): - case(PrimitiveSet::TRIANGLE_STRIP): - case(PrimitiveSet::TRIANGLE_FAN): - case(PrimitiveSet::QUAD_STRIP): - case(PrimitiveSet::PATCHES): - case(PrimitiveSet::POLYGON): - { - unsigned int primcount = _indirectCommandArray->getNumElements(); - return primcount; - } + case(PrimitiveSet::POINTS): + for(unsigned int i=0;i<_indirectCommandArray->getNumElements();++i) + total+=_indirectCommandArray->count(i); + case(PrimitiveSet::LINES): + for(unsigned int i=0;i<_indirectCommandArray->getNumElements();++i) + total+=_indirectCommandArray->count(i)/2; + case(PrimitiveSet::TRIANGLES): + for(unsigned int i=0;i<_indirectCommandArray->getNumElements();++i) + total+=_indirectCommandArray->count(i)/3; + case(PrimitiveSet::QUADS): + for(unsigned int i=0;i<_indirectCommandArray->getNumElements();++i) + total+=_indirectCommandArray->count(i)/4; + case(PrimitiveSet::LINE_STRIP): + case(PrimitiveSet::LINE_LOOP): + case(PrimitiveSet::TRIANGLE_STRIP): + case(PrimitiveSet::TRIANGLE_FAN): + case(PrimitiveSet::QUAD_STRIP): + case(PrimitiveSet::PATCHES): + case(PrimitiveSet::POLYGON): + { + unsigned int primcount = _indirectCommandArray->getNumElements(); + return primcount; + } } return total; } -unsigned int MultiDrawElementsIndirectUInt::getNumPrimitives() const{return getNumPrimitivesMDI(*this);} -unsigned int MultiDrawElementsIndirectUByte::getNumPrimitives() const{return getNumPrimitivesMDI(*this);} -unsigned int MultiDrawElementsIndirectUShort::getNumPrimitives() const{return getNumPrimitivesMDI(*this);} +unsigned int MultiDrawElementsIndirectUInt::getNumPrimitives() const { return getNumPrimitivesMDI(*this); } +unsigned int MultiDrawElementsIndirectUByte::getNumPrimitives() const { return getNumPrimitivesMDI(*this); } +unsigned int MultiDrawElementsIndirectUShort::getNumPrimitives() const { return getNumPrimitivesMDI(*this); } //////////////////////////////////////////////////////////////////////////////////////////////////////// // @@ -278,6 +284,7 @@ MultiDrawElementsIndirectUByte::~MultiDrawElementsIndirectUByte() { releaseGLObjects(); } + void MultiDrawElementsIndirectUByte::draw(State& state, bool useVertexBufferObjects) const { GLBufferObject* dibo = _indirectCommandArray->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() ); @@ -289,27 +296,26 @@ void MultiDrawElementsIndirectUByte::draw(State& state, bool useVertexBufferObje if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP; #endif - GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID()); assert (useVertexBufferObjects && ebo); state.bindElementBufferObject(ebo); - state.get()-> glMultiDrawElementsIndirect(mode, GL_UNSIGNED_BYTE, (const GLvoid *)(dibo->getOffset(_indirectCommandArray->getBufferIndex())),_indirectCommandArray->getNumElements(), _stride); - + state.get()-> glMultiDrawElementsIndirect(mode, GL_UNSIGNED_BYTE, + (const GLvoid *)(dibo->getOffset(_indirectCommandArray->getBufferIndex())),_indirectCommandArray->getNumElements(), _stride); } void MultiDrawElementsIndirectUByte::accept(PrimitiveFunctor& functor) const { #ifdef PRIMFUNCTORBASEVERTEX //TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method - unsigned int maxindex=_count>0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + unsigned int maxindex= (_count>0) ? _firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; if (!empty() ) for(unsigned int i = _firstCommand; icount(i), - &(*this)[_indirectCommandArray->firstIndex(i)] - ,_indirectCommandArray->baseVertex(i)); + &(*this)[_indirectCommandArray->firstIndex(i)], + _indirectCommandArray->baseVertex(i)); #endif } @@ -317,12 +323,12 @@ void MultiDrawElementsIndirectUByte::accept(PrimitiveIndexFunctor& functor) cons { #ifdef PRIMFUNCTORBASEVERTEX //TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method - unsigned int maxindex=_count>0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + unsigned int maxindex= (_count>0) ? _firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; if (!empty() ) for(unsigned int i = _firstCommand; icount(i), - &(*this)[_indirectCommandArray->firstIndex(i)] - ,_indirectCommandArray->baseVertex(i)); + &(*this)[_indirectCommandArray->firstIndex(i)], + _indirectCommandArray->baseVertex(i)); #endif } @@ -355,20 +361,19 @@ void MultiDrawElementsIndirectUShort::draw(State& state, bool useVertexBufferObj state.bindElementBufferObject(ebo); state.get()-> glMultiDrawElementsIndirect(mode, GL_UNSIGNED_SHORT, (const GLvoid *)(dibo->getOffset(_indirectCommandArray->getBufferIndex())), - _count>0?_count:_indirectCommandArray->getNumElements(),_stride); - + (_count>0) ?_count:_indirectCommandArray->getNumElements(),_stride); } void MultiDrawElementsIndirectUShort::accept(PrimitiveFunctor& functor) const { #ifdef PRIMFUNCTORBASEVERTEX //TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method - unsigned int maxindex=_count>0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + unsigned int maxindex= (_count>0) ? _firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; if (!empty() ) for(unsigned int i = _firstCommand; icount(i), - &(*this)[_indirectCommandArray->firstIndex(i)] - ,_indirectCommandArray->baseVertex(i)); + &(*this)[_indirectCommandArray->firstIndex(i)], + _indirectCommandArray->baseVertex(i)); #endif } @@ -376,12 +381,12 @@ void MultiDrawElementsIndirectUShort::accept(PrimitiveIndexFunctor& functor) con { #ifdef PRIMFUNCTORBASEVERTEX //TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method - unsigned int maxindex=_count>0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + unsigned int maxindex = (_count>0) ?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; if (!empty() ) for(unsigned int i = _firstCommand; icount(i), - &(*this)[_indirectCommandArray->firstIndex(i)] - ,_indirectCommandArray->baseVertex(i)); + &(*this)[_indirectCommandArray->firstIndex(i)], + _indirectCommandArray->baseVertex(i)); #endif } @@ -404,7 +409,6 @@ void MultiDrawElementsIndirectUInt::draw(State& state, bool useVertexBufferObjec if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP; #endif - GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID()); assert (useVertexBufferObjects && ebo); @@ -412,20 +416,19 @@ void MultiDrawElementsIndirectUInt::draw(State& state, bool useVertexBufferObjec state.bindElementBufferObject(ebo); state.get()-> glMultiDrawElementsIndirect(mode, GL_UNSIGNED_INT, (const GLvoid *)(dibo->getOffset(_indirectCommandArray->getBufferIndex())), - _count>0?_count:_indirectCommandArray->getNumElements(), _stride); - + (_count>0) ? _count:_indirectCommandArray->getNumElements(), _stride); } void MultiDrawElementsIndirectUInt::accept(PrimitiveFunctor& functor) const { #ifdef PRIMFUNCTORBASEVERTEX //TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method - unsigned int maxindex=_count>0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + unsigned int maxindex= (_count>0) ? _firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; if (!empty() ) for(unsigned int i = _firstCommand; icount(i), - &(*this)[_indirectCommandArray->firstIndex(i)] - ,_indirectCommandArray->baseVertex(i)); + &(*this)[_indirectCommandArray->firstIndex(i)], + _indirectCommandArray->baseVertex(i)); #endif } @@ -433,12 +436,12 @@ void MultiDrawElementsIndirectUInt::accept(PrimitiveIndexFunctor& functor) const { #ifdef PRIMFUNCTORBASEVERTEX //TODO: add base vertex parameter in PrimitiveFunctor and PrimitiveIndexFunctor drawelements method - unsigned int maxindex=_count>0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + unsigned int maxindex = (_count>0) ?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; if (!empty() ) for(unsigned int i = _firstCommand; icount(i), - &(*this)[_indirectCommandArray->firstIndex(i)] - ,_indirectCommandArray->baseVertex(i)); + &(*this)[_indirectCommandArray->firstIndex(i)], + _indirectCommandArray->baseVertex(i)); #endif } @@ -454,9 +457,7 @@ void DrawArraysIndirect::draw(osg::State& state, bool) const GLExtensions* ext = state.get(); - ext->glDrawArraysIndirect(_mode, (const GLvoid *)(dibo->getOffset(_indirectCommandArray->getBufferIndex()) - +_firstCommand* _indirectCommandArray->getElementSize())); - + ext->glDrawArraysIndirect(_mode, (const GLvoid *)(dibo->getOffset(_indirectCommandArray->getBufferIndex())+_firstCommand* _indirectCommandArray->getElementSize())); } void DrawArraysIndirect::accept(PrimitiveFunctor& functor) const @@ -488,24 +489,24 @@ unsigned int DrawArraysIndirect::getNumPrimitives() const { switch(_mode) { - case(POINTS): - return _indirectCommandArray->count(_firstCommand); - case(LINES): - return _indirectCommandArray->count(_firstCommand)/2; - case(TRIANGLES): - return _indirectCommandArray->count(_firstCommand)/3; - case(QUADS): - return _indirectCommandArray->count(_firstCommand)/4; - case(LINE_STRIP): - case(LINE_LOOP): - case(TRIANGLE_STRIP): - case(TRIANGLE_FAN): - case(QUAD_STRIP): - case(PATCHES): - case(POLYGON): - { - return 1; - } + case(POINTS): + return _indirectCommandArray->count(_firstCommand); + case(LINES): + return _indirectCommandArray->count(_firstCommand)/2; + case(TRIANGLES): + return _indirectCommandArray->count(_firstCommand)/3; + case(QUADS): + return _indirectCommandArray->count(_firstCommand)/4; + case(LINE_STRIP): + case(LINE_LOOP): + case(TRIANGLE_STRIP): + case(TRIANGLE_FAN): + case(QUAD_STRIP): + case(PATCHES): + case(POLYGON): + { + return 1; + } } return 0; } @@ -522,13 +523,13 @@ void MultiDrawArraysIndirect::draw(osg::State& state, bool) const GLExtensions* ext = state.get(); ext->glMultiDrawArraysIndirect(_mode, (const GLvoid *)(dibo->getOffset(_indirectCommandArray->getBufferIndex())+_firstCommand*_indirectCommandArray->getElementSize()), - _count>0?_count:_indirectCommandArray->getNumElements(), _stride); + (_count>0) ?_count:_indirectCommandArray->getNumElements(), _stride); } void MultiDrawArraysIndirect::accept(PrimitiveFunctor& functor) const { - unsigned int maxindex=_count>0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + unsigned int maxindex= (_count>0) ? _firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; for(unsigned int i = _firstCommand; ifirst(i), _indirectCommandArray->count(i)); @@ -537,7 +538,7 @@ void MultiDrawArraysIndirect::accept(PrimitiveFunctor& functor) const void MultiDrawArraysIndirect::accept(PrimitiveIndexFunctor& functor) const { - unsigned int maxindex=_count>0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + unsigned int maxindex= (_count>0) ? _firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; for(unsigned int i = _firstCommand; ifirst(i), _indirectCommandArray->count(i)); @@ -547,16 +548,16 @@ void MultiDrawArraysIndirect::accept(PrimitiveIndexFunctor& functor) const unsigned int MultiDrawArraysIndirect::getNumIndices() const { unsigned int total=0; - - unsigned int maxindex=_count>0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + unsigned int maxindex= (_count>0) ? _firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; for(unsigned int i = _firstCommand; icount(i); + return total; } unsigned int MultiDrawArraysIndirect::index(unsigned int pos) const { - unsigned int i = 0, maxindex=_count>0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + unsigned int i = 0, maxindex= (_count>0) ? _firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; for(i=_firstCommand; icount(i); @@ -570,41 +571,40 @@ unsigned int MultiDrawArraysIndirect::index(unsigned int pos) const void MultiDrawArraysIndirect::offsetIndices(int offset) { - unsigned int maxindex=_count>0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + unsigned int maxindex= (_count>0) ? _firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; for(unsigned int i = _firstCommand; ifirst(i) += offset; } unsigned int MultiDrawArraysIndirect::getNumPrimitives() const { - unsigned int total=0;unsigned int maxindex=_count>0?_firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; + unsigned int total=0;unsigned int maxindex= (_count>0) ? _firstCommand + _count : _indirectCommandArray->getNumElements() - _firstCommand; switch(_mode) { - case(POINTS): - for(unsigned int i = _firstCommand; icount(i); - case(LINES): - for(unsigned int i = _firstCommand; icount(i)/2; - case(TRIANGLES): - for(unsigned int i = _firstCommand; icount(i)/3; - case(QUADS): - for(unsigned int i = _firstCommand; icount(i)/4; - case(LINE_STRIP): - case(LINE_LOOP): - case(TRIANGLE_STRIP): - case(TRIANGLE_FAN): - case(QUAD_STRIP): - case(PATCHES): - case(POLYGON): - { - unsigned int primcount = _indirectCommandArray->getNumElements(); - return primcount; - } + case(POINTS): + for(unsigned int i = _firstCommand; icount(i); + case(LINES): + for(unsigned int i = _firstCommand; icount(i)/2; + case(TRIANGLES): + for(unsigned int i = _firstCommand; icount(i)/3; + case(QUADS): + for(unsigned int i = _firstCommand; icount(i)/4; + case(LINE_STRIP): + case(LINE_LOOP): + case(TRIANGLE_STRIP): + case(TRIANGLE_FAN): + case(QUAD_STRIP): + case(PATCHES): + case(POLYGON): + { + unsigned int primcount = _indirectCommandArray->getNumElements(); + return primcount; + } } return total; } - From d1adb9acbc5bcf354d9e9b05044037f7bd04b3df Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 28 Jul 2017 14:34:59 +0100 Subject: [PATCH 11/19] Added missing break statements --- src/osg/PrimitiveSetIndirect.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/osg/PrimitiveSetIndirect.cpp b/src/osg/PrimitiveSetIndirect.cpp index 7314dedba..424c946e5 100644 --- a/src/osg/PrimitiveSetIndirect.cpp +++ b/src/osg/PrimitiveSetIndirect.cpp @@ -248,15 +248,19 @@ unsigned int getNumPrimitivesMDI( const T&_this) case(PrimitiveSet::POINTS): for(unsigned int i=0;i<_indirectCommandArray->getNumElements();++i) total+=_indirectCommandArray->count(i); + break; case(PrimitiveSet::LINES): for(unsigned int i=0;i<_indirectCommandArray->getNumElements();++i) total+=_indirectCommandArray->count(i)/2; + break; case(PrimitiveSet::TRIANGLES): for(unsigned int i=0;i<_indirectCommandArray->getNumElements();++i) total+=_indirectCommandArray->count(i)/3; + break; case(PrimitiveSet::QUADS): for(unsigned int i=0;i<_indirectCommandArray->getNumElements();++i) total+=_indirectCommandArray->count(i)/4; + break; case(PrimitiveSet::LINE_STRIP): case(PrimitiveSet::LINE_LOOP): case(PrimitiveSet::TRIANGLE_STRIP): @@ -490,7 +494,7 @@ unsigned int DrawArraysIndirect::getNumPrimitives() const switch(_mode) { case(POINTS): - return _indirectCommandArray->count(_firstCommand); + return _indirectCommandArray->count(_firstCommand); case(LINES): return _indirectCommandArray->count(_firstCommand)/2; case(TRIANGLES): @@ -585,15 +589,19 @@ unsigned int MultiDrawArraysIndirect::getNumPrimitives() const case(POINTS): for(unsigned int i = _firstCommand; icount(i); + break; case(LINES): for(unsigned int i = _firstCommand; icount(i)/2; + break; case(TRIANGLES): for(unsigned int i = _firstCommand; icount(i)/3; + break; case(QUADS): for(unsigned int i = _firstCommand; icount(i)/4; + break; case(LINE_STRIP): case(LINE_LOOP): case(TRIANGLE_STRIP): From d810d4a4c096a5515bf3c60fb7a69bb281567ea2 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Sun, 30 Jul 2017 10:15:32 +0200 Subject: [PATCH 12/19] add a very simple example for mdi with basevertex --- examples/CMakeLists.txt | 1 + examples/osgsimpleMDI/CMakeLists.txt | 7 ++ examples/osgsimpleMDI/osgsimpleMDI.cpp | 160 +++++++++++++++++++++++++ 3 files changed, 168 insertions(+) create mode 100644 examples/osgsimpleMDI/CMakeLists.txt create mode 100644 examples/osgsimpleMDI/osgsimpleMDI.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index d695fe86f..9d54ac9ca 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -20,6 +20,7 @@ ELSE(ANDROID) IF(DYNAMIC_OPENSCENEGRAPH) + ADD_SUBDIRECTORY(osgsimpleMDI) ADD_SUBDIRECTORY(osg2cpp) ADD_SUBDIRECTORY(osganalysis) ADD_SUBDIRECTORY(osganimate) diff --git a/examples/osgsimpleMDI/CMakeLists.txt b/examples/osgsimpleMDI/CMakeLists.txt new file mode 100644 index 000000000..3c14efece --- /dev/null +++ b/examples/osgsimpleMDI/CMakeLists.txt @@ -0,0 +1,7 @@ +#this file is automatically generated + + +SET(TARGET_SRC osgsimpleMDI.cpp ) + +#### end var setup ### +SETUP_EXAMPLE(osgsimpleMDI) diff --git a/examples/osgsimpleMDI/osgsimpleMDI.cpp b/examples/osgsimpleMDI/osgsimpleMDI.cpp new file mode 100644 index 000000000..7166f973d --- /dev/null +++ b/examples/osgsimpleMDI/osgsimpleMDI.cpp @@ -0,0 +1,160 @@ +/* OpenSceneGraph example, osgtransformfeedback +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ + +/* file: examples/osgsimpleMDI/osgsimpleMDI.cpp +* author: Julien Valentin 2017-08-01 +* copyright: (C) 2013 +* license: OpenSceneGraph Public License (OSGPL) +* +* A simple example of mdi with basevertex +* +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + + + + +/////////////////////////////////////////////////////////////////////////// +#define MAXX 100 +#define MAXY 100 + +int main( int argc, char**argv ) +{ + + osg::ArgumentParser arguments(&argc,argv); + + bool MDIenable=true; + if(arguments.read("--classic")) + MDIenable=false; + + osg::Geode* root( new osg::Geode ); + osg::BoundingBox bb; + + osg::Vec3 corner; + osg::ref_ptr vertbo=new osg::VertexBufferObject; + osg::ref_ptr texbo=new osg::VertexBufferObject; + osg::ref_ptr ebo=new osg::ElementBufferObject; + + ///create empty mdi + osg::MultiDrawElementsIndirectUShort* mdi=new osg::MultiDrawElementsIndirectUShort(osg::PrimitiveSet::TRIANGLE_STRIP); + osg::DefaultIndirectCommandDrawElements* mdicommands= new osg::DefaultIndirectCommandDrawElements(); + mdi->setIndirectCommandArray(mdicommands); + mdi->setBufferObject(ebo); + + osg::ref_ptr oldprHolder=new osg::Geometry(); + + osg::Vec3 myCoords[] = + { + osg::Vec3(0,0.0f,0.7f), + osg::Vec3(0,0.0f,0), + osg::Vec3(0.7,0.0f,0), + osg::Vec3(0.7f,0.0f,0.7f) + }; + + osg::Vec2 myTexCoords[] = + { + osg::Vec2(0,1), + osg::Vec2(0,0), + osg::Vec2(1,0), + osg::Vec2(1,1) + }; + unsigned short myIndices[] = + { + 0, + 1, + 3, + 2 + }; + for(int j =0 ; jsetUseVertexBufferObjects(true); + osg::Vec3Array * verts=new osg::Vec3Array(4,myCoords); + for(int z=0; z<4; z++)(*verts)[z]+=corner; + geom->setVertexArray(verts); + geom->setTexCoordArray(0,new osg::Vec2Array(4,myTexCoords)); + geom->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_STRIP,4,myIndices)); + ///end generate indexed quad + + bb.expandBy(geom->getBoundingBox()); + + if(MDIenable) { + ///setup bos + geom->getVertexArray()->setBufferObject(vertbo); + geom->getTexCoordArray(0)->setBufferObject(texbo); + osg::DrawElementsUShort *dre = static_cast(geom->getPrimitiveSet(0)); + dre->setBufferObject(ebo); + + ///keep old pr alive for indices upload purpose + oldprHolder->addPrimitiveSet(dre); + geom->removePrimitiveSet(0,1); + + ///create indirect command + osg::DrawElementsIndirectCommand cmd; + cmd.count=4; + cmd.instanceCount=1; + cmd.firstIndex=root->getNumChildren()*4; + cmd.baseVertex=root->getNumChildren()*4; + mdicommands->push_back(cmd); + + if(cmd.firstIndex==0) { + ///only first geom have a mdi primset + geom->addPrimitiveSet(mdi); + ///avoid bound computation to fail because of the lack of support of basevertex in functors + geom->setComputeBoundingBoxCallback(new osg::Drawable::ComputeBoundingBoxCallback); + } + + } + root->addChild(geom); + } + } + + if(MDIenable) { + ///override bounds + root->getDrawable(0)->setInitialBound(bb); + ///put it somewhere + root->setUserData( oldprHolder); + } + + osgViewer::Viewer viewer; + viewer.addEventHandler(new osgViewer::StatsHandler); + viewer.setSceneData( root ); + return viewer.run(); +} From aac146c7bc7da1558645e488a8e8239c05c51063 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 31 Jul 2017 02:43:50 +0200 Subject: [PATCH 13/19] correct a bug and make it more conservative --- examples/osgsimpleMDI/osgsimpleMDI.cpp | 95 +++++++++----------------- 1 file changed, 34 insertions(+), 61 deletions(-) diff --git a/examples/osgsimpleMDI/osgsimpleMDI.cpp b/examples/osgsimpleMDI/osgsimpleMDI.cpp index 7166f973d..e7814f2c3 100644 --- a/examples/osgsimpleMDI/osgsimpleMDI.cpp +++ b/examples/osgsimpleMDI/osgsimpleMDI.cpp @@ -38,7 +38,7 @@ #include #include -#include +#include #include #include @@ -51,7 +51,7 @@ /////////////////////////////////////////////////////////////////////////// #define MAXX 100 #define MAXY 100 - +//#define VIAINTERFACE 1 int main( int argc, char**argv ) { @@ -59,23 +59,25 @@ int main( int argc, char**argv ) bool MDIenable=true; if(arguments.read("--classic")) - MDIenable=false; + { MDIenable=false; + OSG_WARN<<"disabling MDI"< vertbo=new osg::VertexBufferObject; - osg::ref_ptr texbo=new osg::VertexBufferObject; osg::ref_ptr ebo=new osg::ElementBufferObject; ///create empty mdi osg::MultiDrawElementsIndirectUShort* mdi=new osg::MultiDrawElementsIndirectUShort(osg::PrimitiveSet::TRIANGLE_STRIP); osg::DefaultIndirectCommandDrawElements* mdicommands= new osg::DefaultIndirectCommandDrawElements(); mdi->setIndirectCommandArray(mdicommands); - mdi->setBufferObject(ebo); - osg::ref_ptr oldprHolder=new osg::Geometry(); + osg::ref_ptr geom=new osg::Geometry(); + geom->setUseVertexBufferObjects(true); + osg::BoundingBox bb; + bb.set(0,0,0,MAXX,0,MAXY); + //set bounds by hand cause of the lack of support of basevertex in PrimitiveFunctors + geom->setInitialBound(bb); osg::Vec3 myCoords[] = { @@ -85,13 +87,6 @@ int main( int argc, char**argv ) osg::Vec3(0.7f,0.0f,0.7f) }; - osg::Vec2 myTexCoords[] = - { - osg::Vec2(0,1), - osg::Vec2(0,0), - osg::Vec2(1,0), - osg::Vec2(1,1) - }; unsigned short myIndices[] = { 0, @@ -99,60 +94,38 @@ int main( int argc, char**argv ) 3, 2 }; + osg::Vec3Array * verts=new osg::Vec3Array(); + + for(int j =0 ; jsetUseVertexBufferObjects(true); - osg::Vec3Array * verts=new osg::Vec3Array(4,myCoords); - for(int z=0; z<4; z++)(*verts)[z]+=corner; - geom->setVertexArray(verts); - geom->setTexCoordArray(0,new osg::Vec2Array(4,myTexCoords)); - geom->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_STRIP,4,myIndices)); - ///end generate indexed quad - - bb.expandBy(geom->getBoundingBox()); - - if(MDIenable) { - ///setup bos - geom->getVertexArray()->setBufferObject(vertbo); - geom->getTexCoordArray(0)->setBufferObject(texbo); - osg::DrawElementsUShort *dre = static_cast(geom->getPrimitiveSet(0)); - dre->setBufferObject(ebo); - - ///keep old pr alive for indices upload purpose - oldprHolder->addPrimitiveSet(dre); - geom->removePrimitiveSet(0,1); - - ///create indirect command - osg::DrawElementsIndirectCommand cmd; - cmd.count=4; - cmd.instanceCount=1; - cmd.firstIndex=root->getNumChildren()*4; - cmd.baseVertex=root->getNumChildren()*4; - mdicommands->push_back(cmd); - - if(cmd.firstIndex==0) { - ///only first geom have a mdi primset - geom->addPrimitiveSet(mdi); - ///avoid bound computation to fail because of the lack of support of basevertex in functors - geom->setComputeBoundingBoxCallback(new osg::Drawable::ComputeBoundingBoxCallback); - } + ///create indirect command + osg::DrawElementsIndirectCommand cmd; + cmd.count=4; + cmd.instanceCount=1; + cmd.firstIndex=verts->size(); + cmd.baseVertex=verts->size(); + mdicommands->push_back(cmd); + for(int z=0; z<4; z++) { + verts->push_back(osg::Vec3(i,0,j)+myCoords[z]); + mdi->addElement(myIndices[z]); } - root->addChild(geom); } } - + geom->setVertexArray(verts); if(MDIenable) { - ///override bounds - root->getDrawable(0)->setInitialBound(bb); - ///put it somewhere - root->setUserData( oldprHolder); - } + geom->addPrimitiveSet(mdi); + } else + for(int i=0; isetElementBufferObject(ebo); + geom->addPrimitiveSet(dre); + } + root->addChild(geom); osgViewer::Viewer viewer; viewer.addEventHandler(new osgViewer::StatsHandler); viewer.setSceneData( root ); From 3537460b0eb3408047faa2f9a56d7529c2677bc6 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 31 Jul 2017 03:08:52 +0200 Subject: [PATCH 14/19] Add arguments, command line usage and use DrawElementsUInt for classic case --- examples/osgsimpleMDI/osgsimpleMDI.cpp | 38 +++++++++++++++++--------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/examples/osgsimpleMDI/osgsimpleMDI.cpp b/examples/osgsimpleMDI/osgsimpleMDI.cpp index e7814f2c3..13ca86dbb 100644 --- a/examples/osgsimpleMDI/osgsimpleMDI.cpp +++ b/examples/osgsimpleMDI/osgsimpleMDI.cpp @@ -38,7 +38,7 @@ #include #include -#include +#include #include #include @@ -49,13 +49,29 @@ /////////////////////////////////////////////////////////////////////////// -#define MAXX 100 -#define MAXY 100 -//#define VIAINTERFACE 1 +//#define MAXX 1000 +//#define MAXY 1000 + int main( int argc, char**argv ) { osg::ArgumentParser arguments(&argc,argv); + arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates Multi Indirect Draw with basevertex"); + arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] "); + arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); + arguments.getApplicationUsage()->addCommandLineOption("--numX","square count on X"); + arguments.getApplicationUsage()->addCommandLineOption("--numY","square count on Y"); + arguments.getApplicationUsage()->addCommandLineOption("--classic","disable MDI and use classic DrawElements"); + + if (arguments.read("-h") || arguments.read("--help")) + { + arguments.getApplicationUsage()->write(std::cout); + return 1; + } + + int MAXX=200;int MAXY=200; + arguments.read("--numX",MAXX); + arguments.read("--numY",MAXY); bool MDIenable=true; if(arguments.read("--classic")) @@ -87,13 +103,9 @@ int main( int argc, char**argv ) osg::Vec3(0.7f,0.0f,0.7f) }; - unsigned short myIndices[] = - { - 0, - 1, - 3, - 2 - }; + unsigned short myIndices[] = { 0, 1, 3, 2 }; + unsigned int myIndicesUI[] = { 0, 1, 3, 2 }; + osg::Vec3Array * verts=new osg::Vec3Array(); @@ -120,8 +132,8 @@ int main( int argc, char**argv ) } else for(int i=0; isetElementBufferObject(ebo); geom->addPrimitiveSet(dre); } From 9e9d3cd2491f1e9aa57c4e6b492fe28c4406b8d9 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Mon, 31 Jul 2017 03:15:03 +0200 Subject: [PATCH 15/19] fix a bug : indices pre incremented should be post --- examples/osgsimpleMDI/osgsimpleMDI.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/examples/osgsimpleMDI/osgsimpleMDI.cpp b/examples/osgsimpleMDI/osgsimpleMDI.cpp index 13ca86dbb..be7bd2c31 100644 --- a/examples/osgsimpleMDI/osgsimpleMDI.cpp +++ b/examples/osgsimpleMDI/osgsimpleMDI.cpp @@ -47,11 +47,6 @@ - -/////////////////////////////////////////////////////////////////////////// -//#define MAXX 1000 -//#define MAXY 1000 - int main( int argc, char**argv ) { @@ -69,9 +64,10 @@ int main( int argc, char**argv ) return 1; } - int MAXX=200;int MAXY=200; - arguments.read("--numX",MAXX); - arguments.read("--numY",MAXY); + int MAXX=200; + int MAXY=200; + arguments.read("--numX",MAXX); + arguments.read("--numY",MAXY); bool MDIenable=true; if(arguments.read("--classic")) @@ -132,10 +128,10 @@ int main( int argc, char**argv ) } else for(int i=0; isetElementBufferObject(ebo); geom->addPrimitiveSet(dre); + for(int z=0; z<4; z++)myIndicesUI[z]+=4; } root->addChild(geom); osgViewer::Viewer viewer; From 3965b4e66e77a64797fb8e5652cc17d0d78f85b5 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Tue, 1 Aug 2017 02:18:15 +0200 Subject: [PATCH 16/19] fix a bug in MDI serializer --- src/osgWrappers/serializers/osg/PrimitiveSetIndirect.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/osgWrappers/serializers/osg/PrimitiveSetIndirect.cpp b/src/osgWrappers/serializers/osg/PrimitiveSetIndirect.cpp index 1d732cdb8..867f57162 100644 --- a/src/osgWrappers/serializers/osg/PrimitiveSetIndirect.cpp +++ b/src/osgWrappers/serializers/osg/PrimitiveSetIndirect.cpp @@ -168,13 +168,13 @@ REGISTER_OBJECT_WRAPPER( DrawElementsIndirect, } #define INDIRECTDRAW_ELEMENTS_WRAPPER( DRAWELEMENTS, ELEMENTTYPE ) \ namespace Wrapper##DRAWELEMENTS { \ - REGISTER_OBJECT_WRAPPER( DRAWELEMENTS, new osg::DRAWELEMENTS, osg::DRAWELEMENTS, "osg::Object osg::BufferData osg::PrimitiveSet osg::IndirectDrawElements osg::"#DRAWELEMENTS) \ + REGISTER_OBJECT_WRAPPER( DRAWELEMENTS, new osg::DRAWELEMENTS, osg::DRAWELEMENTS, "osg::Object osg::BufferData osg::PrimitiveSet osg::DrawElementsIndirect osg::"#DRAWELEMENTS) \ { \ ADD_ISAVECTOR_SERIALIZER( vector, osgDB::BaseSerializer::ELEMENTTYPE, 4 ); \ } \ }\ namespace WrapperMulti##DRAWELEMENTS { \ - REGISTER_OBJECT_WRAPPER( Multi##DRAWELEMENTS, new osg::Multi##DRAWELEMENTS, osg::Multi##DRAWELEMENTS, "osg::Object osg::BufferData osg::PrimitiveSet osg::IndirectDrawElements osg::"#DRAWELEMENTS" osg::Multi"#DRAWELEMENTS) \ + REGISTER_OBJECT_WRAPPER( Multi##DRAWELEMENTS, new osg::Multi##DRAWELEMENTS, osg::Multi##DRAWELEMENTS, "osg::Object osg::BufferData osg::PrimitiveSet osg::DrawElementsIndirect osg::"#DRAWELEMENTS" osg::Multi"#DRAWELEMENTS) \ { \ ADD_UINT_SERIALIZER( NumCommandsToDraw, 0);\ } \ From 7f292c3fb5bdab16f8257b042de16d94e7330cd0 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Wed, 2 Aug 2017 21:50:25 +0200 Subject: [PATCH 17/19] add resize methods method in CommandArrays (it allows user to work without casting to the concrete class result of MDI.getCommandArray()) move getTotalDataSize in CommandArrays interfaces comply with other DrawElementsXXX removing parameters in mdi constructors and add several method ( allow use of osgUtil::DrawElementTypeSimplifer on these) --- include/osg/PrimitiveSetIndirect | 121 +++++++++++++++++++++++++------ 1 file changed, 97 insertions(+), 24 deletions(-) diff --git a/include/osg/PrimitiveSetIndirect b/include/osg/PrimitiveSetIndirect index e18d17e1e..96a7c070f 100644 --- a/include/osg/PrimitiveSetIndirect +++ b/include/osg/PrimitiveSetIndirect @@ -31,6 +31,8 @@ public: IndirectCommandDrawArrays(const IndirectCommandDrawArrays& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/) : BufferData(copy, copyop) {} + virtual unsigned int getTotalDataSize() const { return getNumElements()*getElementSize(); } + virtual unsigned int & count(const unsigned int&index)=0; virtual unsigned int & instanceCount(const unsigned int&index)=0; virtual unsigned int & first(const unsigned int&index)=0; @@ -38,6 +40,7 @@ public: virtual unsigned int getElementSize() const = 0; virtual unsigned int getNumElements() const = 0; + virtual void resize(const unsigned int) = 0; }; class OSG_EXPORT IndirectCommandDrawElements: public BufferData @@ -48,6 +51,8 @@ public: IndirectCommandDrawElements(const IndirectCommandDrawElements& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/) : BufferData(copy, copyop) {} + virtual unsigned int getTotalDataSize() const { return getNumElements()*getElementSize(); } + virtual unsigned int & count(const unsigned int&index)=0; virtual unsigned int & instanceCount(const unsigned int&index)=0; virtual unsigned int & firstIndex(const unsigned int&index)=0; @@ -56,6 +61,7 @@ public: virtual unsigned int getElementSize()const = 0; virtual unsigned int getNumElements() const = 0; + virtual void resize(const unsigned int) = 0; }; @@ -84,13 +90,15 @@ public: IndirectCommandDrawArrays(copy, copyop),MixinVector() {} virtual const GLvoid* getDataPointer() const { return empty()?0:&front(); } - virtual unsigned int getTotalDataSize() const { return 16u*static_cast(size()); } virtual unsigned int getElementSize()const { return 16u; }; + virtual unsigned int getNumElements() const { return static_cast(size()); } + virtual void resize(const unsigned int n) {resize(n);} + virtual unsigned int & count(const unsigned int&index) { return at(index).count; } virtual unsigned int & instanceCount(const unsigned int&index) { return at(index).instanceCount; } virtual unsigned int & first(const unsigned int&index) { return at(index).first; } virtual unsigned int & baseInstance(const unsigned int&index) { return at(index).baseInstance; } - virtual unsigned int getNumElements() const { return static_cast(size()); } + }; @@ -120,15 +128,17 @@ public: IndirectCommandDrawElements(copy, copyop), MixinVector() {} virtual const GLvoid* getDataPointer() const { return empty()?0:&front(); } - virtual unsigned int getTotalDataSize() const { return 20u*static_cast(size()); } - + virtual unsigned int getNumElements() const { return static_cast(size()); } virtual unsigned int getElementSize()const { return 20u; }; + virtual void resize(const unsigned int n) {resize(n);} + virtual unsigned int & count(const unsigned int&index) { return at(index).count; } virtual unsigned int & instanceCount(const unsigned int&index) { return at(index).instanceCount; } virtual unsigned int & firstIndex(const unsigned int&index) { return at(index).firstIndex; } virtual unsigned int & baseVertex(const unsigned int&index) { return at(index).baseVertex; } virtual unsigned int & baseInstance(const unsigned int&index) { return at(index).baseInstance; } - virtual unsigned int getNumElements() const { return static_cast(size()); } + + }; /////////////////////////////////////////////////////////////////////////////////////// @@ -191,8 +201,8 @@ public: typedef VectorGLubyte vector_type; - DrawElementsIndirectUByte(GLenum mode = 0,unsigned int firstCommand = 0, GLsizei stride = 0) : - DrawElementsIndirect(DrawElementsUByteIndirectPrimitiveType,mode,firstCommand,stride) {} + DrawElementsIndirectUByte(GLenum mode = 0/*,unsigned int firstCommand = 0, GLsizei stride = 0*/) : + DrawElementsIndirect(DrawElementsUByteIndirectPrimitiveType,mode) {} DrawElementsIndirectUByte(const DrawElementsIndirectUByte& array, const CopyOp& copyop=CopyOp::SHALLOW_COPY) : DrawElementsIndirect(array,copyop), @@ -204,7 +214,7 @@ public: * \param ptr Pointer to a GLubyte to copy index data from. */ DrawElementsIndirectUByte(GLenum mode, unsigned int no, const GLubyte* ptr) : - DrawElementsIndirect(MultiDrawElementsUByteIndirectPrimitiveType,mode), + DrawElementsIndirect(DrawElementsUByteIndirectPrimitiveType,mode), vector_type(ptr,ptr+no) {} /** @@ -212,7 +222,7 @@ public: * \param no Number of intended elements. This will be the size of the underlying vector. */ DrawElementsIndirectUByte(GLenum mode, unsigned int no) : - DrawElementsIndirect(MultiDrawElementsUByteIndirectPrimitiveType,mode), + DrawElementsIndirect(DrawElementsUByteIndirectPrimitiveType,mode), vector_type(no) {} virtual Object* cloneType() const { return new DrawElementsIndirectUByte(); } @@ -260,8 +270,8 @@ public: typedef VectorGLushort vector_type; - DrawElementsIndirectUShort(GLenum mode = 0,unsigned int firstCommand = 0, GLsizei stride = 0) : - DrawElementsIndirect(DrawElementsUShortIndirectPrimitiveType,mode,firstCommand,stride) {} + DrawElementsIndirectUShort(GLenum mode = 0/*,unsigned int firstCommand = 0, GLsizei stride = 0*/) : + DrawElementsIndirect(DrawElementsUShortIndirectPrimitiveType,mode) {} DrawElementsIndirectUShort(const DrawElementsIndirectUShort& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY) : DrawElementsIndirect(array,copyop), @@ -273,7 +283,7 @@ public: * \param ptr Pointer to a GLushort to copy index data from. */ DrawElementsIndirectUShort(GLenum mode, unsigned int no, const GLushort* ptr) : - DrawElementsIndirect(MultiDrawElementsUShortIndirectPrimitiveType,mode), + DrawElementsIndirect(DrawElementsUShortIndirectPrimitiveType,mode), vector_type(ptr,ptr+no) {} /** @@ -281,12 +291,12 @@ public: * \param no Number of intended elements. This will be the size of the underlying vector. */ DrawElementsIndirectUShort(GLenum mode, unsigned int no) : - DrawElementsIndirect(MultiDrawElementsUShortIndirectPrimitiveType,mode), + DrawElementsIndirect(DrawElementsUShortIndirectPrimitiveType,mode), vector_type(no) {} template DrawElementsIndirectUShort(GLenum mode, InputIterator first,InputIterator last) : - DrawElementsIndirect(MultiDrawElementsUShortIndirectPrimitiveType,mode), + DrawElementsIndirect(DrawElementsUShortIndirectPrimitiveType,mode), vector_type(first,last) {} virtual Object* cloneType() const { return new DrawElementsIndirectUShort(); } @@ -332,8 +342,8 @@ public: typedef VectorGLuint vector_type; - DrawElementsIndirectUInt(GLenum mode = 0,unsigned int firstCommand = 0, GLsizei stride = 0) : - DrawElementsIndirect(DrawElementsUIntIndirectPrimitiveType,mode,firstCommand,stride) {} + DrawElementsIndirectUInt(GLenum mode = 0/*,unsigned int firstCommand = 0, GLsizei stride = 0*/) : + DrawElementsIndirect(DrawElementsUIntIndirectPrimitiveType,mode) {} DrawElementsIndirectUInt(const DrawElementsIndirectUInt& array,const CopyOp& copyop=CopyOp::SHALLOW_COPY) : DrawElementsIndirect(array,copyop), @@ -353,12 +363,12 @@ public: * \param no Number of intended elements. This will be the size of the underlying vector. */ DrawElementsIndirectUInt(GLenum mode, unsigned int no) : - DrawElementsIndirect(MultiDrawElementsUIntIndirectPrimitiveType,mode), + DrawElementsIndirect(DrawElementsUIntIndirectPrimitiveType,mode), vector_type(no) {} template DrawElementsIndirectUInt(GLenum mode, InputIterator first,InputIterator last) : - DrawElementsIndirect(MultiDrawElementsUIntIndirectPrimitiveType,mode), + DrawElementsIndirect(DrawElementsUIntIndirectPrimitiveType,mode), vector_type(first,last) {} virtual Object* cloneType() const { return new DrawElementsIndirectUInt(); } @@ -400,11 +410,32 @@ protected: class OSG_EXPORT MultiDrawElementsIndirectUShort : public DrawElementsIndirectUShort { public: - MultiDrawElementsIndirectUShort(GLenum mode = 0,unsigned int firstCommand = 0,unsigned int commandcount = 0, GLsizei stride = 0) : - DrawElementsIndirectUShort(mode,firstCommand,stride),_count(commandcount) { _primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType)); } + MultiDrawElementsIndirectUShort(GLenum mode = 0/*,unsigned int firstCommand = 0, GLsizei stride = 0*/) : + DrawElementsIndirectUShort(mode),_count(0) { _primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType)); } MultiDrawElementsIndirectUShort(const MultiDrawElementsIndirectUShort& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY) : DrawElementsIndirectUShort(mdi,copyop),_count(mdi._count) {} + /** + * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used. + * \param no Number of intended elements. This will be the size of the underlying vector. + * \param ptr Pointer to a GLunsigned int to copy index data from. + */ + MultiDrawElementsIndirectUShort(GLenum mode, unsigned int no, const GLushort* ptr) : + DrawElementsIndirectUShort(mode,no,ptr) + {_primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType));} + + /** + * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used. + * \param no Number of intended elements. This will be the size of the underlying vector. + */ + MultiDrawElementsIndirectUShort(GLenum mode, unsigned int no) : + DrawElementsIndirectUShort(mode,no) + {_primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType));} + + template + MultiDrawElementsIndirectUShort(GLenum mode, InputIterator first,InputIterator last) : + DrawElementsIndirectUShort(mode,first,last) + {_primitiveType=(Type(MultiDrawElementsUShortIndirectPrimitiveType));} virtual osg::Object* cloneType() const { return new MultiDrawElementsIndirectUShort(); } virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new MultiDrawElementsIndirectUShort(*this,copyop); } @@ -431,11 +462,32 @@ protected: class OSG_EXPORT MultiDrawElementsIndirectUByte : public DrawElementsIndirectUByte { public: - MultiDrawElementsIndirectUByte(GLenum mode = 0,unsigned int firstCommand = 0,unsigned int commandcount = 0, GLsizei stride = 0) : - DrawElementsIndirectUByte(mode,firstCommand,stride),_count(commandcount) { _primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType)); } + MultiDrawElementsIndirectUByte(GLenum mode = 0) : + DrawElementsIndirectUByte(mode),_count(0) { _primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType)); } MultiDrawElementsIndirectUByte(const MultiDrawElementsIndirectUByte& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY) : DrawElementsIndirectUByte(mdi,copyop),_count(mdi._count) {} + /** + * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used. + * \param no Number of intended elements. This will be the size of the underlying vector. + * \param ptr Pointer to a GLunsigned int to copy index data from. + */ + MultiDrawElementsIndirectUByte(GLenum mode, unsigned int no, const GLubyte* ptr) : + DrawElementsIndirectUByte(mode,no,ptr) + {_primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType));} + + /** + * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used. + * \param no Number of intended elements. This will be the size of the underlying vector. + */ + MultiDrawElementsIndirectUByte(GLenum mode, unsigned int no) : + DrawElementsIndirectUByte(mode,no) + {_primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType));} + + template + MultiDrawElementsIndirectUByte(GLenum mode, InputIterator first,InputIterator last) : + DrawElementsIndirectUByte(mode,first,last) + {_primitiveType=(Type(MultiDrawElementsUByteIndirectPrimitiveType));} virtual osg::Object* cloneType() const { return new MultiDrawElementsIndirectUByte(); } virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new MultiDrawElementsIndirectUByte(*this,copyop); } @@ -460,11 +512,32 @@ protected: class OSG_EXPORT MultiDrawElementsIndirectUInt : public DrawElementsIndirectUInt { public: - MultiDrawElementsIndirectUInt(GLenum mode = 0,unsigned int firstCommand = 0,unsigned int commandcount = 0, GLsizei stride = 0) : - DrawElementsIndirectUInt(mode,firstCommand,stride),_count(commandcount) { _primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType)); } + MultiDrawElementsIndirectUInt(GLenum mode = 0) : + DrawElementsIndirectUInt(mode),_count(0) { _primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType)); } MultiDrawElementsIndirectUInt(const MultiDrawElementsIndirectUInt& mdi,const CopyOp& copyop=CopyOp::SHALLOW_COPY) : DrawElementsIndirectUInt(mdi,copyop),_count(mdi._count) {} + /** + * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used. + * \param no Number of intended elements. This will be the size of the underlying vector. + * \param ptr Pointer to a GLunsigned int to copy index data from. + */ + MultiDrawElementsIndirectUInt(GLenum mode, unsigned int no, const GLuint* ptr) : + DrawElementsIndirectUInt(mode,no,ptr) + {_primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType));} + + /** + * \param mode One of osg::PrimitiveSet::Mode. Determines the type of primitives used. + * \param no Number of intended elements. This will be the size of the underlying vector. + */ + MultiDrawElementsIndirectUInt(GLenum mode, unsigned int no) : + DrawElementsIndirectUInt(mode,no) + {_primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType));} + + template + MultiDrawElementsIndirectUInt(GLenum mode, InputIterator first,InputIterator last) : + DrawElementsIndirectUInt(mode,first,last) + {_primitiveType=(Type(MultiDrawElementsUIntIndirectPrimitiveType));} virtual osg::Object* cloneType() const { return new MultiDrawElementsIndirectUInt(); } virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new MultiDrawElementsIndirectUInt(*this,copyop); } From 35eb53cc95b2ac781a45a24ce4f772d368b1ac3b Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Wed, 2 Aug 2017 22:10:02 +0200 Subject: [PATCH 18/19] add MDI support --- src/osgUtil/DrawElementTypeSimplifier.cpp | 39 +++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/osgUtil/DrawElementTypeSimplifier.cpp b/src/osgUtil/DrawElementTypeSimplifier.cpp index 6397f8e06..14f359649 100644 --- a/src/osgUtil/DrawElementTypeSimplifier.cpp +++ b/src/osgUtil/DrawElementTypeSimplifier.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -61,6 +62,44 @@ void DrawElementTypeSimplifier::simplify(osg::Geometry & geometry) const break; } + case osg::PrimitiveSet::DrawElementsUShortIndirectPrimitiveType: + { + osg::DrawElementsIndirectUShort & de = *static_cast(it->get()); + + max = getMax(de); + if (max < 255) *it = copy(de); + + break; + } + case osg::PrimitiveSet::DrawElementsUIntIndirectPrimitiveType: + { + osg::DrawElementsIndirectUInt & de = *static_cast(it->get()); + + max = getMax(de); + if (max < 256) *it = copy(de); + else if (max < 65536) *it = copy(de); + + break; + } + case osg::PrimitiveSet::MultiDrawElementsUShortIndirectPrimitiveType: + { + osg::MultiDrawElementsIndirectUShort & de = *static_cast(it->get()); + + max = getMax(de); + if (max < 255) *it = copy(de); + + break; + } + case osg::PrimitiveSet::MultiDrawElementsUIntIndirectPrimitiveType: + { + osg::MultiDrawElementsIndirectUInt & de = *static_cast(it->get()); + + max = getMax(de); + if (max < 256) *it = copy(de); + else if (max < 65536) *it = copy(de); + + break; + } default: break; } } From 899a704eb7712d3a2715cb9a768408751019b4c9 Mon Sep 17 00:00:00 2001 From: Julien Valentin Date: Sat, 5 Aug 2017 18:03:27 +0200 Subject: [PATCH 19/19] update IndirectCommandArrays interfaces and default impl to use DrawElements like semantic --- include/osg/PrimitiveSetIndirect | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/include/osg/PrimitiveSetIndirect b/include/osg/PrimitiveSetIndirect index 96a7c070f..2ce5c1d8d 100644 --- a/include/osg/PrimitiveSetIndirect +++ b/include/osg/PrimitiveSetIndirect @@ -40,7 +40,8 @@ public: virtual unsigned int getElementSize() const = 0; virtual unsigned int getNumElements() const = 0; - virtual void resize(const unsigned int) = 0; + virtual void reserveElements(const unsigned int) = 0; + virtual void resizeElements(const unsigned int) = 0; }; class OSG_EXPORT IndirectCommandDrawElements: public BufferData @@ -61,7 +62,8 @@ public: virtual unsigned int getElementSize()const = 0; virtual unsigned int getNumElements() const = 0; - virtual void resize(const unsigned int) = 0; + virtual void reserveElements(const unsigned int) = 0; + virtual void resizeElements(const unsigned int) = 0; }; @@ -92,7 +94,8 @@ public: virtual const GLvoid* getDataPointer() const { return empty()?0:&front(); } virtual unsigned int getElementSize()const { return 16u; }; virtual unsigned int getNumElements() const { return static_cast(size()); } - virtual void resize(const unsigned int n) {resize(n);} + virtual void reserveElements(const unsigned int n) {reserve(n);} + virtual void resizeElements(const unsigned int n) {resize(n);} virtual unsigned int & count(const unsigned int&index) { return at(index).count; } virtual unsigned int & instanceCount(const unsigned int&index) { return at(index).instanceCount; } @@ -130,7 +133,8 @@ public: virtual const GLvoid* getDataPointer() const { return empty()?0:&front(); } virtual unsigned int getNumElements() const { return static_cast(size()); } virtual unsigned int getElementSize()const { return 20u; }; - virtual void resize(const unsigned int n) {resize(n);} + virtual void reserveElements(const unsigned int n) {reserve(n);} + virtual void resizeElements(const unsigned int n) {resize(n);} virtual unsigned int & count(const unsigned int&index) { return at(index).count; } virtual unsigned int & instanceCount(const unsigned int&index) { return at(index).instanceCount; }