change the design of BufferIndexBinding to work with BufferData instead of BufferObject

allow convenient BufferData abstraction +  serialization of BufferIndexBinding
This commit is contained in:
Julien Valentin 2017-08-23 23:42:12 +02:00
parent 3b03699fbc
commit d49f0d67af
7 changed files with 199 additions and 103 deletions

View File

@ -773,7 +773,7 @@ void ComputeNode::initComputingSetup()
_dataArray->setBufferObject(_ssbo.get()); _dataArray->setBufferObject(_ssbo.get());
_ssbb = new osg::ShaderStorageBufferBinding(0, _ssbo.get(), 0, blockSize); _ssbb = new osg::ShaderStorageBufferBinding(0, _dataArray, 0, blockSize);
statesetComputation->setAttributeAndModes(_ssbb.get(), osg::StateAttribute::ON); statesetComputation->setAttributeAndModes(_ssbb.get(), osg::StateAttribute::ON);

View File

@ -108,10 +108,10 @@ class ResetAtomicCounter : public osg::StateAttributeCallback
osg::AtomicCounterBufferBinding * acbb = dynamic_cast<osg::AtomicCounterBufferBinding *>(sa); osg::AtomicCounterBufferBinding * acbb = dynamic_cast<osg::AtomicCounterBufferBinding *>(sa);
if (acbb) if (acbb)
{ {
osg::AtomicCounterBufferObject * acbo = dynamic_cast<osg::AtomicCounterBufferObject*>(acbb->getBufferObject()); osg::BufferData * acbd = acbb->getBufferData();
if (acbo && acbo->getBufferData(0)) if (acbd)
{ {
acbo->getBufferData(0)->dirty(); acbd->dirty();
} }
} }
} }
@ -207,10 +207,10 @@ int main(int argc, char** argv)
acboBlue->setUsage(GL_STREAM_COPY); acboBlue->setUsage(GL_STREAM_COPY);
atomicCounterArrayBlue->setBufferObject(acboBlue.get()); atomicCounterArrayBlue->setBufferObject(acboBlue.get());
osg::ref_ptr<osg::AtomicCounterBufferBinding> acbbRedAndGreen = new osg::AtomicCounterBufferBinding(0, acboRedAndGreen.get(), 0, sizeof(GLuint)*3); osg::ref_ptr<osg::AtomicCounterBufferBinding> acbbRedAndGreen = new osg::AtomicCounterBufferBinding(0, atomicCounterArrayRedAndGreen.get(), 0, sizeof(GLuint)*3);
ss->setAttributeAndModes(acbbRedAndGreen.get()); ss->setAttributeAndModes(acbbRedAndGreen.get());
osg::ref_ptr<osg::AtomicCounterBufferBinding> acbbBlue = new osg::AtomicCounterBufferBinding(2, acboBlue.get(), 0, sizeof(GLuint)); osg::ref_ptr<osg::AtomicCounterBufferBinding> acbbBlue = new osg::AtomicCounterBufferBinding(2, atomicCounterArrayBlue.get(), 0, sizeof(GLuint));
ss->setAttributeAndModes(acbbBlue.get()); ss->setAttributeAndModes(acbbBlue.get());
acbbRedAndGreen->setUpdateCallback(new ResetAtomicCounter); acbbRedAndGreen->setUpdateCallback(new ResetAtomicCounter);

View File

