How do I draw 1000+ particles (w/ unique rotation, scale, and alpha) in iPhone OpenGL ES particle system without slowing down the game?

StackOverflow https://stackoverflow.com/questions/7435123

Question

I am developing a game for iPhone using OpenGL ES 1.1. In this game, I have blood particles which emit from characters when they are shot, so there can be 1000+ blood particles on the screen at any one time. The problem is that when I have over 500 particles to render, the game's frame rate drops immensely.

Currently, each particle renders itself using glDrawArrays(..), and I know this is the cause for the slow down. All particles share the same texture atlas.

So what is the best option to reduce slow down from drawing many particles? Here are the options I found:

  1. group all the blood particles together and render them using a single glDrawArrays(..) call --if I use this method, is there a way for each particle to have its own rotation and alpha? Or do all of them HAVE to have the same rotation when this method is used? If I can't render particles with unique rotation, then I cannot use this option.
  2. Use point sprites in OpenGL ES 2.0. I am not using OpenGL ES 2.0 yet b/c I need to meet a deadline which I have set to release my game on the App Store. To use OpenGL ES would require preliminary research which unfortunately I do not have the time to perform. I will upgrade to OpenGL ES 2.0 upon a later release, but for the first, I only want to use 1.1.

Here is each particle rendering itself. This is my original particle-rendering methodolgy which caused the game to experience a significant drop in frame rate after 500+ particles were being rendered.

// original method: each particle renders itself.
// slow when many particles must be rendered

[[AtlasLibrary sharedAtlasLibrary] ensureContainingTextureAtlasIsBoundInOpenGLES:self.containingAtlasKey];

glPushMatrix();

// translate
glTranslatef(translation.x, translation.y, translation.z);

// rotate
glRotatef(rotation.x, 1, 0, 0);
glRotatef(rotation.y, 0, 1, 0);
glRotatef(rotation.z, 0, 0, 1);

// scale
glScalef(scale.x, scale.y, scale.z);

// alpha
glColor4f(1.0, 1.0, 1.0, alpha);

// load vertices
glVertexPointer(2, GL_FLOAT, 0, texturedQuad.vertices);
glEnableClientState(GL_VERTEX_ARRAY);

// load uv coordinates for texture
glTexCoordPointer(2, GL_FLOAT, 0, texturedQuad.textureCoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

// render
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glPopMatrix();

Then I used method 1, but particles can't have unique rotation, scale, or alpha using this method (that I know of).

    // this is method 1: group all particles and call glDrawArrays(..) once

    // declare vertex and uv-coordinate arrays
    int numParticles = 2000;
    CGFloat *vertices = (CGFloat *) malloc(2 * 6 * numParticles * sizeof(CGFloat));
    CGFloat *uvCoordinates = (CGFloat *) malloc (2 * 6 * numParticles * sizeof(CGFloat));

    ...build vertex arrays based on particle vertices and uv-coordinates.
    ...this part works fine.


    // get ready to render the particles
    glPushMatrix();
    glLoadIdentity();

    // if the particles' texture atlas is not already bound in OpenGL ES, then bind it
    [[AtlasLibrary sharedAtlasLibrary] ensureContainingTextureAtlasIsBoundInOpenGLES:((Particle *)[particles objectAtIndex:0]).containingAtlasKey];

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);

    glVertexPointer(2, GL_FLOAT, 0, vertices);
    glTexCoordPointer(2, GL_FLOAT, 0, uvCoordinates);

    // render
    glDrawArrays(GL_TRIANGLES, 0, vertexIndex);

    glPopMatrix();

I'll reiterate my question:
How do I render 1000+ particles without frame rate drastically dropping and each particle can still have unique rotation, alpha, and scale?

Any constructive advice would really help and would be greatly appreciated!

Thanks!

No correct solution

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top