Fast particles system using VBO

I am trying to do particles system with VBO (i am just started learning VBO), but i have some performance issues.
First, i created particle system using immediate mode, and i get about 60 fps with 40000 particles, but when i rewrited it using VBO my performance drop dramatically, now i am getting only 5000 particles with 60 fps.

Here some my code:

CREATING PARTICLE:

public Particle(){
		 FloatBuffer vertices = BufferUtils.createFloatBuffer(2*4);
         vertices.put(new float[]
         {
              0,   0,
             5, 0,
             5, 5,
             0,   5
         });
         vertices.rewind();

         vboVertexID = glGenBuffers();
         glBindBuffer(GL_ARRAY_BUFFER, vboVertexID);
         glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
         glBindBuffer(GL_ARRAY_BUFFER, 0);
	}

DRAWING PARTICLES:

public void renderGL() {
		
		 glClear(GL_COLOR_BUFFER_BIT);
	        
	        // Bind the vertex buffer
	        glBindBuffer(GL_ARRAY_BUFFER, vboVertexID);
	        glVertexPointer(2, GL_FLOAT, 0, 0);
	        
	              
	       
	        glEnableClientState(GL_VERTEX_ARRAY);
	        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	    
	        
	      
	        for(int i = 0;i < particles.size();i++){
				particles.get(i).render();
			}
	       
			glDisableClientState(GL_VERTEX_ARRAY);
		      glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	     
		     
	}
public void render(){
		
		    glBindBuffer(GL_ARRAY_BUFFER, vboVertexID);
	         glVertexPointer(2, GL_FLOAT, 0, 0);
	      
	         GL11.glTranslatef(x, y, 0);
	         glDrawArrays(GL_QUADS, 0, 4);
	         GL11.glTranslatef(-x, -y, 0);

	        
	}

I am clearly doing something wrong, please help me.

instead of creating one BO for each particle create one buffer which holds all particles.

How i should do that? Any examples would be great.

What do you mean? Just put all particle data into 1 big fat VBO.

You could put all particles into a list, then create a vbo and add each particles vertices into that single vbo.

OpenGL doesn’t know what a “particle” is, it just understands triangles and other primitives. You can feed it thousands of triangles in a single VBO, and it will render them all in a single draw call. This will be much faster than issuing a draw call for each particle.

Some tips for fast particles:

  • Use triangles instead of quads. You can use two triangles if you need a square-like particle texture. But many particles (e.g. feathered white circle) can be defined with a single triangle, by offsetting texture coordinates.
  • Use a separate buffer for texture coordinates, since they are probably going to be static. Unless of course you use sprite sheets or something.
  • Avoid glTranslate/etc. You should probably also use custom vertex attributes instead of relying on fixed-function.
  • If your particles need simple or predictable movement (e.g. modeled with an equation), then you can keep all of your vertex data static and update position/size/etc in your vertex shaders. This will be super fast.
  • More complex particle systems might use instance draw calls, transform feedback, or float textures and FBOs to try and take full advantage of the GPU. Honestly, these are a bit overkill if you just need a simple 2D particle system.

I just want to learn basics of VBO and create simple particles system. I would like to get simple example how i can draw multiple particles in single VBO. I mean i know how i can draw multiple particles in single VBO, but i have no idea how i can change each particle position?

[quote]You could put all particles into a list, then create a vbo and add each particles vertices into that single vbo.
[/quote]
I would like to get example in code :slight_smile:

Not trying to push outdated stuff but because particles are dynamic I would simply use the built in vertex arrays from opengl 1.1 They are stupid easy to use and give huge boosts in performance. They are also rather easy to change to using more advanced VBO stuff later.

Although, it would most likely be better to just learn the most modern stuff as it is more useful overall. Good luck.

PS: for particles systems. Unless you need 100k+ particles, basic batching will be fine. Like davedes said, most of the advanced stuff he posted is generally for large projects that need 100K+ but for us small indie/hobbyist devs we do not need that much.

Uhm you’re just lazy. Everyone is when they are saying something like that. Everyone says that from time to time.

I’m lazy to learn something, so I will try to explain how to do it to you.

  • Create a VBO (You know how to do it I believe).
  • Don’t add particle’s data to any VBO when creating particles.
  • Make an array or a list of particles.
  • Just make the particles static (not moving at all) for the first time you’re trying this.
  • Go through your array or list. Add each particles vertices to the FloatBuffer like you did with each single particle.
  • After you added all particles vertices to the FloatBuffer, send the FloatBuffer to VBO.

You’re kinda done.

To edit data in the VBO, you need to use glMapBuffer(); It will return a ByteBuffer. You can do ByteBuffer.asFloatBuffer to get FloatBuffer from it. That will return the FloatBuffer that you sent to the VBO.
You can edit that FloatBuffer as you like.

Thanks! now i am starting to understand this.

Because particles are dynamic you will need to update the VBO or VBOs holding the particle information every frame. You do not need to build a whole new VBO but you have to map stuff. Mapping and buffering only particles that change seems like a good idea for performance but it is hard to tell if a particle needs to be updated or not. If a particle is not doing something, it should be dead anyways.

I strongly recommend making a spritebatcher which is basically all you need for the rendering part of a particle system. There are many examples that use VBOs on here and the webs. davedes has a great tutorial on doing it in the modern style in is signature.

Basic idea of batching which is what VBO are very much about. Well more about buffering data to the GPU where the data can be anything you want.

Few ways.
VBO for vertex position of particles.
VBO for tex coords.
VBO for color info.
VBO for uv/norms/what ever else.

Or
Interleaved VBO
[V C T U V N, V1 C1 T1 U1 V1 N1, … etc ] (vertex color texturecoord uv normal)
[V, V1, V2 … C1, C2, C3… etc]

If using shaders, you will need to set them up properly as well.

Key thing for dynamic data is to build a bytebuffer with your data. It can be mapped or not w/e. Then upload it to GPU and render.

Note: Making particle systems is really kinda easy. But using any system to produce good results is something that I have found very few people have skills in. All the time I play a game or look at screen shots for a game (generally indie or small company) and just want to tear my eyes out at how bad the particle effects are. I am going to do more in my particle system tutorial soon talking about the multiple sense of motion that particles need to produce a realistic effect.