@ -187,14 +187,14 @@ struct IndirectTarget
} }
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::Image* indirectCommandImage = new osg::Image;
indirectCommandImage->setImage( indirectCommands->getTotalDataSize()/sizeof(unsigned int), 1, 1, GL_R32I, GL_RED, GL_UNSIGNED_INT, (unsigned char*)indirectCommands->getDataPointer(), osg::Image::NO_DELETE ); //indirectCommandImage->setImage( indirectCommands->getTotalDataSize()/sizeof(unsigned int), 1, 1, GL_R32I, GL_RED, GL_UNSIGNED_INT, (unsigned char*)indirectCommands->getDataPointer(), osg::Image::NO_DELETE );
osg::VertexBufferObject * indirectCommandImagebuffer=new osg::VertexBufferObject(); osg::VertexBufferObject * indirectCommandImagebuffer=new osg::VertexBufferObject();
indirectCommandImagebuffer->setUsage(GL_DYNAMIC_DRAW); indirectCommandImagebuffer->setUsage(GL_DYNAMIC_DRAW);
indirectCommandImage->setBufferObject(indirectCommandImagebuffer); indirectCommands->setBufferObject(indirectCommandImagebuffer);
indirectCommandTextureBuffer = new osg::TextureBuffer(indirectCommandImage); 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);
indirectCommandTextureBuffer->setUnRefImageDataAfterApply(false); indirectCommandTextureBuffer->setUnRefImageDataAfterApply(false);
@ -222,9 +222,9 @@ struct IndirectTarget
} }
///attach a DrawIndirect buffer binding to the stateset ///attach a DrawIndirect buffer binding to the stateset
osg::ref_ptr<osg::DrawIndirectBufferBinding> bb=new osg::DrawIndirectBufferBinding(); osg::ref_ptr<osg::DrawIndirectBufferBinding> bb=new osg::DrawIndirectBufferBinding(indirectCommands);
bb->setBufferObject(indirectCommandImage->getBufferObject());
geometryAggregator->getAggregatedGeometry()->getOrCreateStateSet()->setAttribute(bb ); geometryAggregator->getAggregatedGeometry()->getOrCreateStateSet()->setAttributeAndModes(bb );
geometryAggregator->getAggregatedGeometry()->setUseDisplayList(false); geometryAggregator->getAggregatedGeometry()->setUseDisplayList(false);
geometryAggregator->getAggregatedGeometry()->setUseVertexBufferObjects(true); geometryAggregator->getAggregatedGeometry()->setUseVertexBufferObjects(true);
@ -288,7 +288,7 @@ struct GPUCullData
instanceTypesUBO = new osg::UniformBufferObject; instanceTypesUBO = new osg::UniformBufferObject;
// instanceTypesUBO->setUsage( GL_STREAM_DRAW ); // instanceTypesUBO->setUsage( GL_STREAM_DRAW );
instanceTypes->setBufferObject( instanceTypesUBO.get() ); instanceTypes->setBufferObject( instanceTypesUBO.get() );
instanceTypesUBB = new osg::UniformBufferBinding(1, instanceTypesUBO.get(), 0, 0); instanceTypesUBB = new osg::UniformBufferBinding(1, instanceTypes.get(), 0, 0);
} }
void setUseMultiDrawArraysIndirect( bool value ) void setUseMultiDrawArraysIndirect( bool value )
@ -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();
} }

View File

