Come faccio a disegnare 1000+ particelle (con rotazione unica, scala e alfa) nel sistema di particelle di iPhone OpenGL senza rallentare il gioco?

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

Domanda

Sto sviluppando un gioco per iPhone usando OpenGL ES 1.1. In questo gioco, ho particelle di sangue che emettono dai personaggi quando vengono girati, quindi ci possono essere oltre 1000 particelle di sangue sullo schermo contemporaneamente. Il problema è che quando ho oltre 500 particelle da rendere, la frequenza dei frame del gioco scende immensamente.

Attualmente, ogni particella si rende utilizzando gldrawarrays (..), e so che questa è la causa del rallentamento. Tutte le particelle condividono la stessa trama atlante.

Allora qual è l'opzione migliore per ridurre il rallentamento dal disegno di molte particelle? Ecco le opzioni che ho trovato:

  1. raggruppa tutte le particelle di sangue insieme e renderle usando un singolo gldrawarrays (..) chiamata -Se uso questo metodo, c'è un modo per ogni particella di avere la propria rotazione e alfa? O tutti devono avere la stessa rotazione quando viene utilizzato questo metodo? Se non riesco a rendere particelle con una rotazione unica, non posso usare questa opzione.
  2. Usa gli sprite punti in OpenGL ES 2.0. Non sto usando OpenGL ES 2.0 ma b/c Ho bisogno di rispettare una scadenza che ho impostato per rilasciare il mio gioco sull'App Store. Utilizzare gli OpenGL richiederebbero ricerche preliminari che purtroppo non ho il tempo di esibirmi. Aggiornerò a OpenGL ES 2.0 su una versione successiva, ma per la prima, voglio solo usare 1.1.

Ecco ogni particella che si renderà se stessa. Questa è la mia metodolgia originale di rendering delle particelle che ha causato un calo significativo del gioco dopo che venivano resi oltre 500 particelle.

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

Quindi ho usato il metodo 1, ma le particelle non possono avere una rotazione, una scala o un alfa unici usando questo metodo (che conosco).

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

Ribaderò la mia domanda:
Come faccio a renderla 1000+ particelle senza la frequenza fotogramma che cade drasticamente e ogni particella può ancora avere una rotazione, alfa e scala unici?

Qualsiasi consiglio costruttivo aiuterebbe davvero e sarebbe molto apprezzato!

Grazie!

Nessuna soluzione corretta

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top