2011-08-04 3 views
0

Je viens de commencer à travailler avec OpenGL ES dans Android mais je suppose que cela pourrait aussi aller pour d'autres plates-formes mobiles qui utilisent OpenGL ES. J'ai suivi quelques tutoriels pour commencer, mais j'ai l'impression qu'il y a plusieurs choses qui me manquent.Quelles sont les bonnes pratiques OpenGL ES 1.x?

Par exemple, est-ce une bonne pratique que des objets se dessinent individuellement? J'ai un objet cube qui se dessine, alors j'ai un objet "panel" qui est un tableau de 10x10 cubes, et enfin un autre objet qui consiste en des panneaux pour créer un cube comme un objet. J'ai 7500 cubes qui doivent être dessinés, bien que chacun soit très "petit". Voici ce que la fonction de dessin ressemble à:

public void draw(GL10 gl) { 
    gl.glFrontFace(GL10.GL_CCW); 

    gl.glEnable(GL10.GL_CULL_FACE); 
    gl.glCullFace(GL10.GL_BACK); 

    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, verticesBuffer); 

    gl.glColor4f(rgba[0], rgba[1], rgba[2], rgba[3]); 

    gl.glTranslatef(x, y, z); 
    gl.glRotatef(rx, 1, 0, 0); 
    gl.glRotatef(ry, 0, 1, 0); 
    gl.glRotatef(rz, 0, 0, 1); 

    gl.glDrawElements(GL10.GL_TRIANGLES, numOfIndices, 
        GL10.GL_UNSIGNED_SHORT, indicesBuffer); 

    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 
    gl.glDisable(GL10.GL_CULL_FACE); 
} 

Existe-t-il d'autres choses que l'on doit éviter lors de traiter avec OpenGL ES?

Edit: Une autre chose que je me suis demandé, est-il une bonne pratique pour réduire le nombre d'appels à certaines méthodes, telles que

gl.glFrontFace(GL10.GL_CCW); 
gl.glEnable(GL10.GL_CULL_FACE); 
gl.glCullFace(GL10.GL_BACK); 

gl.glDisable(GL10.GL_CULL_FACE); 

Ceci est appelé pour chaque objet quand il est dessiné, est-il une nécessité ou Peut-il être appelé une fois dans mon objet le plus élevé une fois?

aussi:

gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 

gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 

Je me rends compte que activation et la désactivation peut être nécessaire en fonction de la situation, mais si elle peut être évitée, ce ne nuira pas quoi que ce soit?

+0

Vous ne pouvez pas appeler gl.glDrawElements après avoir parcouru chaque objet en boucle? – Mikhail

+0

Il peut être possible en ajoutant tous les sommets et les index dans un tableau? Je ne suis pas tout à fait sûr mais parce que glDrawElements vous oblige à le nourrir les indices de chaque triangle pour dessiner vous auriez besoin de les regrouper tous ensemble. –

Répondre

1

Vous pouvez utiliser un doseur pour grouper tous les vertices dans un tableau puis dessiner, en utilisant un seul appel draw.

EDIT: Voici un exemple de mon projet. J'ai plusieurs PNJ dont j'ai besoin de dessiner et de mettre à jour individuellement afin qu'ils se déplacent indépendamment les uns des autres.

// update 
    for (int i = 0; i < npcs.length; i++) { 
     npcs[i].update(touchEvents); 
    } 

    // draw 
    npcBatcher.beginBatch(Assets.atlas); 
    for (int i = 0; i < npcs.length; i++) { 
     npcs[i].draw(npcBatcher); 
    } 
    npcBatcher.endBatch(); 

Dans ma méthode de tirage au sort, je commence le lot, ajouter au lot et enfin fin le lot (qui fait le dessin en fait). Dans la méthode de mise à jour, je parcourt chaque objet NPC et met à jour CHAQUE NPC. Dans la méthode de mise à jour pour l'objet NPC, je génère aléatoirement quelques nombres et les déplace en fonction du nombre aléatoire (faire toute la logique qui les fait se comporter différemment). Puisque chaque PNJ a sa propre mise à jour avec des nombres générés au hasard, ils agissent tous différemment. Tout le dessin est fait à la fois. Le dessin à la fois n'a pas d'importance, c'est la mise à jour pour chaque objet qui compte et c'est ce que vous cherchez.

+0

Désolé, le traitement par lots permettrait-il le positionnement exact des sommets? Dire que j'avais besoin de faire pivoter un cube, ou dois-je modifier directement les sommets pour qu'ils correspondent aux positions à l'écran? –

+0

Je ne vois pas pourquoi vous auriez besoin de changer vos sommets. Une fois que vous les avez soumis, vous pouvez appeler glRotate() ou glTranslate. Le traitement par lots vous permet simplement d'ajouter tous vos sommets ensemble et de les dessiner tous avec un seul appel de tirage, comparé à plusieurs appels qui peuvent gêner votre performance. – semajhan

+0

Ce que je voulais dire, c'est qu'actuellement, tout est créé autour de (0,0,0) et ensuite pivoté ou traduit en place, chaque fois qu'il est tiré. Je réalise que c'est probablement une mauvaise pratique. Donc ce que je demande est que je devrais faire la rotation et traduire avant de mettre les sommets à la main exactement où je veux et éviter les frais généraux supplémentaires. C'est la seule façon de voir le dessin par lots fonctionner correctement. –

1

votre performance est fortement dépendante de votre nombre d'appels gl, alors essayez de réduire les appels gl. Si c'est votre seul endroit pour dessiner, il n'est pas nécessaire de désactiver la matrice cullface et vertex à chaque fois et de mettre vos appels habilitants de la face de réforme dans la méthode d'initialisation uniquement pour qu'elle ne soit activée qu'une seule fois.

+0

Ok, il n'est donc pas nécessaire de désactiver les options une fois activées à moins que j'active quelque chose qui soit directement en conflit? –

+0

Oui, vous avez raison. – LebRon

Questions connexes