@ -104,9 +104,7 @@ public:
void operator() (StateAttribute* attr, NodeVisitor* nv) void operator() (StateAttribute* attr, NodeVisitor* nv)
{ {
UniformBufferBinding* ubb = static_cast<UniformBufferBinding*>(attr); UniformBufferBinding* ubb = static_cast<UniformBufferBinding*>(attr);
UniformBufferObject* ubo FloatArray* array = static_cast<FloatArray*>(ubb->getBufferData());
= static_cast<UniformBufferObject*>(ubb->getBufferObject());
FloatArray* array = static_cast<FloatArray*>(ubo->getBufferData(0));
double time = nv->getFrameStamp()->getSimulationTime(); double time = nv->getFrameStamp()->getSimulationTime();
double frac = fmod(time, 1.0); double frac = fmod(time, 1.0);
Vec4f warmColor = (Vec4f(0.0, 0.0, 1.0 ,1) * frac Vec4f warmColor = (Vec4f(0.0, 0.0, 1.0 ,1) * frac
@ -165,7 +163,7 @@ int main(int argc, char** argv)
group1->addChild(loadedModel.get()); group1->addChild(loadedModel.get());
scene->addChild(group1); scene->addChild(group1);
ref_ptr<UniformBufferBinding> ubb1 ref_ptr<UniformBufferBinding> ubb1
= new UniformBufferBinding(0, ubo.get(), 0, blockSize); = new UniformBufferBinding(0, colorArray.get(), 0, blockSize);
ss1->setAttributeAndModes(ubb1.get(), StateAttribute::ON); ss1->setAttributeAndModes(ubb1.get(), StateAttribute::ON);
ref_ptr<FloatArray> colorArray2 ref_ptr<FloatArray> colorArray2
@ -180,7 +178,7 @@ int main(int argc, char** argv)
group2->addChild(loadedModel.get()); group2->addChild(loadedModel.get());
scene->addChild(group2); scene->addChild(group2);
ref_ptr<UniformBufferBinding> ubb2 ref_ptr<UniformBufferBinding> ubb2
= new UniformBufferBinding(0, ubo2.get(), 0, blockSize); = new UniformBufferBinding(0, colorArray2.get(), 0, blockSize);
ss2->setAttributeAndModes(ubb2.get(), StateAttribute::ON); ss2->setAttributeAndModes(ubb2.get(), StateAttribute::ON);
ref_ptr<FloatArray> colorArray3 ref_ptr<FloatArray> colorArray3
@ -195,7 +193,7 @@ int main(int argc, char** argv)
group3->addChild(loadedModel.get()); group3->addChild(loadedModel.get());
scene->addChild(group3); scene->addChild(group3);
ref_ptr<UniformBufferBinding> ubb3 ref_ptr<UniformBufferBinding> ubb3
= new UniformBufferBinding(0, ubo3.get(), 0, blockSize); = new UniformBufferBinding(0, colorArray3.get(), 0, blockSize);
ubb3->setUpdateCallback(new UniformBufferCallback); ubb3->setUpdateCallback(new UniformBufferCallback);
ubb3->setDataVariance(Object::DYNAMIC); ubb3->setDataVariance(Object::DYNAMIC);
ss3->setAttributeAndModes(ubb3.get(), StateAttribute::ON); ss3->setAttributeAndModes(ubb3.get(), StateAttribute::ON);

View File

@ -1,6 +1,7 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
* Copyright (C) 2010 Tim Moore * Copyright (C) 2010 Tim Moore
* Copyright (C) 2012 David Callu * Copyright (C) 2012 David Callu
* Copyright (C) 2017 Julien Valentin
* *
* This library is open source and may be redistributed and/or modified under * 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 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
@ -40,53 +41,67 @@ class OSG_EXPORT BufferIndexBinding : public StateAttribute
{ {
protected: protected:
BufferIndexBinding(GLenum target, GLuint index); BufferIndexBinding(GLenum target, GLuint index);
BufferIndexBinding(GLenum target, GLuint index, BufferObject* bo, GLintptr offset, BufferIndexBinding(GLenum target, GLuint index, BufferData* bd, GLintptr offset=0, GLsizeiptr size=0);
GLsizeiptr size);
BufferIndexBinding(const BufferIndexBinding& rhs, const CopyOp& copyop=CopyOp::SHALLOW_COPY); BufferIndexBinding(const BufferIndexBinding& rhs, const CopyOp& copyop=CopyOp::SHALLOW_COPY);
public: public:
// The member value is part of the key to this state attribute in // The member value is part of the key to this state attribute in
// the State class. Using the index target, we can separately // the State class. Using the index target, we can separately
// track the bindings for many different index targets. // track the bindings for many different index targets.
virtual unsigned getMember() const { return static_cast<unsigned int>(_index); } virtual unsigned getMember() const { return static_cast<unsigned int>(_index); }
GLenum getTarget() const { return _target; } GLenum getTarget() const { return _target; }
///enable arbitrary BufferBinding (user is responsible for _target mismatch with bufferdata
/// what can be done is setting wrong _target and use the one of bd if not subclassed
void setTarget(GLenum t){_target=t;}
/** Set the renderbuffer index of the BlendEquationi. */ inline void setBufferData(BufferData *bufferdata) {
void setIndex(unsigned int index); if (_bufferData.valid())
{
_bufferData->removeClient(this);
}
_bufferData=bufferdata;
if (_bufferData.valid())
{
if(!_bufferData->getBufferObject())
_bufferData->setBufferObject(new VertexBufferObject());
if(_size==0)
_size=_bufferData->getTotalDataSize();
}
}
/** Get the buffer data to be bound.
*/
inline const BufferData* getBufferData() const { return _bufferData.get(); }
inline BufferData* getBufferData(){ return _bufferData.get(); }
/** Get the index target. /** Get the index target.
*/ */
unsigned int getIndex() const { return _index; } inline GLuint getIndex() const { return _index; }
/** Set the index target. (and update parents StateSets)
/** Set the buffer object that will be bound to the index target.
*/ */
void setBufferObject(BufferObject *bo) { _bufferObject = bo; } void setIndex(GLuint index);
/** Get the buffer object to be bound.
*/
const BufferObject* getBufferObject() const { return _bufferObject.get(); }
BufferObject* getBufferObject(){ return _bufferObject.get(); }
/** Set the starting offset into the buffer object for data for /** Set the starting offset into the buffer data for
the indexed target. Note: the required alignment on the offset the indexed target. Note: the required alignment on the offset
may be quite large (e.g., 256 bytes on NVidia 8600M). This may be quite large (e.g., 256 bytes on NVidia 8600M). This
should be checked with glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT...). should be checked with glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT...).
*/ */
void setOffset(GLintptr offset) { _offset = offset; } inline void setOffset(GLintptr offset) { _offset = offset; }
GLintptr getOffset() const { return _offset; } inline GLintptr getOffset() const { return _offset; }
/** Set the size of data for the indexed target. /** Set the size override of bufferdata binded for the indexed target.
*/ */
void setSize(GLsizeiptr size) { _size = size; } inline void setSize(GLsizeiptr size) { _size = size; }
GLsizeiptr getSize() const { return _size; } inline GLsizeiptr getSize() const { return _size; }
virtual void apply(State& state) const; virtual void apply(State& state) const;
protected: protected:
virtual ~BufferIndexBinding(); virtual ~BufferIndexBinding();
const GLenum _target; /*const*/ GLenum _target;
ref_ptr<BufferData> _bufferData;
GLuint _index; GLuint _index;
ref_ptr<BufferObject> _bufferObject;
GLintptr _offset; GLintptr _offset;
GLsizeiptr _size; GLsizeiptr _size;
}; };
@ -100,21 +115,20 @@ class OSG_EXPORT UniformBufferBinding : public BufferIndexBinding
UniformBufferBinding(GLuint index); UniformBufferBinding(GLuint index);
/** Create a binding for a uniform buffer index target. /** Create a binding for a uniform buffer index target.
* @param index the index target * @param index the index target
* @param bo associated buffer object * @param bd associated buffer data
* @param offset offset into buffer object * @param offset offset into buffer data
* @param size size of data in buffer object * @param size size of data in buffer data
*/ */
UniformBufferBinding(GLuint index, BufferObject* bo, GLintptr offset, GLsizeiptr size); UniformBufferBinding(GLuint index, BufferData* bd, GLintptr offset=0, GLsizeiptr size=0);
UniformBufferBinding(const UniformBufferBinding& rhs, const CopyOp& copyop=CopyOp::SHALLOW_COPY); UniformBufferBinding(const UniformBufferBinding& rhs, const CopyOp& copyop=CopyOp::SHALLOW_COPY);
META_StateAttribute(osg, UniformBufferBinding, UNIFORMBUFFERBINDING); META_StateAttribute(osg, UniformBufferBinding, UNIFORMBUFFERBINDING);
virtual int compare(const StateAttribute& bb) const virtual int compare(const StateAttribute& bb) const
{ {
COMPARE_StateAttribute_Types(UniformBufferBinding, bb) COMPARE_StateAttribute_Types(UniformBufferBinding, bb)
COMPARE_StateAttribute_Parameter(_target) COMPARE_StateAttribute_Parameter(_target)
COMPARE_StateAttribute_Parameter(_index) COMPARE_StateAttribute_Parameter(_index)
COMPARE_StateAttribute_Parameter(_bufferObject) COMPARE_StateAttribute_Parameter(_bufferData)
COMPARE_StateAttribute_Parameter(_offset) COMPARE_StateAttribute_Parameter(_offset)
COMPARE_StateAttribute_Parameter(_size) COMPARE_StateAttribute_Parameter(_size)
return 0; return 0;
@ -127,17 +141,16 @@ class OSG_EXPORT TransformFeedbackBufferBinding : public BufferIndexBinding
{ {
public: public:
TransformFeedbackBufferBinding(GLuint index = 0); TransformFeedbackBufferBinding(GLuint index = 0);
TransformFeedbackBufferBinding(GLuint index, BufferObject* bo, GLintptr offset, GLsizeiptr size); TransformFeedbackBufferBinding(GLuint index, BufferData* bd, GLintptr offset=0, GLsizeiptr size=0);
TransformFeedbackBufferBinding(const TransformFeedbackBufferBinding& rhs, const CopyOp& copyop=CopyOp::SHALLOW_COPY); TransformFeedbackBufferBinding(const TransformFeedbackBufferBinding& rhs, const CopyOp& copyop=CopyOp::SHALLOW_COPY);
META_StateAttribute(osg, TransformFeedbackBufferBinding, TRANSFORMFEEDBACKBUFFERBINDING); META_StateAttribute(osg, TransformFeedbackBufferBinding, TRANSFORMFEEDBACKBUFFERBINDING);
virtual int compare(const StateAttribute& bb) const virtual int compare(const StateAttribute& bb) const
{ {
COMPARE_StateAttribute_Types(TransformFeedbackBufferBinding, bb) COMPARE_StateAttribute_Types(TransformFeedbackBufferBinding, bb)
COMPARE_StateAttribute_Parameter(_target) COMPARE_StateAttribute_Parameter(_target)
COMPARE_StateAttribute_Parameter(_index) COMPARE_StateAttribute_Parameter(_index)
COMPARE_StateAttribute_Parameter(_bufferObject) COMPARE_StateAttribute_Parameter(_bufferData)
COMPARE_StateAttribute_Parameter(_offset) COMPARE_StateAttribute_Parameter(_offset)
COMPARE_StateAttribute_Parameter(_size) COMPARE_StateAttribute_Parameter(_size)
return 0; return 0;
@ -152,11 +165,11 @@ class OSG_EXPORT AtomicCounterBufferBinding : public BufferIndexBinding
AtomicCounterBufferBinding(GLuint index=0); AtomicCounterBufferBinding(GLuint index=0);
/** Create a binding for a atomic counter buffer index target. /** Create a binding for a atomic counter buffer index target.
* @param index the index target * @param index the index target
* @param bo associated buffer object * @param bd associated buffer data
* @param offset offset into buffer object * @param offset offset into buffer data
* @param size size of data in buffer object * @param size size of data in buffer data
*/ */
AtomicCounterBufferBinding(GLuint index, BufferObject* bo, GLintptr offset, GLsizeiptr size); AtomicCounterBufferBinding(GLuint index, BufferData* bd, GLintptr offset=0, GLsizeiptr size=0);
AtomicCounterBufferBinding(const AtomicCounterBufferBinding& rhs, const CopyOp& copyop=CopyOp::SHALLOW_COPY); AtomicCounterBufferBinding(const AtomicCounterBufferBinding& rhs, const CopyOp& copyop=CopyOp::SHALLOW_COPY);
META_StateAttribute(osg, AtomicCounterBufferBinding, ATOMICCOUNTERBUFFERBINDING); META_StateAttribute(osg, AtomicCounterBufferBinding, ATOMICCOUNTERBUFFERBINDING);
@ -165,10 +178,9 @@ class OSG_EXPORT AtomicCounterBufferBinding : public BufferIndexBinding
virtual int compare(const StateAttribute& bb) const virtual int compare(const StateAttribute& bb) const
{ {
COMPARE_StateAttribute_Types(AtomicCounterBufferBinding, bb) COMPARE_StateAttribute_Types(AtomicCounterBufferBinding, bb)
COMPARE_StateAttribute_Parameter(_target) COMPARE_StateAttribute_Parameter(_target)
COMPARE_StateAttribute_Parameter(_index) COMPARE_StateAttribute_Parameter(_index)
COMPARE_StateAttribute_Parameter(_bufferObject) COMPARE_StateAttribute_Parameter(_bufferData)
COMPARE_StateAttribute_Parameter(_offset) COMPARE_StateAttribute_Parameter(_offset)
COMPARE_StateAttribute_Parameter(_size) COMPARE_StateAttribute_Parameter(_size)
return 0; return 0;
@ -181,11 +193,11 @@ class OSG_EXPORT ShaderStorageBufferBinding : public BufferIndexBinding
ShaderStorageBufferBinding(GLuint index=0); ShaderStorageBufferBinding(GLuint index=0);
/** Create a binding for a shader storage buffer index target. /** Create a binding for a shader storage buffer index target.
* @param index the index target * @param index the index target
* @param bo associated buffer object * @param bd associated buffer data
* @param offset offset into buffer object * @param offset offset into buffer data
* @param size size of data in buffer object * @param size size of data in buffer data
*/ */
ShaderStorageBufferBinding(GLuint index, BufferObject* bo, GLintptr offset, GLsizeiptr size); ShaderStorageBufferBinding(GLuint index, BufferData* bd, GLintptr offset=0, GLsizeiptr size=0);
ShaderStorageBufferBinding(const ShaderStorageBufferBinding& rhs, const CopyOp& copyop=CopyOp::SHALLOW_COPY); ShaderStorageBufferBinding(const ShaderStorageBufferBinding& rhs, const CopyOp& copyop=CopyOp::SHALLOW_COPY);
META_StateAttribute(osg, ShaderStorageBufferBinding, SHADERSTORAGEBUFFERBINDING); META_StateAttribute(osg, ShaderStorageBufferBinding, SHADERSTORAGEBUFFERBINDING);
@ -194,31 +206,32 @@ class OSG_EXPORT ShaderStorageBufferBinding : public BufferIndexBinding
COMPARE_StateAttribute_Types(ShaderStorageBufferBinding, bb) COMPARE_StateAttribute_Types(ShaderStorageBufferBinding, bb)
COMPARE_StateAttribute_Parameter(_target) COMPARE_StateAttribute_Parameter(_target)
COMPARE_StateAttribute_Parameter(_index) COMPARE_StateAttribute_Parameter(_index)
COMPARE_StateAttribute_Parameter(_bufferObject) COMPARE_StateAttribute_Parameter(_bufferData)
COMPARE_StateAttribute_Parameter(_offset) COMPARE_StateAttribute_Parameter(_offset)
COMPARE_StateAttribute_Parameter(_size) COMPARE_StateAttribute_Parameter(_size)
return 0; return 0;
} }
}; };
class OSG_EXPORT DrawIndirectBufferBinding : public BufferIndexBinding class OSG_EXPORT DrawIndirectBufferBinding : public BufferIndexBinding
{ {
public: public:
DrawIndirectBufferBinding(); DrawIndirectBufferBinding();
/** Create a binding for a uniform buffer index target. /** Create a binding for a draw indirect buffer target.
* @param bo associated buffer object * @param bd associated buffer data
*/ */
DrawIndirectBufferBinding( BufferObject* bo); DrawIndirectBufferBinding( BufferData* bd);
void apply(State& state) const;
DrawIndirectBufferBinding(const DrawIndirectBufferBinding& rhs, const CopyOp& copyop=CopyOp::SHALLOW_COPY); DrawIndirectBufferBinding(const DrawIndirectBufferBinding& rhs, const CopyOp& copyop=CopyOp::SHALLOW_COPY);
META_StateAttribute(osg, DrawIndirectBufferBinding, INDIRECTDRAWBUFFERBINDING); META_StateAttribute(osg, DrawIndirectBufferBinding, INDIRECTDRAWBUFFERBINDING);
virtual void apply(State& state) const;
virtual int compare(const StateAttribute& bb) const virtual int compare(const StateAttribute& bb) const
{ {
COMPARE_StateAttribute_Types(DrawIndirectBufferBinding, bb) COMPARE_StateAttribute_Types(DrawIndirectBufferBinding, bb)
COMPARE_StateAttribute_Parameter(_target) COMPARE_StateAttribute_Parameter(_target)
COMPARE_StateAttribute_Parameter(_bufferObject) COMPARE_StateAttribute_Parameter(_bufferData)
return 0; return 0;
} }
}; };

View File

@ -1,6 +1,7 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
* Copyright (C) 2010 Tim Moore * Copyright (C) 2010 Tim Moore
* Copyright (C) 2012 David Callu * Copyright (C) 2012 David Callu
* Copyright (C) 2017 Julien Valentin
* *
* This library is open source and may be redistributed and/or modified under * 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 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
@ -24,23 +25,25 @@
namespace osg { namespace osg {
BufferIndexBinding::BufferIndexBinding(GLenum target, GLuint index) BufferIndexBinding::BufferIndexBinding(GLenum target, GLuint index)
: _target(target), _index(index), _offset(0), _size(0) :_target(target), _bufferData(0), _index(index), _offset(0), _size(0)
{ {
} }
BufferIndexBinding::BufferIndexBinding(GLenum target, GLuint index, BufferObject* bo, BufferIndexBinding::BufferIndexBinding(GLenum target, GLuint index, BufferData* bo,
GLintptr offset, GLsizeiptr size) GLintptr offset, GLsizeiptr size)
: _target(target), _index(index), _bufferObject(bo), _offset(offset), _size(size) : _target(target), _index(index), _offset(offset), _size(size)
{ {
setBufferData(bo);
} }
BufferIndexBinding::BufferIndexBinding(const BufferIndexBinding& rhs, const CopyOp& copyop) BufferIndexBinding::BufferIndexBinding(const BufferIndexBinding& rhs, const CopyOp& copyop):StateAttribute(rhs,copyop),
: StateAttribute(rhs, copyop), _target(rhs._target),
_target(rhs._target), _index(rhs._index), _bufferData(static_cast<BufferData*>(copyop(rhs._bufferData.get()))),
_bufferObject(static_cast<BufferObject*>(copyop(rhs._bufferObject.get()))), _index(rhs._index),
_offset(rhs._offset), _offset(rhs._offset),
_size(rhs._size) _size(rhs._size)
{ {
} }
@ -59,15 +62,13 @@ void BufferIndexBinding::setIndex(unsigned int index)
void BufferIndexBinding::apply(State& state) const void BufferIndexBinding::apply(State& state) const
{ {
if (_bufferObject.valid()) if (_bufferData.valid())
{ {
GLBufferObject* glObject GLBufferObject* glObject
= _bufferObject->getOrCreateGLBufferObject(state.getContextID()); = _bufferData->getBufferObject()->getOrCreateGLBufferObject(state.getContextID());
if (!glObject->_extensions->isUniformBufferObjectSupported)
return;
if (glObject->isDirty()) glObject->compileBuffer(); if (glObject->isDirty()) glObject->compileBuffer();
glObject->_extensions->glBindBufferRange(_target, _index, glObject->_extensions->glBindBufferRange(_target, _index,
glObject->getGLObjectID(), _offset, _size); glObject->getGLObjectID(), glObject->getOffset(_bufferData->getBufferIndex())+_offset, _size-_offset);
} }
} }
@ -77,30 +78,30 @@ UniformBufferBinding::UniformBufferBinding()
} }
UniformBufferBinding::UniformBufferBinding(GLuint index) UniformBufferBinding::UniformBufferBinding(GLuint index)
: BufferIndexBinding(GL_UNIFORM_BUFFER, index) : BufferIndexBinding(GL_UNIFORM_BUFFER, index)
{ {
} }
UniformBufferBinding::UniformBufferBinding(GLuint index, BufferObject* bo, GLintptr offset, UniformBufferBinding::UniformBufferBinding(GLuint index, BufferData* bo, GLintptr offset,
GLsizeiptr size) GLsizeiptr size)
: BufferIndexBinding(GL_UNIFORM_BUFFER, index, bo, offset, size) : BufferIndexBinding(GL_UNIFORM_BUFFER, index, bo, offset, size)
{ {
} }
UniformBufferBinding::UniformBufferBinding(const UniformBufferBinding& rhs, UniformBufferBinding::UniformBufferBinding(const UniformBufferBinding& rhs,
const CopyOp& copyop) const CopyOp& copyop)
: BufferIndexBinding(rhs, copyop) : BufferIndexBinding(rhs, copyop)
{ {
} }
TransformFeedbackBufferBinding::TransformFeedbackBufferBinding(GLuint index) TransformFeedbackBufferBinding::TransformFeedbackBufferBinding(GLuint index)
: BufferIndexBinding(GL_TRANSFORM_FEEDBACK_BUFFER, index) : BufferIndexBinding(GL_TRANSFORM_FEEDBACK_BUFFER, index)
{ {
} }
TransformFeedbackBufferBinding::TransformFeedbackBufferBinding(GLuint index, BufferObject* bo, GLintptr offset, GLsizeiptr size) TransformFeedbackBufferBinding::TransformFeedbackBufferBinding(GLuint index, BufferData* bo, GLintptr offset, GLsizeiptr size)
: BufferIndexBinding(GL_TRANSFORM_FEEDBACK_BUFFER, index, bo, offset, size) : BufferIndexBinding(GL_TRANSFORM_FEEDBACK_BUFFER, index, bo, offset, size)
{ {
@ -113,11 +114,11 @@ TransformFeedbackBufferBinding::TransformFeedbackBufferBinding(const TransformFe
AtomicCounterBufferBinding::AtomicCounterBufferBinding(GLuint index) AtomicCounterBufferBinding::AtomicCounterBufferBinding(GLuint index)
: BufferIndexBinding(GL_ATOMIC_COUNTER_BUFFER, index) : BufferIndexBinding(GL_ATOMIC_COUNTER_BUFFER, index)
{ {
} }
AtomicCounterBufferBinding::AtomicCounterBufferBinding(GLuint index, BufferObject* bo, GLintptr offset, GLsizeiptr size) AtomicCounterBufferBinding::AtomicCounterBufferBinding(GLuint index, BufferData* bo, GLintptr offset, GLsizeiptr size)
: BufferIndexBinding(GL_ATOMIC_COUNTER_BUFFER, index, bo, offset, size) : BufferIndexBinding(GL_ATOMIC_COUNTER_BUFFER, index, bo, offset, size)
{ {
@ -130,9 +131,9 @@ AtomicCounterBufferBinding::AtomicCounterBufferBinding(const AtomicCounterBuffer
void AtomicCounterBufferBinding::readData(osg::State & state, osg::UIntArray & uintArray) const void AtomicCounterBufferBinding::readData(osg::State & state, osg::UIntArray & uintArray) const
{ {
if (!_bufferObject) return; if (!_bufferData) return;
GLBufferObject* bo = _bufferObject->getOrCreateGLBufferObject( state.getContextID() ); GLBufferObject* bo = _bufferData->getBufferObject()->getOrCreateGLBufferObject( state.getContextID() );
if (!bo) return; if (!bo) return;
@ -143,7 +144,7 @@ void AtomicCounterBufferBinding::readData(osg::State & state, osg::UIntArray & u
bo->_extensions->glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, bo->getGLObjectID()); bo->_extensions->glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, bo->getGLObjectID());
GLubyte* src = (GLubyte*)bo->_extensions->glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GLubyte* src = (GLubyte*)bo->_extensions->glMapBuffer(GL_ATOMIC_COUNTER_BUFFER,
GL_READ_ONLY_ARB); GL_READ_ONLY_ARB);
if(src) if(src)
{ {
size_t size = osg::minimum<int>(_size, uintArray.getTotalDataSize()); size_t size = osg::minimum<int>(_size, uintArray.getTotalDataSize());
@ -161,7 +162,7 @@ ShaderStorageBufferBinding::ShaderStorageBufferBinding(GLuint index)
{ {
} }
ShaderStorageBufferBinding::ShaderStorageBufferBinding(GLuint index, BufferObject* bo, GLintptr offset, GLsizeiptr size) ShaderStorageBufferBinding::ShaderStorageBufferBinding(GLuint index, BufferData* bo, GLintptr offset, GLsizeiptr size)
: BufferIndexBinding(GL_SHADER_STORAGE_BUFFER, index, bo, offset, size) : BufferIndexBinding(GL_SHADER_STORAGE_BUFFER, index, bo, offset, size)
{ {
@ -173,26 +174,24 @@ ShaderStorageBufferBinding::ShaderStorageBufferBinding(const ShaderStorageBuffer
} }
DrawIndirectBufferBinding::DrawIndirectBufferBinding( ) DrawIndirectBufferBinding::DrawIndirectBufferBinding( )
: BufferIndexBinding(GL_DRAW_INDIRECT_BUFFER, 0) : BufferIndexBinding(GL_DRAW_INDIRECT_BUFFER, 0)
{ {
} }
void DrawIndirectBufferBinding::apply(State& state) const void DrawIndirectBufferBinding::apply(State& state) const
{ {
if (_bufferObject.valid()) if (_bufferData.valid())
{ {
BufferObject * bo = _bufferData->getBufferObject();
GLBufferObject* glObject GLBufferObject* glObject
= _bufferObject->getOrCreateGLBufferObject(state.getContextID()); = bo->getOrCreateGLBufferObject(state.getContextID());
if (!glObject->_extensions->isUniformBufferObjectSupported) if (!glObject->_extensions->isUniformBufferObjectSupported)
return; return;
// if (glObject->isDirty()) glObject->compileBuffer(); if (glObject->isDirty()) glObject->compileBuffer();
glObject->_extensions->glBindBuffer (_target, glObject->getGLObjectID()); glObject->_extensions->glBindBuffer (_target, glObject->getGLObjectID());
} }
} }
DrawIndirectBufferBinding::DrawIndirectBufferBinding( BufferObject* bo) DrawIndirectBufferBinding::DrawIndirectBufferBinding( BufferData* bo)
: BufferIndexBinding(GL_DRAW_INDIRECT_BUFFER, 0, bo, 0, 0) : BufferIndexBinding(GL_DRAW_INDIRECT_BUFFER, 0, bo, 0, 0)
{ {

View File

@ -0,0 +1,86 @@
#include <osg/BufferIndexBinding>
#include <osg/BufferObject>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
#define ADD_GLUINT_SERIALIZER(PROP, DEF) \
wrapper->addSerializer( new osgDB::PropByValSerializer< MyClass, GLuint >( \
#PROP, ((unsigned int)(DEF)), &MyClass::get##PROP, &MyClass::set##PROP), osgDB::BaseSerializer::RW_UINT )
#define GLsizei_ptrSERIALIZER(TYPE,XXX) \
static bool check##XXX( const TYPE& node )\
{ return node.get##XXX()>0;}\
static bool read##XXX( osgDB::InputStream& is, TYPE& node )\
{\
unsigned int size = 0; is >> size ; node.set##XXX(size); return true;\
}\
static bool write##XXX( osgDB::OutputStream& os, const TYPE& node )\
{\
unsigned int size = node.get##XXX(); os << size << std::endl; return true;\
}
GLsizei_ptrSERIALIZER(osg::BufferIndexBinding,Size)
GLsizei_ptrSERIALIZER(osg::BufferIndexBinding,Offset)
namespace wrap_osgBufferIndexBinding
{
REGISTER_OBJECT_WRAPPER( BufferIndexBinding,
/*new osg::BufferIndexBinding*/NULL,
osg::BufferIndexBinding,
"osg::Object osg::StateAttribute osg::BufferIndexBinding" )
{
ADD_GLENUM_SERIALIZER( Target,GLenum, GL_BUFFER); // _target
ADD_OBJECT_SERIALIZER( BufferData, osg::BufferData, NULL ); // _bufferObject
ADD_GLUINT_SERIALIZER( Index, 0); // _index
ADD_USER_SERIALIZER(Size);
ADD_USER_SERIALIZER(Offset);
}
}
namespace wrap_osgUniformBufferBinding
{
REGISTER_OBJECT_WRAPPER( UniformBufferBinding,
new osg::UniformBufferBinding,
osg::UniformBufferBinding,
"osg::Object osg::StateAttribute osg::BufferIndexBinding osg::UniformBufferBinding" )
{
}
}
namespace wrap_osgTransformFeedbackBufferBinding
{
REGISTER_OBJECT_WRAPPER( TransformFeedbackBufferBinding,
new osg::TransformFeedbackBufferBinding,
osg::TransformFeedbackBufferBinding,
"osg::Object osg::StateAttribute osg::BufferIndexBinding osg::TransformFeedbackBufferBinding" )
{
}
}
namespace wrap_osgAtomicCounterBufferBinding
{
REGISTER_OBJECT_WRAPPER( AtomicCounterBufferBinding,
new osg::AtomicCounterBufferBinding,
osg::AtomicCounterBufferBinding,
"osg::Object osg::StateAttribute osg::BufferIndexBinding osg::AtomicCounterBufferBinding" )
{
}
}
namespace wrap_osgShaderStorageBufferBinding
{
REGISTER_OBJECT_WRAPPER( ShaderStorageBufferBinding,
new osg::ShaderStorageBufferBinding,
osg::ShaderStorageBufferBinding,
"osg::Object osg::StateAttribute osg::BufferIndexBinding osg::ShaderStorageBufferBinding" )
{
}
}