From 5cb486f7c5774a045d4a7c8cab26298803206ef8 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 22 Jan 2016 09:47:49 +0000 Subject: [PATCH] Added osg::MultiDrawArrays which wraps up glMultiDrawArrays extension. --- include/osg/GLExtensions | 4 + include/osg/PrimitiveSet | 56 +++++++- src/osg/GLExtensions.cpp | 6 +- src/osg/PrimitiveSet.cpp | 123 +++++++++++++++++- .../serializers/osg/PrimitiveSet.cpp | 15 +++ 5 files changed, 200 insertions(+), 4 deletions(-) diff --git a/include/osg/GLExtensions b/include/osg/GLExtensions index 31b8c7b34..ea8e9945c 100644 --- a/include/osg/GLExtensions +++ b/include/osg/GLExtensions @@ -609,6 +609,10 @@ class OSG_EXPORT GLExtensions : public osg::Referenced GLboolean (GL_APIENTRY * glIsVertexArray) (GLuint handle); void (GL_APIENTRY * glBindVertexArray) (GLuint handle); + // MultiDrawArrays + void (GL_APIENTRY * glMultiDrawArrays) (GLenum mode, const GLint * first, const GLsizei * count, GLsizei primcount); + + }; diff --git a/include/osg/PrimitiveSet b/include/osg/PrimitiveSet index b9168add9..f3893647b 100644 --- a/include/osg/PrimitiveSet +++ b/include/osg/PrimitiveSet @@ -29,6 +29,8 @@ #include +#define OSG_HAS_MULTIDRAWARRAYS + namespace osg { typedef MixinVector VectorGLsizei; @@ -174,7 +176,8 @@ class OSG_EXPORT PrimitiveSet : public BufferData DrawArrayLengthsPrimitiveType, DrawElementsUBytePrimitiveType, DrawElementsUShortPrimitiveType, - DrawElementsUIntPrimitiveType + DrawElementsUIntPrimitiveType, + MultiDrawArraysPrimitiveType }; enum Mode @@ -587,6 +590,57 @@ class OSG_EXPORT DrawElementsUInt : public DrawElements, public VectorGLuint virtual ~DrawElementsUInt(); }; +#ifdef OSG_HAS_MULTIDRAWARRAYS +class OSG_EXPORT MultiDrawArrays : public osg::PrimitiveSet +{ +public: + + MultiDrawArrays(GLenum mode=0): + osg::PrimitiveSet(Type(MultiDrawArraysPrimitiveType), mode) {} + + MultiDrawArrays(const MultiDrawArrays& dal,const CopyOp& copyop=CopyOp::SHALLOW_COPY): + osg::PrimitiveSet(dal,copyop), + _firsts(dal._firsts), + _counts(dal._counts) {} + + virtual osg::Object* cloneType() const { return new MultiDrawArrays(); } + virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new MultiDrawArrays(*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 "MultiDrawArrays"; } + + + virtual void draw(osg::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; + + typedef std::vector Firsts; + void setFirsts(const Firsts& firsts) { _firsts = firsts; } + Firsts& getFirsts() { return _firsts; } + const Firsts& getFirsts() const { return _firsts; } + + typedef std::vector Counts; + void setCounts(const Counts& firsts) { _counts = firsts; } + Counts& getCounts() { return _counts; } + const Counts& getCounts() const { return _counts; } + + void add(GLint first, GLsizei count); + +protected: + + Firsts _firsts; + Counts _counts; +}; +#endif + + } #endif diff --git a/src/osg/GLExtensions.cpp b/src/osg/GLExtensions.cpp index 24e49917b..681930e52 100644 --- a/src/osg/GLExtensions.cpp +++ b/src/osg/GLExtensions.cpp @@ -1034,7 +1034,7 @@ GLExtensions::GLExtensions(unsigned int contextID) glGenerateMipmap != 0 && glGetRenderbufferParameteriv != 0 && ( OSG_GLES1_FEATURES || isGLExtensionOrVersionSupported(contextID, "GL_EXT_framebuffer_object",3.0f) ); - + isPackedDepthStencilSupported = OSG_GL3_FEATURES || (isGLExtensionSupported(contextID, "GL_EXT_packed_depth_stencil")) || @@ -1077,7 +1077,9 @@ GLExtensions::GLExtensions(unsigned int contextID) osg::setGLExtensionFuncPtr(glBindVertexArray,"glBindVertexArray"); osg::setGLExtensionFuncPtr(glDeleteVertexArrays,"glDeleteVertexArrays"); osg::setGLExtensionFuncPtr(glIsVertexArray,"glIsVertexArray"); - + + // MultiDrawArrays + setGLExtensionFuncPtr(glMultiDrawArrays, "glMultiDrawArrays", "glMultiDrawArraysEXT"); } diff --git a/src/osg/PrimitiveSet.cpp b/src/osg/PrimitiveSet.cpp index 9bb9fb7be..acb8a16d4 100644 --- a/src/osg/PrimitiveSet.cpp +++ b/src/osg/PrimitiveSet.cpp @@ -17,6 +17,10 @@ using namespace osg; +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// PrimitiveSet +// unsigned int PrimitiveSet::getNumPrimitives() const { switch(_mode) @@ -36,6 +40,10 @@ unsigned int PrimitiveSet::getNumPrimitives() const return 0; } +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// DrawArray +// void DrawArrays::draw(State& state, bool) const { #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) @@ -72,6 +80,10 @@ void DrawArrays::accept(PrimitiveIndexFunctor& functor) const functor.drawArrays(_mode,_first,_count); } +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// DrawArrayLengths +// unsigned int DrawArrayLengths::getNumPrimitives() const { switch(_mode) @@ -159,6 +171,10 @@ unsigned int DrawArrayLengths::getNumIndices() const return count; } +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// DrawElementsUByte +// DrawElementsUByte::~DrawElementsUByte() { releaseGLObjects(); @@ -215,6 +231,10 @@ void DrawElementsUByte::offsetIndices(int offset) } +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// DrawElementsUShort +// DrawElementsUShort::~DrawElementsUShort() { releaseGLObjects(); @@ -270,7 +290,10 @@ void DrawElementsUShort::offsetIndices(int offset) } } - +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// DrawElementsUInt +// DrawElementsUInt::~DrawElementsUInt() { releaseGLObjects(); @@ -325,3 +348,101 @@ void DrawElementsUInt::offsetIndices(int offset) *itr += offset; } } + +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// MultiDrawArrays +// +#ifdef OSG_HAS_MULTIDRAWARRAYS +void MultiDrawArrays::draw(osg::State& state, bool) const +{ + // OSG_NOTICE<<"osg::MultiDrawArrays::draw"<(); + if (ext->glMultiDrawArrays) + { + GLsizei primcount = std::min(_firsts.size(), _counts.size()); + + ext->glMultiDrawArrays(_mode, &_firsts.front(), &_counts.front(), primcount); + } +} + +void MultiDrawArrays::accept(PrimitiveFunctor& functor) const +{ + unsigned int primcount = std::min(_firsts.size(), _counts.size()); + for(unsigned int i=0; i=_firsts.size()) return 0; + + return _firsts[i] + pos; +} + +void MultiDrawArrays::offsetIndices(int offset) +{ + for(Firsts::iterator itr = _firsts.begin(); itr!=_firsts.end(); ++itr) + { + *itr += offset; + } +} + +unsigned int MultiDrawArrays::getNumPrimitives() const +{ + switch(_mode) + { + case(POINTS): return getNumIndices(); + case(LINES): return getNumIndices()/2; + case(TRIANGLES): return getNumIndices()/3; + case(QUADS): return getNumIndices()/4; + case(LINE_STRIP): + case(LINE_LOOP): + case(TRIANGLE_STRIP): + case(TRIANGLE_FAN): + case(QUAD_STRIP): + case(PATCHES): + case(POLYGON): + { + unsigned int primcount = std::min(_firsts.size(), _counts.size()); + return primcount; + } + } + return 0; +} + +void MultiDrawArrays::add(GLint first, GLsizei count) +{ + _firsts.push_back(first); + _counts.push_back(count); +} +#endif \ No newline at end of file diff --git a/src/osgWrappers/serializers/osg/PrimitiveSet.cpp b/src/osgWrappers/serializers/osg/PrimitiveSet.cpp index 3ab2aeeb9..c35bd6685 100644 --- a/src/osgWrappers/serializers/osg/PrimitiveSet.cpp +++ b/src/osgWrappers/serializers/osg/PrimitiveSet.cpp @@ -149,3 +149,18 @@ REGISTER_OBJECT_WRAPPER( DrawElements, DRAW_ELEMENTS_WRAPPER( DrawElementsUByte, RW_UCHAR ) DRAW_ELEMENTS_WRAPPER( DrawElementsUShort, RW_USHORT ) DRAW_ELEMENTS_WRAPPER( DrawElementsUInt, RW_UINT ) + +#ifdef OSG_HAS_MULTIDRAWARRAYS +namespace MultiDrawArrayWrapper { + +REGISTER_OBJECT_WRAPPER( MultiDrawArrays, + new osg::MultiDrawArrays, + osg::MultiDrawArrays, + "osg::Object osg::PrimitiveSet osg::MultiDrawArrays" ) +{ + ADD_VECTOR_SERIALIZER( Firsts, osg::MultiDrawArrays::Firsts, osgDB::BaseSerializer::RW_INT, 8 ); + ADD_VECTOR_SERIALIZER( Counts, osg::MultiDrawArrays::Counts, osgDB::BaseSerializer::RW_INT, 8 ); +} + +} +#endif \ No newline at end of file