Comment dessiner plus de 1000 particules (avec rotation, échelle et alpha unique) dans le système de particules iPhone OpenGl ES sans ralentir le jeu?

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

Question

Je développe un jeu pour iPhone en utilisant OpenGL ES 1.1. Dans ce jeu, j'ai des particules de sang qui émettent des personnages lorsqu'ils sont tournés, il peut donc y avoir plus de 1000 particules de sang à l'écran à tout moment. Le problème est que lorsque j'ai plus de 500 particules à rendre, la fréquence d'images du jeu baisse énormément.

Actuellement, chaque particule se rend en utilisant glDrawarrays (..), et je sais que c'est la cause du ralentissement. Toutes les particules partagent le même atlas de texture.

Alors, quelle est la meilleure option pour réduire le ralentissement du dessin de nombreuses particules? Voici les options que j'ai trouvées:

  1. regrouper toutes les particules de sang ensemble et les rendre en utilisant un seul glDrawarrays (..) appel - Si j'utilise cette méthode, y a-t-il un moyen pour chaque particule d'avoir sa propre rotation et alpha? Ou tous doivent-ils avoir la même rotation lorsque cette méthode est utilisée? Si je ne peux pas rendre des particules avec une rotation unique, je ne peux pas utiliser cette option.
  2. Utilisez des sprites ponctuels dans OpenGL ES 2.0. Je n'utilise pas encore OpenGL ES 2.0 b / c J'ai besoin de respecter une échéance que j'ai définie pour publier mon jeu sur l'App Store. Utiliser des ouvertures nécessiterait des recherches préliminaires qui, malheureusement, je n'ai pas le temps de jouer. Je passerai à OpenGL ES 2.0 sur une version ultérieure, mais pour le premier, je veux seulement utiliser 1.1.

Voici chaque particule se rendant. Il s'agit de ma méthodgie d'origine de rendu de particules qui a fait que le jeu connaît une baisse significative de la fréquence d'images après que plus de 500 particules ont été rendues.

// 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();

Ensuite, j'ai utilisé la méthode 1, mais les particules ne peuvent pas avoir une rotation, une échelle ou un alpha uniques en utilisant cette méthode (que je connais).

    // 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();

Je vais réitérer ma question:
Comment rendre plus de 1000 particules sans la fréquence d'images en baisse considérablement et chaque particule peut encore avoir une rotation, un alpha et une échelle uniques?

Tout conseil constructif aiderait vraiment et serait grandement apprécié!

Merci!

Pas de solution correcte

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top