Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Particles in OpenGL

This thread is locked; no one can reply to it. rss feed Print
Particles in OpenGL
Tobias Dammers
Member #2,604
August 2002
avatar

For my 3d opengl space shooter, I want explosions to be created on-the-fly through sprite particles. I've got a system up & running right now which works ok, but it's slow. The problem is thet when drawing the particle, I need to make horrifying calculations to rotate the sprite's normal vector so that it points toward the viewpoint and the particle appears to be a sphere (instead of the add-blended square texture it is). Also, I need to do this with EVERY particle EVERY frame, which is now 16 particles per explosion. Even on my "moderately" high-end machine (Athlon XP 2000+, GForce4 128MB) that drags me down to 30 fps (instead of smooth 60 when there's no explosion).
I would just love to retrieve the modelview-transformed vertex data back from opengl after reaching the particle's position, then glLoadIdentity(), then glTranslatef() back to that point, but opengl won't give me those coords.
I'd need to do all the matrix calculations by myself then, which is kinda awkward, considering opengl does it for me better and faster.

Any ideas?

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

X-G
Member #856
December 2000
avatar

Quote:

I would just love to retrieve the modelview-transformed vertex data back from opengl after reaching the particle's position, then glLoadIdentity(), then glTranslatef() back to that point, but opengl won't gi

use the feedback buffer?

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

gillius
Member #119
April 2000

Hmm I wonder if OpenGL has the same thing. In Direct3D you can draw particles using point sprites. You set a size attribute and then pass the particles to the buffer, each vertex is a particle. The video card will find that point and draw a quad around it for you. Benefits are that the video card can probably make some optimizations for this case, and the video bandwidth required is cut in a fourth, since you send 1 vertex and not 4. Recent video cards will hardware accelerate it -- D3D has software fallback, but it seems to perform very nicely.

I heard something about the normals and whatnot... Like how people normally thought to do it that way but that is not the way to do them. I've never done particles that way but I haven't done particle systems in OGL yet.

Gillius
Gillius's Programming -- https://gillius.org/

Carrus85
Member #2,633
August 2002
avatar

Google is your friend

Here are some links that I found that may be useful...
OpenGL.org Developers Code Particles

Yahoo Open GL Developer's Group Link

NeHe OpenGL Particles Basic Tutorial

Maybe some of these links would help?

Korval
Member #1,538
September 2001
avatar

Quote:

I need to make horrifying calculations to rotate the sprite's normal vector so that it points toward the viewpoint and the particle appears to be a sphere (instead of the add-blended square texture it is). Also, I need to do this with EVERY particle EVERY frame, which is now 16 particles per explosion. Even on my "moderately" high-end machine (Athlon XP 2000+, GForce4 128MB) that drags me down to 30 fps (instead of smooth 60 when there's no explosion).

You've got a GeForce 4: use a vertex program.

Failing that, the T&L isn't really that bad. Even with an unoptimized library, you should be able to do hundreds without much framerate loss.

Quote:

I would just love to retrieve the modelview-transformed vertex data back from opengl after reaching the particle's position, then glLoadIdentity(), then glTranslatef() back to that point, but opengl won't give me those coords.

That would hurt your performance far more than just doing the T&L yourself.

X-G
Member #856
December 2000
avatar

How exactly does one do hardware T&L anyway?

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Bob
Free Market Evangelist
September 2000
avatar

Quote:

How exactly does one do hardware T&L anyway?

Just use OpenGL functions - they'll be forwarded to the hw if the hw supports the calls; it's all transparent!

Quote:

I would just love to retrieve the modelview-transformed vertex data back from opengl after reaching the particle's position, then glLoadIdentity(), then glTranslatef() back to that point, but opengl won't give me those coords.

You can use the feedback buffer, but that's a bit slow. You can use vertex programs, but then you're limited to GeForce 3 and above. You could also use billboarding (look it up on google).

--
- Bob
[ -- All my signature links are 404 -- ]

X-G
Member #856
December 2000
avatar

Bob: What if I just want to translate a particular point in 3D space without actually rendering anything? Feedback buffer to the rescue?

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Bob
Free Market Evangelist
September 2000
avatar

You can also implement your own matrix multiplication, which will likely be faster than using the feedback buffer.

--
- Bob
[ -- All my signature links are 404 -- ]

