Beginings of refactoring ParticleSystem so that it does uses vertex arrays rather than GLBeginEndAdapter

This commit is contained in:
Robert Osfield 2016-08-26 19:48:32 +01:00
parent 611b7afb07
commit 886b922596
2 changed files with 162 additions and 27 deletions

View File

@ -167,7 +167,7 @@ namespace osgParticle
inline const Particle* getParticle(int i) const;
/// Create a new particle from the specified template (or the default one if <CODE>ptemplate</CODE> is null).
inline virtual Particle* createParticle(const Particle* ptemplate);
virtual Particle* createParticle(const Particle* ptemplate);
/// Destroy the i-th particle.
inline virtual void destroyParticle(int i);
@ -257,6 +257,16 @@ namespace osgParticle
ReadWriterMutex* getReadWriteMutex() const { return &_readWriteMutex; }
/** Resize any per context GLObject buffers to specified size. */
virtual void resizeGLObjectBuffers(unsigned int maxSize);
/** If State is non-zero, this function releases OpenGL objects for
* the specified graphics context. Otherwise, releases OpenGL objects
* for all graphics contexts. */
virtual void releaseGLObjects(osg::State* state=0) const;
virtual osg::VertexArrayState* createVertexArrayState(osg::RenderInfo& renderInfo, bool usingVBOs) const;
protected:
virtual ~ParticleSystem();
@ -308,6 +318,24 @@ namespace osgParticle
mutable int _draw_count;
mutable ReadWriterMutex _readWriteMutex;
struct ArrayData
{
ArrayData();
void reserve(unsigned int numVertices);
void resize(unsigned int numVertices);
void resizeGLObjectBuffers(unsigned int maxSize);
void releaseGLObjects(osg::State* state);
osg::ref_ptr<osg::BufferObject> vertexBufferObject;
osg::ref_ptr<osg::Vec3Array> vertices;
osg::ref_ptr<osg::Vec4Array> colors;
osg::ref_ptr<osg::Vec2Array> texcoords;
};
typedef osg::buffered_object< ArrayData > BufferedArrayData;
mutable BufferedArrayData _bufferedArrayData;
};
// INLINE FUNCTIONS
@ -496,32 +524,6 @@ namespace osgParticle
if (_useShaders) _dirty_uniforms = true;
}
// I'm not sure this function should be inlined...
inline Particle* ParticleSystem::createParticle(const Particle* ptemplate)
{
// is there any dead particle?
if (!_deadparts.empty()) {
// retrieve a pointer to the last dead particle
Particle* P = _deadparts.top();
// create a new (alive) particle in the same place
*P = ptemplate? *ptemplate: _def_ptemp;
// remove the pointer from the death stack
_deadparts.pop();
return P;
} else {
// add a new particle to the vector
_particles.push_back(ptemplate? *ptemplate: _def_ptemp);
return &_particles.back();
}
}
}
#endif

View File

