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