fix osggpucull to fit both new BIB and MDI

This commit is contained in:
Julien Valentin 2017-08-24 14:15:09 +02:00
parent 107b7be95b
commit 2d1aaedb9c

View File

@ -37,12 +37,13 @@
#include <osgViewer/ViewerEventHandlers> #include <osgViewer/ViewerEventHandlers>
#include <osg/BufferTemplate> #include <osg/BufferTemplate>
#include <osg/PrimitiveSetIndirect> #include <osg/PrimitiveSetIndirect>
#include "ShapeToGeometry.h" #include "ShapeToGeometry.h"
#include "AggregateGeometryVisitor.h" #include "AggregateGeometryVisitor.h"
#include "DrawIndirectPrimitiveSet.h"
#include "GpuCullShaders.h" #include "GpuCullShaders.h"
// 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 )
const unsigned int OSGGPUCULL_MAXIMUM_LOD_NUMBER = 8; const unsigned int OSGGPUCULL_MAXIMUM_LOD_NUMBER = 8;
@ -176,20 +177,17 @@ struct IndirectTarget
IndirectTarget() IndirectTarget()
: maxTargetQuantity(0) : maxTargetQuantity(0)
{ {
indirectCommands = new osg::DrawArraysIndirectCommandArray ; indirectCommands = new osg::DefaultIndirectCommandDrawArrays;
indirectCommands->getBufferObject()->setUsage(GL_DYNAMIC_DRAW);
} }
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::DrawArraysIndirectCommandArray; indirectCommands = new osg::DefaultIndirectCommandDrawArrays;
indirectCommands->getBufferObject()->setUsage(GL_DYNAMIC_DRAW);
} }
void endRegister(unsigned int index, unsigned int rowsPerInstance, GLenum pixelFormat, GLenum type, GLint internalFormat, bool useMultiDrawArraysIndirect ) void endRegister(unsigned int index, unsigned int rowsPerInstance, GLenum pixelFormat, GLenum type, GLint internalFormat, bool useMultiDrawArraysIndirect )
{ {
osg::DrawIndirectBufferObject * indirectCommandbuffer=new osg::DrawIndirectBufferObject();
indirectCommandbuffer->setUsage(GL_DYNAMIC_DRAW);
indirectCommands->setBufferObject(indirectCommandbuffer);
indirectCommandTextureBuffer = new osg::TextureBuffer(indirectCommands); indirectCommandTextureBuffer = new osg::TextureBuffer(indirectCommands);
indirectCommandTextureBuffer->setInternalFormat( GL_R32I ); indirectCommandTextureBuffer->setInternalFormat( GL_R32I );
indirectCommandTextureBuffer->bindToImageUnit(index, osg::Texture::READ_WRITE); indirectCommandTextureBuffer->bindToImageUnit(index, osg::Texture::READ_WRITE);
@ -199,28 +197,27 @@ 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->size(); ++j) for(unsigned int j=0;j<indirectCommands->size(); ++j){
newPrimitiveSets.push_back( new DrawArraysIndirect( GL_TRIANGLES, j*sizeof( osg::DrawArraysIndirectCommand ), indirectCommands ) ); osg::DrawArraysIndirect *ipr=new osg::DrawArraysIndirect( GL_TRIANGLES, j );
ipr->setIndirectCommandArray( 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->size(); ++j) for(unsigned int j=0;j<indirectCommands->size(); ++j)
geometryAggregator->getAggregatedGeometry()->addPrimitiveSet( newPrimitiveSets[j] ); geometryAggregator->getAggregatedGeometry()->addPrimitiveSet( newPrimitiveSets[j] );
/*DrawIndirectBufferBinding should be deprecated
///attach a DrawIndirect buffer binding to the stateset for non builtin primset DrawArraysIndirect
osg::ref_ptr<osg::DrawIndirectBufferBinding> bb=new osg::DrawIndirectBufferBinding();
bb->setBufferObject(indirectCommandbuffer );
geometryAggregator->getAggregatedGeometry()->getOrCreateStateSet()->setAttribute(bb );*/
} }
else // use glMultiDrawArraysIndirect() else // use glMultiDrawArraysIndirect()
{ {
osg::MultiDrawArraysIndirect * mdi=new osg::MultiDrawArraysIndirect(GL_TRIANGLES); osg::MultiDrawArraysIndirect *ipr=new osg::MultiDrawArraysIndirect( GL_TRIANGLES );
mdi->setIndirectCommandArray(indirectCommands); ipr->setIndirectCommandArray( indirectCommands );
geometryAggregator->getAggregatedGeometry()->removePrimitiveSet(0,geometryAggregator->getAggregatedGeometry()->getNumPrimitiveSets() ); geometryAggregator->getAggregatedGeometry()->removePrimitiveSet(0,geometryAggregator->getAggregatedGeometry()->getNumPrimitiveSets() );
geometryAggregator->getAggregatedGeometry()->addPrimitiveSet(mdi ); geometryAggregator->getAggregatedGeometry()->addPrimitiveSet( ipr );
} }
geometryAggregator->getAggregatedGeometry()->setUseDisplayList(false); geometryAggregator->getAggregatedGeometry()->setUseDisplayList(false);
@ -266,7 +263,7 @@ struct IndirectTarget
stateset->setAttributeAndModes( drawProgram.get(), osg::StateAttribute::ON ); stateset->setAttributeAndModes( drawProgram.get(), osg::StateAttribute::ON );
} }
osg::ref_ptr< osg::DrawArraysIndirectCommandArray > 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;
@ -316,7 +313,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->push_back( osg::DrawArraysIndirectCommand( aoResult.count,1,aoResult.first ) ); target->second.indirectCommands->push_back( osg::DrawArraysIndirectCommand( aoResult.count,1, aoResult.first ) );
osg::ComputeBoundsVisitor cbv; osg::ComputeBoundsVisitor cbv;
node->accept(cbv); node->accept(cbv);
@ -725,9 +722,9 @@ struct ResetTexturesCallback : public osg::StateSet::Callback
osg::TextureBuffer* tex = dynamic_cast<osg::TextureBuffer*>( 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::BufferData* drawcmds = tex->getBufferData(); osg::BufferData* img =const_cast<osg::BufferData*>(tex->getBufferData());
if(drawcmds!=NULL) if(img!=NULL)
drawcmds->dirty(); img->dirty();
} }
for(it=texUnitsDirtyParams.begin(), eit=texUnitsDirtyParams.end(); it!=eit; ++it) for(it=texUnitsDirtyParams.begin(), eit=texUnitsDirtyParams.end(); it!=eit; ++it)
{ {
@ -1563,3 +1560,4 @@ int main( int argc, char **argv )
return viewer.run(); return viewer.run();
} }