@ -94,6 +94,29 @@ osgParticle::ParticleSystem::~ParticleSystem()
{
}
osgParticle::Particle* osgParticle::ParticleSystem::createParticle(const osgParticle::Particle* ptemplate)
{
// is there any dead particle?
if (!_deadparts.empty()) {
// retrieve a pointer to the last dead particle
Particle* P = _deadparts.top();
// create a new (alive) particle in the same place
*P = ptemplate? *ptemplate: _def_ptemp;
// remove the pointer from the death stack
_deadparts.pop();
return P;
} else {
// add a new particle to the vector
_particles.push_back(ptemplate? *ptemplate: _def_ptemp);
return &_particles.back();
}
}
void osgParticle::ParticleSystem::update(double dt, osg::NodeVisitor& nv)
{
// reset bounds
@ -517,3 +540,113 @@ osg::BoundingBox osgParticle::ParticleSystem::computeBoundingBox() const
}
}
void osgParticle::ParticleSystem::resizeGLObjectBuffers(unsigned int maxSize)
{
_bufferedArrayData.resize(maxSize);
for(unsigned int i=0; i<_bufferedArrayData.size(); ++i)
{
_bufferedArrayData[i].resizeGLObjectBuffers(maxSize);
}
}
void osgParticle::ParticleSystem::releaseGLObjects(osg::State* state) const
{
if (state)
{
_bufferedArrayData[state->getContextID()].releaseGLObjects(state);
}
else
{
for(unsigned int i=0; i<_bufferedArrayData.size(); ++i)
{
_bufferedArrayData[i].releaseGLObjects(0);
}
}
}
osg::VertexArrayState* osgParticle::ParticleSystem::createVertexArrayState(osg::RenderInfo& renderInfo, bool usingVBOs) const
{
OSG_NOTICE<<"osgParticle::ParticleSystem::createVertexArrayState() "<<this<<std::endl;
#if 0
return osg::Drawable::createVertexArrayState(renderInfo, usingVBOs);
#else
osg::State& state = *renderInfo.getState();
ArrayData& ad = _bufferedArrayData[state.getContextID()];
osg::VertexArrayState* vas = new osg::VertexArrayState(&state);
OSG_NOTICE<<" Creating new osg::VertexArrayState "<< vas<<std::endl;
if (ad.vertices.valid()) vas->assignVertexArrayDispatcher();
if (ad.colors.valid()) vas->assignColorArrayDispatcher();
if (ad.texcoords.valid()) vas->assignTexCoordArrayDispatcher(1);
if (state.useVertexArrayObject(_useVertexArrayObject))
{
OSG_NOTICE<<" Setup VertexArrayState to use VAO "<<vas<<std::endl;
vas->generateVertexArrayObject();
}
else
{
OSG_NOTICE<<" Setup VertexArrayState to without using VAO "<<vas<<std::endl;
}
return vas;
#endif
}
/////////////////////////////////////////////////////////////////////////////////////
//
// ArrayData
//
osgParticle::ParticleSystem::ArrayData::ArrayData()
{
OSG_NOTICE<<"osgParticle::ParticleSystem::ArrayData() "<<this<<std::endl;
vertexBufferObject = new osg::VertexBufferObject;
vertices = new osg::Vec3Array;
vertices->setBufferObject(vertexBufferObject.get());
colors = new osg::Vec4Array;
colors->setBufferObject(vertexBufferObject.get());
texcoords = new osg::Vec2Array;
texcoords->setBufferObject(vertexBufferObject.get());
}
void osgParticle::ParticleSystem::ArrayData::reserve(unsigned int numVertices)
{
vertices->reserve(numVertices);
colors->reserve(numVertices);
texcoords->reserve(numVertices);
}
void osgParticle::ParticleSystem::ArrayData::resize(unsigned int numVertices)
{
vertices->resize(numVertices);
colors->resize(numVertices);
texcoords->resize(numVertices);
}
void osgParticle::ParticleSystem::ArrayData::resizeGLObjectBuffers(unsigned int maxSize)
{
OSG_NOTICE<<"osgParticle::ParticleSystem::resizeGLObjectBuffers("<<maxSize<<") "<<this<<std::endl;
vertexBufferObject->resizeGLObjectBuffers(maxSize);
vertices->resizeGLObjectBuffers(maxSize);
colors->resizeGLObjectBuffers(maxSize);
texcoords->resizeGLObjectBuffers(maxSize);
}
void osgParticle::ParticleSystem::ArrayData::releaseGLObjects(osg::State* state)
{
OSG_NOTICE<<"osgParticle::ParticleSystem::releaseGLObjects("<<state<<") "<<this<<std::endl;
vertexBufferObject->releaseGLObjects(state);
vertices->releaseGLObjects(state);
colors->releaseGLObjects(state);
texcoords->releaseGLObjects(state);
}