Added osg::MultiDrawArrays which wraps up glMultiDrawArrays extension.
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#define OSG_HAS_MULTIDRAWARRAYS
|
||||
|
||||
namespace osg {
|
||||
|
||||
typedef MixinVector<GLsizei> 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<const MultiDrawArrays*>(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<GLint> Firsts;
|
||||
void setFirsts(const Firsts& firsts) { _firsts = firsts; }
|
||||
Firsts& getFirsts() { return _firsts; }
|
||||
const Firsts& getFirsts() const { return _firsts; }
|
||||
|
||||
typedef std::vector<GLsizei> 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
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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"<<std::endl;
|
||||
|
||||
GLExtensions* ext = state.get<GLExtensions>();
|
||||
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<primcount; ++i)
|
||||
{
|
||||
functor.drawArrays(_mode, _firsts[i], _counts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void MultiDrawArrays::accept(PrimitiveIndexFunctor& functor) const
|
||||
{
|
||||
unsigned int primcount = std::min(_firsts.size(), _counts.size());
|
||||
for(unsigned int i=0; i<primcount; ++i)
|
||||
{
|
||||
functor.drawArrays(_mode, _firsts[i], _counts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int MultiDrawArrays::getNumIndices() const
|
||||
{
|
||||
unsigned int total=0;
|
||||
for(Counts::const_iterator itr = _counts.begin(); itr!=_counts.end(); ++itr)
|
||||
{
|
||||
total += *itr;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
unsigned int MultiDrawArrays::index(unsigned int pos) const
|
||||
{
|
||||
unsigned int i;
|
||||
for(i=0; i<_counts.size(); ++i)
|
||||
{
|
||||
unsigned int count = _counts[i];
|
||||
if (pos<count) break;
|
||||
pos -= count;
|
||||
}
|
||||
if (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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user