X-G
Member #856
December 2000
avatar

But it's not really HARDWARE T&L in that case, is it?

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Bob
Free Market Evangelist
September 2000
avatar

Nope, in that case, it isn't. If you used the feedback buffer, you could end up with hardware T&L. In that case, however, the overhead associated with computing and reading back the data will render the fact that it's hardware driven pretty much pointless.

--
- Bob
[ -- All my signature links are 404 -- ]

X-G
Member #856
December 2000
avatar

What is the feedback buffer really good for then?

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

gillius
Member #119
April 2000

GL must have a way to do point sprites. Maybe through an extension. My particle engine I wrote using just the stock off-the-shelf D3D point sprite vertex lists I had in my game (had a landscape engine and a skeletal animation system with lots of terrain objects) I was pushing through 1000+ particles per frame with basically no slowdown, and I was still getting triple digit FPS.

Gillius
Gillius's Programming -- https://gillius.org/

Ashteth
Member #3,310
March 2003
avatar

I agree, reading back from the hardware buffer would be horribly inefficient. The most significant speed inhibitor in modern 3D graphics is in fact the system bus and using it twice (once to write a matrix and once to retrieve a matrix) would be highly inefficient. If you want to do particle systems correctly you should either do the matrix multiplications yourself and render the entire system at once as a vertex array/buffer or (since you have a GeForce 4), use the new NV_point_sprite extension. Point sprites do all the rotation calculations for you on the hardware so it is extremely fast. Unfortunately this is currently GeForce 4 only. There is currently no standard OpenGL extension for this and unlike DirectX, GL does not simulate Point Sprites in software for non-compliant cards.

If you aren't interested in writing your own math library, I suggest you check out NVidia's website and search for point sprites or use the aforementioned Nehe tutorials (even though Nehe uses immediate mode ::)). If you want to go the Nehe route, I suggest you add this to the start of the drawing phase: glDepthMask(0) and this to the end: glDepthMask(1). This will enable / disable writing to the depth buffer and allow you to use the Nehe code in 3D (which it currently can't do very well). Actually this is probably what is causing your artifact problem as well. Someone should probably tell Nehe to update the tutorials...

I chose to write my own math libs, but it took several months and understandably you may not have the time to do this. I can't thinks of a better way of learning 3D though.

Korval
Member #1,538
September 2001
avatar

Quote:

What is the feedback buffer really good for then?

Nothing.

It is one of a small number of ill-concieved features in the OpenGL API. That's what happens when you try to predict the future: sometimes you get it right (hardware T&L), and sometimes you get it wrong.

Quote:

If you want to do particle systems correctly you should either do the matrix multiplications yourself and render the entire system at once as a vertex array/buffer or (since you have a GeForce 4), use the new NV_point_sprite extension.

You can use a vertex program. With that, you can do far more interesting tricks, like 1D-point-sprites.

Quote:

There is currently no standard OpenGL extension

You speak too soon.

The ARB just tentitively approved ARB_point_sprite. Granted, it's not avaliable yet, but it is coming with the next GL revision.

Quote:

If you aren't interested in writing your own math library

You can just download one for free ;) There are several on the net.

gillius
Member #119
April 2000

My guru OpenGL friend told me about the matrix hack:

glGetDoublev(GL_MODELVIEW_MATRIX, m);
 
 
m[0] = 1; m[1] = 0;
m[2] = 0;
 
m[4] = 0; m[5] = 1;
m[6] = 0;
 
m[8] = 0; m[9] = 0;
m[10] = 1;
 
 
glLoadMatrixd(m);

Then you draw your particles in 2D expanding them on the X-Y plane. The video card will do the transformation for you. No need to orientate the triangles or anything. No need for calculations on the CPU.

And he says that it will make the particles smaller as you go out, and bigger as you get close, like they do as well in D3D by certain options.

D3D has options to change the min particle size and max particle size and adjust how it changes size, and you can even make them the same size at any distance -- in that sense D3D will clip as well. So I'm guessing this code acts as if you drew a quad in real space, which is what you want almost all the time, though.

But if you wanted to clip to min and max or not have the particles attinuate then that may be why there is an ARB_point_sprite and not just a matrix hack?

Gillius
Gillius's Programming -- https://gillius.org/

Go to: