VBO Concept Question

Started by
4 comments, last by Katie 12 years, 11 months ago
I'm currently using immediate mode in a game I'm writing to learn OpenGL, and it's getting pretty slow when there are a lot of particles being drawn on-screen, so I'm wondering if I should switch to VBO's.

Conceptually however, I'm a little confused about VBO's. Currently, I have particle objects that store their position, velocity, etc. To draw my particles, I use glTranslate* and glRotate, and then use a fixed set of vertices to draw my particles (as quads). How would I do this with VBO's? Would I have to store the raw vertices of every particle in the VBO? Would using a VBO in this case even make sense, or should I look at something else? Does it make sense the way I'm doing it now, or should I be storing my vertices in the particle objects themselves, and not using glTranslate at all?

Maybe I'm mistaken in thinking that I can't still use glTranslate? Since all of my particles use the same set of vertices, do I just store those vertices in my VBO, and then use glTranslate and draw them one at a time? If so, would that really speed anything up?
Advertisement
VBO is just a block of memory which lives on the graphics card.

The point is that the card can read the vertex data when you ask it instead of having to send it every time.

There are multiple ways to use the VBO data.

The simple way is that you can just put the billboarded vertex data into the VBO and draw it. The draw will complete faster because it will no longer block on the CPU feeding vertices to the card.

Next up is putting the real world particle coord into the VBO along with a corner number and other data for each particle x each corner. The shader turns those into a billboard centred on the coord.

Next up is using instancing and reading the vertex data out using the shader texture read calls (using the instance number) so you only have one copy of each particle's data.

VBO is just a block of memory which lives on the graphics card.

The point is that the card can read the vertex data when you ask it instead of having to send it every time.

There are multiple ways to use the VBO data.

The simple way is that you can just put the billboarded vertex data into the VBO and draw it. The draw will complete faster because it will no longer block on the CPU feeding vertices to the card.

Next up is putting the real world particle coord into the VBO along with a corner number and other data for each particle x each corner. The shader turns those into a billboard centred on the coord.

Next up is using instancing and reading the vertex data out using the shader texture read calls (using the instance number) so you only have one copy of each particle's data.


So it sounds like, in the case of a particle engine, the VBO wouldn't really be that much faster then? The particles are going to be updating pretty much every frame (every frame actually in my game loop, but eventually I hope to separate my framerate from my particle updates...), so that means I'd probably use the "STREAM" hint for the VBO and sending vertices to the card every frame anyway.

Please correct me if I'm wrong, but it definitely sounds like VBO's wouldn't be much of an improvement for things that are constantly updating.
You can use Vertex Arrays instead of VBOs for this situation which might be more natural than copying over the data to the gpu each frame. The syntax is almost exactly the same as VBO's except the vertex data is read from system memory instead of a gpu buffer.

However anything else should be much faster than the immediate mode you're using right now.

There is some time penalty with each opengl call that you make, and most of the immediate mode slowdown comes from calling several api commands for each vertex, while the alternative (VA's or VBO's) you invoke maybe 5-10 commands which then can draw thousands of triangles in a single uninterrupted batch.

One idea may be to create a buffer in your program of all of the vertex positions (do the coordinate transform on the cpu), and then stream that buffer to opengl as a big batch of quads.

You lose the benefit of doing vertex transform on the gpu, but for such small objects (4 verts), I think that would be outweighed by the benefit of not having to interrupt opengl every couple vertices to change the transform matrices. You just calculate all the vertex positions locally and then render all of the particles in a single call.
[size=2]My Projects:
[size=2]Portfolio Map for Android - Free Visual Portfolio Tracker
[size=2]Electron Flux for Android - Free Puzzle/Logic Game
There is a nvidia demo called gpu_particles. Have a look.
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
The NV demo and also a similar system inside the GLSL orange book do the *physics* part of the system on the card as well. The VBO contains the emission x,y,z and time for the particles and a lifetime and so on. The global time is set in a uniform and then the vertex shader can do the s=ut+1/2at^2 type sums.

This means that the buffer only needs updating to add/remove particles.

This topic is closed to new replies.

Advertisement