views:

182

answers:

3

I'm currently writing an interactive simulator which displays the evolution of a system of particles. I'm developing on Windows 7 32-bit, using Visual Studio.

Currently, I have a function to draw all the particles on screen that looks something like this:

void Simulator::draw()
{
    glColor4f(255, 255, 255, 0);
    glBegin();
    for (size_t i = 0; i < numParticles; i++)
        glVertex3dv(p[i].pos);
    glEnd();       
}

This works great and all for testing, but it's absurdly slow. If I have 200 particles on screen, without doing any other computations (just repeatedly calling draw()), I get about 60 fps. But if I use 1000 particles, this runs at only about 15 - 20 fps.

My question is: How can I draw the particles more quickly? My simulation runs at a fairly decent speed, and at a certain point it's actually being held back (!) by the drawing.

+6  A: 

The very first optimization you should do is to drop glBegin/glEnd (Immediate mode) and move to Vertex Arrays (VAs) and Vertex Buffer Objects (VBOs).

You might also want to look into Point Sprites to draw the particles.

Matias Valdenegro
A: 

First, if you haven't done so, disable the desktop window manager -- it can make a huge difference in speed (you're basically getting largely software rendering with it turned on).

Second, though I doubt you'll need to, you could switch to using glDrawArrays or glDrawElements (for only a couple among many possibilities).

Jerry Coffin
A: 

this will be unpopular, I know I hate it:

use Direct X instead.

Microsoft have been trying to kill off openGL since Vista. so chances are they are going to make life difficult for you.

so if ALL ELSE fails, you could try using DirectX.

but yeah, what others have said:

-use DrawArrays / Elements

-use Vertex Buffers

-use point sprites

-you could make a vertex shader so that you don't have to update the whole vertex buffer every frame (you just store initial settings like init pos, init velocity, init time, then constant gravity, then the shader can calculate current position each frame based on a single updated global constant 'current time')

-if it is a setting in open GL (like it is in directX) make sure you are using Hardware Vertex Processing)

matt