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
This commit is contained in:
parent
c32d3eb926
commit
5be14bc2ba
@ -1,13 +1,11 @@
|
|||||||
SET(TARGET_SRC
|
SET(TARGET_SRC
|
||||||
ShapeToGeometry.cpp
|
ShapeToGeometry.cpp
|
||||||
DrawIndirectPrimitiveSet.cpp
|
|
||||||
AggregateGeometryVisitor.cpp
|
AggregateGeometryVisitor.cpp
|
||||||
osggpucull.cpp
|
osggpucull.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(TARGET_H
|
SET(TARGET_H
|
||||||
ShapeToGeometry.h
|
ShapeToGeometry.h
|
||||||
DrawIndirectPrimitiveSet.h
|
|
||||||
AggregateGeometryVisitor.h
|
AggregateGeometryVisitor.h
|
||||||
GpuCullShaders.h
|
GpuCullShaders.h
|
||||||
)
|
)
|
||||||
|
@ -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 <osg/State>
|
|
||||||
#include <osg/buffered_value>
|
|
||||||
#include <osg/ref_ptr>
|
|
||||||
#include <osg/GLExtensions>
|
|
||||||
#include <osg/Drawable>
|
|
||||||
|
|
||||||
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 ("<<val<<"): "<< tab[val] << " " << tab[val+1] << " " << tab[val+2] << " " << tab[val+3] << std::endl;
|
|
||||||
// dext->glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
|
|
||||||
|
|
||||||
state.get<osg::GLExtensions>()->glDrawArraysIndirect( _mode, reinterpret_cast<const void*>(_indirect) );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void MultiDrawArraysIndirect::draw(osg::State& state, bool /*useVertexBufferObjects*/) const
|
|
||||||
{
|
|
||||||
// DrawIndirectGLExtensions *ext = DrawIndirectGLExtensions::getExtensions( state.getContextID(),true );
|
|
||||||
state.get<osg::GLExtensions>()->glMultiDrawArraysIndirect( _mode, reinterpret_cast<const void*>(_indirect), _drawcount, _stride );
|
|
||||||
}
|
|
@ -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 <osg/PrimitiveSet>
|
|
||||||
#include <osg/BufferObject>
|
|
||||||
#include <osg/TextureBuffer>
|
|
||||||
|
|
||||||
|
|
||||||
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<const DrawArraysIndirect*>(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<const MultiDrawArraysIndirect*>(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
|
|
@ -38,12 +38,14 @@
|
|||||||
#include <osg/BufferTemplate>
|
#include <osg/BufferTemplate>
|
||||||
#include "ShapeToGeometry.h"
|
#include "ShapeToGeometry.h"
|
||||||
#include "AggregateGeometryVisitor.h"
|
#include "AggregateGeometryVisitor.h"
|
||||||
|
#if 0
|
||||||
#include "DrawIndirectPrimitiveSet.h"
|
#include "DrawIndirectPrimitiveSet.h"
|
||||||
|
#else
|
||||||
|
#include <osg/PrimitiveSetIndirect>
|
||||||
|
#endif
|
||||||
#include "GpuCullShaders.h"
|
#include "GpuCullShaders.h"
|
||||||
|
|
||||||
#ifndef GL_RASTERIZER_DISCARD
|
|
||||||
#define GL_RASTERIZER_DISCARD 0x8C89
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// each instance type may have max 8 LODs ( if you change
|
// each instance type may have max 8 LODs ( if you change
|
||||||
// this value, don't forget to change it in vertex shaders accordingly )
|
// this value, don't forget to change it in vertex shaders accordingly )
|
||||||
@ -178,23 +180,20 @@ struct IndirectTarget
|
|||||||
IndirectTarget()
|
IndirectTarget()
|
||||||
: maxTargetQuantity(0)
|
: maxTargetQuantity(0)
|
||||||
{
|
{
|
||||||
indirectCommands = new osg::BufferTemplate< std::vector<DrawArraysIndirectCommand> >;
|
indirectCommands = new osg::DefaultIndirectCommandDrawArrays;
|
||||||
}
|
}
|
||||||
IndirectTarget( AggregateGeometryVisitor* agv, osg::Program* program )
|
IndirectTarget( AggregateGeometryVisitor* agv, osg::Program* program )
|
||||||
: geometryAggregator(agv), drawProgram(program), maxTargetQuantity(0)
|
: geometryAggregator(agv), drawProgram(program), maxTargetQuantity(0)
|
||||||
{
|
{
|
||||||
indirectCommands = new osg::BufferTemplate< std::vector<DrawArraysIndirectCommand> >;
|
indirectCommands = new osg::DefaultIndirectCommandDrawArrays;
|
||||||
}
|
}
|
||||||
void endRegister(unsigned int index, unsigned int rowsPerInstance, GLenum pixelFormat, GLenum type, GLint internalFormat, bool useMultiDrawArraysIndirect )
|
void endRegister(unsigned int index, unsigned int rowsPerInstance, GLenum pixelFormat, GLenum type, GLint internalFormat, bool useMultiDrawArraysIndirect )
|
||||||
{
|
{
|
||||||
osg::Image* indirectCommandImage = new osg::Image;
|
osg::VertexBufferObject * indirectCommandbuffer=new osg::VertexBufferObject();
|
||||||
indirectCommandImage->setImage( indirectCommands->getTotalDataSize()/sizeof(unsigned int), 1, 1, GL_R32I, GL_RED, GL_UNSIGNED_INT, (unsigned char*)indirectCommands->getDataPointer(), osg::Image::NO_DELETE );
|
indirectCommandbuffer->setUsage(GL_DYNAMIC_DRAW);
|
||||||
|
indirectCommands->setBufferObject(indirectCommandbuffer);
|
||||||
|
|
||||||
osg::VertexBufferObject * indirectCommandImagebuffer=new osg::VertexBufferObject();
|
indirectCommandTextureBuffer = new osg::TextureBuffer(indirectCommands);
|
||||||
indirectCommandImagebuffer->setUsage(GL_DYNAMIC_DRAW);
|
|
||||||
indirectCommandImage->setBufferObject(indirectCommandImagebuffer);
|
|
||||||
|
|
||||||
indirectCommandTextureBuffer = new osg::TextureBuffer(indirectCommandImage);
|
|
||||||
indirectCommandTextureBuffer->setInternalFormat( GL_R32I );
|
indirectCommandTextureBuffer->setInternalFormat( GL_R32I );
|
||||||
indirectCommandTextureBuffer->bindToImageUnit(index, osg::Texture::READ_WRITE);
|
indirectCommandTextureBuffer->bindToImageUnit(index, osg::Texture::READ_WRITE);
|
||||||
indirectCommandTextureBuffer->setUnRefImageDataAfterApply(false);
|
indirectCommandTextureBuffer->setUnRefImageDataAfterApply(false);
|
||||||
@ -203,28 +202,29 @@ struct IndirectTarget
|
|||||||
// add proper primitivesets to geometryAggregators
|
// add proper primitivesets to geometryAggregators
|
||||||
if( !useMultiDrawArraysIndirect ) // use glDrawArraysIndirect()
|
if( !useMultiDrawArraysIndirect ) // use glDrawArraysIndirect()
|
||||||
{
|
{
|
||||||
std::vector<DrawArraysIndirect*> newPrimitiveSets;
|
std::vector<osg::DrawArraysIndirect*> newPrimitiveSets;
|
||||||
|
|
||||||
for(unsigned int j=0;j<indirectCommands->getData().size(); ++j)
|
for(unsigned int j=0;j<indirectCommands->size(); ++j){
|
||||||
newPrimitiveSets.push_back( new DrawArraysIndirect( GL_TRIANGLES, j*sizeof( DrawArraysIndirectCommand ) ) );
|
osg::DrawArraysIndirect *ipr=new osg::DrawArraysIndirect( GL_TRIANGLES, j );
|
||||||
|
ipr->setIndirectCommandDrawArrays( indirectCommands);
|
||||||
|
newPrimitiveSets.push_back(ipr);
|
||||||
|
}
|
||||||
|
|
||||||
geometryAggregator->getAggregatedGeometry()->removePrimitiveSet(0,geometryAggregator->getAggregatedGeometry()->getNumPrimitiveSets() );
|
geometryAggregator->getAggregatedGeometry()->removePrimitiveSet(0,geometryAggregator->getAggregatedGeometry()->getNumPrimitiveSets() );
|
||||||
|
|
||||||
for(unsigned int j=0;j<indirectCommands->getData().size(); ++j)
|
for(unsigned int j=0;j<indirectCommands->size(); ++j)
|
||||||
geometryAggregator->getAggregatedGeometry()->addPrimitiveSet( newPrimitiveSets[j] );
|
geometryAggregator->getAggregatedGeometry()->addPrimitiveSet( newPrimitiveSets[j] );
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else // use glMultiDrawArraysIndirect()
|
else // use glMultiDrawArraysIndirect()
|
||||||
{
|
{
|
||||||
|
osg::MultiDrawArraysIndirect *ipr=new osg::MultiDrawArraysIndirect( GL_TRIANGLES );
|
||||||
|
ipr->setIndirectCommandDrawArrays( indirectCommands );
|
||||||
geometryAggregator->getAggregatedGeometry()->removePrimitiveSet(0,geometryAggregator->getAggregatedGeometry()->getNumPrimitiveSets() );
|
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<osg::DrawIndirectBufferBinding> bb=new osg::DrawIndirectBufferBinding();
|
|
||||||
bb->setBufferObject(indirectCommandImage->getBufferObject());
|
|
||||||
geometryAggregator->getAggregatedGeometry()->getOrCreateStateSet()->setAttribute(bb );
|
|
||||||
geometryAggregator->getAggregatedGeometry()->setUseDisplayList(false);
|
geometryAggregator->getAggregatedGeometry()->setUseDisplayList(false);
|
||||||
geometryAggregator->getAggregatedGeometry()->setUseVertexBufferObjects(true);
|
geometryAggregator->getAggregatedGeometry()->setUseVertexBufferObjects(true);
|
||||||
|
|
||||||
@ -268,7 +268,7 @@ struct IndirectTarget
|
|||||||
stateset->setAttributeAndModes( drawProgram.get(), osg::StateAttribute::ON );
|
stateset->setAttributeAndModes( drawProgram.get(), osg::StateAttribute::ON );
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::ref_ptr< osg::BufferTemplate< std::vector<DrawArraysIndirectCommand> > > indirectCommands;
|
osg::ref_ptr< osg::DefaultIndirectCommandDrawArrays > indirectCommands;
|
||||||
osg::ref_ptr<osg::TextureBuffer> indirectCommandTextureBuffer;
|
osg::ref_ptr<osg::TextureBuffer> indirectCommandTextureBuffer;
|
||||||
osg::ref_ptr< AggregateGeometryVisitor > geometryAggregator;
|
osg::ref_ptr< AggregateGeometryVisitor > geometryAggregator;
|
||||||
osg::ref_ptr<osg::Program> drawProgram;
|
osg::ref_ptr<osg::Program> drawProgram;
|
||||||
@ -318,7 +318,7 @@ struct GPUCullData
|
|||||||
// AggregateGeometryVisitor creates single osg::Geometry from all objects used by specific indirect target
|
// AggregateGeometryVisitor creates single osg::Geometry from all objects used by specific indirect target
|
||||||
AggregateGeometryVisitor::AddObjectResult aoResult = target->second.geometryAggregator->addObject( node , typeID, lodNumber );
|
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
|
// 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;
|
osg::ComputeBoundsVisitor cbv;
|
||||||
node->accept(cbv);
|
node->accept(cbv);
|
||||||
@ -360,10 +360,10 @@ struct GPUCullData
|
|||||||
std::map<unsigned int, IndirectTarget>::iterator it,eit;
|
std::map<unsigned int, IndirectTarget>::iterator it,eit;
|
||||||
for(it=targets.begin(), eit=targets.end(); it!=eit; ++it)
|
for(it=targets.begin(), eit=targets.end(); it!=eit; ++it)
|
||||||
{
|
{
|
||||||
for(unsigned j=0; j<it->second.indirectCommands->getData().size(); ++j)
|
for(unsigned j=0; j<it->second.indirectCommands->size(); ++j)
|
||||||
{
|
{
|
||||||
DrawArraysIndirectCommand& iComm = it->second.indirectCommands->getData().at(j);
|
osg::DrawArraysIndirectCommand& iComm = it->second.indirectCommands->at(j);
|
||||||
OSG_INFO<<"("<<iComm.first<<" "<<iComm.primCount<<" "<<iComm.count<<") ";
|
OSG_INFO<<"("<<iComm.first<<" "<<iComm.instanceCount<<" "<<iComm.count<<") ";
|
||||||
}
|
}
|
||||||
unsigned int sizeInBytes = (unsigned int ) it->second.maxTargetQuantity * sizeof(osg::Vec4);
|
unsigned int sizeInBytes = (unsigned int ) it->second.maxTargetQuantity * sizeof(osg::Vec4);
|
||||||
OSG_INFO<<" => Maximum elements in target : "<< it->second.maxTargetQuantity <<" ( "<< sizeInBytes <<" bytes, " << sizeInBytes/1024<< " kB )" << std::endl;
|
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<unsigned int>::iterator it,eit;
|
std::vector<unsigned int>::iterator it,eit;
|
||||||
for(it=texUnitsDirty.begin(), eit=texUnitsDirty.end(); it!=eit; ++it)
|
for(it=texUnitsDirty.begin(), eit=texUnitsDirty.end(); it!=eit; ++it)
|
||||||
{
|
{
|
||||||
osg::Texture* tex = dynamic_cast<osg::Texture*>( stateset->getTextureAttribute(*it,osg::StateAttribute::TEXTURE) );
|
osg::TextureBuffer* tex = dynamic_cast<osg::TextureBuffer*>( stateset->getTextureAttribute(*it,osg::StateAttribute::TEXTURE) );
|
||||||
if(tex==NULL)
|
if(tex==NULL)
|
||||||
continue;
|
continue;
|
||||||
osg::Image* img = tex->getImage(0);
|
osg::BufferData* img =const_cast<osg::BufferData*>(tex->getBufferData());
|
||||||
if(img!=NULL)
|
if(img!=NULL)
|
||||||
img->dirty();
|
img->dirty();
|
||||||
}
|
}
|
||||||
for(it=texUnitsDirtyParams.begin(), eit=texUnitsDirtyParams.end(); it!=eit; ++it)
|
for(it=texUnitsDirtyParams.begin(), eit=texUnitsDirtyParams.end(); it!=eit; ++it)
|
||||||
{
|
{
|
||||||
osg::Texture* tex = dynamic_cast<osg::Texture*>( stateset->getTextureAttribute(*it,osg::StateAttribute::TEXTURE) );
|
osg::TextureBuffer* tex = dynamic_cast<osg::TextureBuffer*>( stateset->getTextureAttribute(*it,osg::StateAttribute::TEXTURE) );
|
||||||
if(tex!=NULL)
|
if(tex!=NULL)
|
||||||
tex->dirtyTextureParameters();
|
tex->dirtyTextureParameters();
|
||||||
}
|
}
|
||||||
|
@ -435,6 +435,8 @@ typedef char GLchar;
|
|||||||
#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D
|
#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D
|
||||||
#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E
|
#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E
|
||||||
#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F
|
#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F
|
||||||
|
#define GL_DRAW_INDIRECT_BUFFER 0x8F3F
|
||||||
|
#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ARB_shader_atomic_counters
|
// ARB_shader_atomic_counters
|
||||||
@ -556,14 +558,14 @@ typedef char GLchar;
|
|||||||
#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
|
#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GL_INT64_ARB 0x140E
|
#define GL_INT64_ARB 0x140E
|
||||||
#define GL_UNSIGNED_INT64_ARB 0x140F
|
#define GL_UNSIGNED_INT64_ARB 0x140F
|
||||||
#define GL_INT64_VEC2_ARB 0x8FE9
|
#define GL_INT64_VEC2_ARB 0x8FE9
|
||||||
#define GL_INT64_VEC3_ARB 0x8FEA
|
#define GL_INT64_VEC3_ARB 0x8FEA
|
||||||
#define GL_INT64_VEC4_ARB 0x8FEB
|
#define GL_INT64_VEC4_ARB 0x8FEB
|
||||||
#define GL_UNSIGNED_INT64_VEC2_ARB 0x8FF5
|
#define GL_UNSIGNED_INT64_VEC2_ARB 0x8FF5
|
||||||
#define GL_UNSIGNED_INT64_VEC3_ARB 0x8FF6
|
#define GL_UNSIGNED_INT64_VEC3_ARB 0x8FF6
|
||||||
#define GL_UNSIGNED_INT64_VEC4_ARB 0x8FF7
|
#define GL_UNSIGNED_INT64_VEC4_ARB 0x8FF7
|
||||||
/* ------------------------------ GL_KHR_debug ----------------------------- */
|
/* ------------------------------ GL_KHR_debug ----------------------------- */
|
||||||
#ifndef GL_KHR_debug
|
#ifndef GL_KHR_debug
|
||||||
#define GL_KHR_debug 1
|
#define GL_KHR_debug 1
|
||||||
|
@ -133,7 +133,15 @@ class OSG_EXPORT PrimitiveSet : public BufferData
|
|||||||
DrawElementsUBytePrimitiveType,
|
DrawElementsUBytePrimitiveType,
|
||||||
DrawElementsUShortPrimitiveType,
|
DrawElementsUShortPrimitiveType,
|
||||||
DrawElementsUIntPrimitiveType,
|
DrawElementsUIntPrimitiveType,
|
||||||
MultiDrawArraysPrimitiveType
|
MultiDrawArraysPrimitiveType,
|
||||||
|
DrawArraysIndirectPrimitiveType,
|
||||||
|
DrawElementsUByteIndirectPrimitiveType,
|
||||||
|
DrawElementsUShortIndirectPrimitiveType,
|
||||||
|
DrawElementsUIntIndirectPrimitiveType,
|
||||||
|
MultiDrawArraysIndirectPrimitiveType,
|
||||||
|
MultiDrawElementsUByteIndirectPrimitiveType,
|
||||||
|
MultiDrawElementsUShortIndirectPrimitiveType,
|
||||||
|
MultiDrawElementsUIntIndirectPrimitiveType
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Mode
|
enum Mode
|
||||||
|
697
include/osg/PrimitiveSetIndirect
Normal file
697
include/osg/PrimitiveSetIndirect
Normal file
@ -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 <osg/PrimitiveSet>
|
||||||
|
|
||||||
|
|
||||||
|
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<DrawArraysIndirectCommand>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
META_Object(osg,DefaultIndirectCommandDrawArrays)
|
||||||
|
|
||||||
|
DefaultIndirectCommandDrawArrays():IndirectCommandDrawArrays(), MixinVector<DrawArraysIndirectCommand>() {}
|
||||||
|
DefaultIndirectCommandDrawArrays(const DefaultIndirectCommandDrawArrays& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/)
|
||||||
|
:IndirectCommandDrawArrays(copy, copyop),MixinVector<DrawArraysIndirectCommand>() {}
|
||||||
|
|
||||||
|
virtual const GLvoid* getDataPointer() const {
|
||||||
|
return empty()?0:&front();
|
||||||
|
}
|
||||||
|
virtual unsigned int getTotalDataSize() const {
|
||||||
|
return 16u*static_cast<unsigned int>(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<unsigned int>(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<DrawElementsIndirectCommand>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
META_Object(osg,DefaultIndirectCommandDrawElements)
|
||||||
|
DefaultIndirectCommandDrawElements():IndirectCommandDrawElements(), MixinVector<DrawElementsIndirectCommand>() {}
|
||||||
|
DefaultIndirectCommandDrawElements(const DefaultIndirectCommandDrawElements& copy,const CopyOp& copyop/*=CopyOp::SHALLOW_COPY*/)
|
||||||
|
:IndirectCommandDrawElements(copy, copyop), MixinVector<DrawElementsIndirectCommand>(){}
|
||||||
|
virtual const GLvoid* getDataPointer() const {
|
||||||
|
return empty()?0:&front();
|
||||||
|
}
|
||||||
|
virtual unsigned int getTotalDataSize() const {
|
||||||
|
return 20u*static_cast<unsigned int>(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<unsigned int>(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<IndirectCommandDrawElements> _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<const DrawElementsIndirectUByte*>(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<unsigned int>(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<unsigned int>(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 <class InputIterator>
|
||||||
|
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<const DrawElementsIndirectUShort*>(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<unsigned int>(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<unsigned int>(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 <class InputIterator>
|
||||||
|
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<const DrawElementsIndirectUInt*>(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<unsigned int>(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<unsigned int>(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<const DrawArraysIndirect*>(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> _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<const MultiDrawArraysIndirect*>(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
|
||||||
|
|
@ -136,6 +136,7 @@ SET(TARGET_H
|
|||||||
${HEADER_PATH}/Polytope
|
${HEADER_PATH}/Polytope
|
||||||
${HEADER_PATH}/PositionAttitudeTransform
|
${HEADER_PATH}/PositionAttitudeTransform
|
||||||
${HEADER_PATH}/PrimitiveSet
|
${HEADER_PATH}/PrimitiveSet
|
||||||
|
${HEADER_PATH}/PrimitiveSetIndirect
|
||||||
${HEADER_PATH}/PrimitiveRestartIndex
|
${HEADER_PATH}/PrimitiveRestartIndex
|
||||||
${HEADER_PATH}/Program
|
${HEADER_PATH}/Program
|
||||||
${HEADER_PATH}/Projection
|
${HEADER_PATH}/Projection
|
||||||
@ -342,6 +343,7 @@ SET(TARGET_SRC
|
|||||||
Polytope.cpp
|
Polytope.cpp
|
||||||
PositionAttitudeTransform.cpp
|
PositionAttitudeTransform.cpp
|
||||||
PrimitiveSet.cpp
|
PrimitiveSet.cpp
|
||||||
|
PrimitiveSetIndirect.cpp
|
||||||
PrimitiveRestartIndex.cpp
|
PrimitiveRestartIndex.cpp
|
||||||
Program.cpp
|
Program.cpp
|
||||||
Projection.cpp
|
Projection.cpp
|
||||||
|
585
src/osg/PrimitiveSetIndirect.cpp
Normal file
585
src/osg/PrimitiveSetIndirect.cpp
Normal file
@ -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 <osg/PrimitiveSetIndirect>
|
||||||
|
#include <osg/BufferObject>
|
||||||
|
#include <osg/State>
|
||||||
|
#include <osg/Notify>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
using namespace osg;
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// DrawElementsIndirect
|
||||||
|
//
|
||||||
|
template<class T> 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<DrawElementsIndirectUInt>(*this);}
|
||||||
|
unsigned int DrawElementsIndirectUByte::getNumPrimitives() const{return getNumPrimitivesDI<DrawElementsIndirectUByte>(*this);}
|
||||||
|
unsigned int DrawElementsIndirectUShort::getNumPrimitives() const{return getNumPrimitivesDI<DrawElementsIndirectUShort>(*this);}
|
||||||
|
|
||||||
|
void DrawElementsIndirectUInt::draw(State& state, bool useVertexBufferObjects) const
|
||||||
|
{ GLBufferObject* dibo = _IndirectCommandDrawArrays->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() );
|
||||||
|
state.get<GLExtensions>()->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<GLExtensions>()-> 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<GLExtensions>()->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<GLExtensions>()-> 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<GLExtensions>()->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<GLExtensions>()-> 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<class T> 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<MultiDrawElementsIndirectUInt>(*this);}
|
||||||
|
unsigned int MultiDrawElementsIndirectUByte::getNumPrimitives() const{return getNumPrimitivesMDI<MultiDrawElementsIndirectUByte>(*this);}
|
||||||
|
unsigned int MultiDrawElementsIndirectUShort::getNumPrimitives() const{return getNumPrimitivesMDI<MultiDrawElementsIndirectUShort>(*this);}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// MultiDrawElementsIndirectUByte
|
||||||
|
//
|
||||||
|
MultiDrawElementsIndirectUByte::~MultiDrawElementsIndirectUByte()
|
||||||
|
{
|
||||||
|
releaseGLObjects();
|
||||||
|
}
|
||||||
|
void MultiDrawElementsIndirectUByte::draw(State& state, bool useVertexBufferObjects) const
|
||||||
|
{
|
||||||
|
GLBufferObject* dibo = _IndirectCommandDrawArrays->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() );
|
||||||
|
|
||||||
|
state.get<GLExtensions>()->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<GLExtensions>()-> 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; i<maxindex;i++)
|
||||||
|
functor.drawElements(_mode,_IndirectCommandDrawArrays->count(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; i<maxindex;i++)
|
||||||
|
functor.drawElements(_mode,_IndirectCommandDrawArrays->count(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<GLExtensions>()->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<GLExtensions>()-> 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; i<maxindex;i++)
|
||||||
|
functor.drawElements(_mode,_IndirectCommandDrawArrays->count(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; i<maxindex;i++)
|
||||||
|
functor.drawElements(_mode,_IndirectCommandDrawArrays->count(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<GLExtensions>()->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<GLExtensions>()-> 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; i<maxindex;i++)
|
||||||
|
functor.drawElements(_mode,_IndirectCommandDrawArrays->count(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; i<maxindex;i++)
|
||||||
|
functor.drawElements(_mode,_IndirectCommandDrawArrays->count(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<GLExtensions>()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID());
|
||||||
|
|
||||||
|
GLExtensions* ext = state.get<GLExtensions>();
|
||||||
|
|
||||||
|
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<GLExtensions>()->glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dibo->getGLObjectID());
|
||||||
|
|
||||||
|
GLExtensions* ext = state.get<GLExtensions>();
|
||||||
|
|
||||||
|
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; i<maxindex;i++)
|
||||||
|
{
|
||||||
|
functor.drawArrays(_mode, _IndirectCommandDrawArrays->first(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; i<maxindex;i++)
|
||||||
|
{
|
||||||
|
functor.drawArrays(_mode, _IndirectCommandDrawArrays->first(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; i<maxindex;i++)
|
||||||
|
total+= _IndirectCommandDrawArrays->count(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; i<maxindex;i++)
|
||||||
|
{
|
||||||
|
unsigned int count = _IndirectCommandDrawArrays->count(i);
|
||||||
|
if (pos<count) break;
|
||||||
|
pos -= count;
|
||||||
|
}
|
||||||
|
return _IndirectCommandDrawArrays->first(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; i<maxindex;i++)
|
||||||
|
_IndirectCommandDrawArrays->first(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; i<maxindex;i++)
|
||||||
|
total+=_IndirectCommandDrawArrays->count(i);
|
||||||
|
case(LINES):
|
||||||
|
for(unsigned int i=_firstCommand; i<maxindex;i++)
|
||||||
|
total+=_IndirectCommandDrawArrays->count(i)/2;
|
||||||
|
case(TRIANGLES):
|
||||||
|
for(unsigned int i=_firstCommand; i<maxindex;i++)
|
||||||
|
total+=_IndirectCommandDrawArrays->count(i)/3;
|
||||||
|
case(QUADS):
|
||||||
|
for(unsigned int i=_firstCommand; i<maxindex;i++)
|
||||||
|
total+=_IndirectCommandDrawArrays->count(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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user