From 886b9225968e9906f7f19c2988af1223b153e559 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 26 Aug 2016 19:48:32 +0100 Subject: [PATCH] Beginings of refactoring ParticleSystem so that it does uses vertex arrays rather than GLBeginEndAdapter --- include/osgParticle/ParticleSystem | 56 ++++++------ src/osgParticle/ParticleSystem.cpp | 133 +++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+), 27 deletions(-) diff --git a/include/osgParticle/ParticleSystem b/include/osgParticle/ParticleSystem index fec42748e..b1a1ac571 100644 --- a/include/osgParticle/ParticleSystem +++ b/include/osgParticle/ParticleSystem @@ -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 ptemplate 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 vertexBufferObject; + osg::ref_ptr vertices; + osg::ref_ptr colors; + osg::ref_ptr 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 diff --git a/src/osgParticle/ParticleSystem.cpp b/src/osgParticle/ParticleSystem.cpp index 23bc65c79..333225471 100644 --- a/src/osgParticle/ParticleSystem.cpp +++ b/src/osgParticle/ParticleSystem.cpp @@ -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() "<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 "<generateVertexArrayObject(); + } + else + { + OSG_NOTICE<<" Setup VertexArrayState to without using VAO "<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("<resizeGLObjectBuffers(maxSize); + vertices->resizeGLObjectBuffers(maxSize); + colors->resizeGLObjectBuffers(maxSize); + texcoords->resizeGLObjectBuffers(maxSize); +} + +void osgParticle::ParticleSystem::ArrayData::releaseGLObjects(osg::State* state) +{ + OSG_NOTICE<<"osgParticle::ParticleSystem::releaseGLObjects("<releaseGLObjects(state); + vertices->releaseGLObjects(state); + colors->releaseGLObjects(state); + texcoords->releaseGLObjects(state); +} \ No newline at end of file