Improve OpenGL Particle System

I am looking for a way to improve particle system performance, as it is a very expensive option in terms of FPS. This is because I call:

glDrawElements(GL_TRIANGLE_STRIP, mNumberOfIndices, GL_UNSIGNED_SHORT, 0); 

I call this method for each particle in my application (which can be from 1000 to 5000 particles). Please note that when you increase to 1000 particles, my application starts to fall in FPS. I use VBO: s, but the performance when calling this method is too expensive.

Any ideas how I can make the particle system more efficient?

Edit: this is how my particle system draws things:

 glBindTexture(GL_TEXTURE_2D, textureObject); glBindBuffer(GL_ARRAY_BUFFER, vboVertexBuffer[0]); glVertexPointer(3, GL_FLOAT, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, vboTextureBuffer[0]); glTexCoordPointer(2, GL_FLOAT, 0, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndexBuffer[0]); Vector3f partPos; for (int i = 0; i < m_numParticles; i++) { partPos = m_particleList[i].m_pos; glTranslatef(partPos.x, partPos.y, partPos.z); glDrawElements(GL_TRIANGLE_STRIP, mNumberOfIndices, GL_UNSIGNED_SHORT, 0); gl.glTranslatef(-partPos.x, -partPos.y, -partPos.z); } 
+4
source share
2 answers

As you describe it, it looks like you have your own VBO for each particle. This is not how it should be done. Put all the particles in one VBO and pull them all out at once using a single call to glDrawElements or glDrawArrays . Or better yet, if available: use instancing.

+6
source

Turning around a bit on what Dantenwolf said, just pack all the particle indices into one index buffer and draw all the particles with a single glDrawElements call. This means that you can no longer use triangular stripes, but a set of triangles, but this should not be too big a problem.

Otherwise, if your equipment supports instant rendering (or, better, instantiated arrays), you can do this by simply making one particle n times with position data and texCoord taken from the corresponding arrays for each particle. Then you need to calculate the four positions in the corner and the texCoord data in the vertex shader (provided that you draw a square for each particle), because with the help of built-in arrays you get only one attribute per instance (particle).

You can also use a geometric shader to create a square of particles and simply visualize a single set of points, but I assume that it can be slower than instancing, given that the SM4 / GL3 hardware is also likely to support instancing.

+1
source

All Articles