2016-07-20 1 views
0

J'essayais de rendre un cube et d'appliquer une seule texture sur toutes les faces. en utilisant aussi peu de sommets que possible en passant les index des sommets du visage. exemple:GLES20 Pourquoi les données de texture ne sont pas liées aux index des sommets?

sommets:

static final float FACE_VERTEX[] = { 
     // front 
     0.0f, 1.0f, 1.0f,  //0 
     0.0f, 0.0f, 1.0f,  //1 
     1.0f, 0.0f, 1.0f,  //2 
     1.0f, 1.0f, 1.0f,  //3 

     //back 
     1.0f, 1.0f, 0.0f,  //4 - 3 
     1.0f, 0.0f, 0.0f,  //5 - 2 
     0.0f, 0.0f, 0.0f,  //6 - 1 
     0.0f, 1.0f, 0.0f,  //7 - 0 
}; 

index:

static final int FACE_INDEX[] = { 
     //front 
     0,1,2, 0,2,3, 
     //back 
     4,5,6, 4,6,7, 

     //left 
     7,6,1, 7,1,0, 

     //right 
     3,2,5, 3,5,4, 

     //top 
     4,7,0, 4,0,3, 

     //bottom 
     1,6,5, 1,5,2 

}; 

données de mappage de texture:

final int textureCoordinateData[] = 
     { 
       // Front face 
       0,0, 0,1, 1,1, 1,0, 
       //back 
       0,0, 0,1, 1,1, 1,0, 
       //left 
       0,0, 0,1, 1,1, 1,0, 
       //right 
       0,0, 0,1, 1,1, 1,0, 
       //top 
       0,0, 0,1, 1,1, 1,0, 
       //bottom 
       0,0, 0,1, 1,1, 1,0, 
       //top 
       0,0, 0,1, 1,1, 1,0, 
       //bottom 
       0,0, 0,1, 1,1, 1,0, 


     }; 

La texture est rendue sur toutes les faces du cube, à l'exception supérieure et inférieure . seule la première rangée de pixels de la face avant sont rendus sur la totalité des faces supérieure et inférieure (voir figure):

enter image description here

J'utilise VBOs pour stocker les données vertex/index/texture dans le GPU , et le rendu avec

glDrawElements(GL_TRIANGLES, indexLength, GL_UNSIGNED_INT, 0); 

Toutefois, cette question est parce que les données de texture doivent être mises en correspondance avec les données de sommet passées (ce qui est un peu gênant pour un modèle de cube) et n'est pas calculé par l'indice. Mes questions seront: - Y at-il un moyen de garder les données de sommets aussi bas que possible et mapper la texture aux données d'index? - Si je crée 36 sommets (certains sont répétés) pour résoudre le problème de mappage de texture, mais que j'ai créé les index corrects pour rendre le cube, serait-il encore plus rapide que d'utiliser glDrawArrays? ou dois-je aller avec glDrawArrays et trash les données d'indexation de toute façon?

question connexe (qui n'a pas répondu à ma question):

OpenGL ES - texture map all faces of an 8 vertex cube?

Si vous avez lu le premier commentaire sur la réponse:

Que voulez-vous dire que vous devez utiliser 24 vertexes? Si vous devez dupliquer les sommets, quel est le point d'utiliser un tampon d'index, alors si vous envoyez toujours des données de répétition au GPU?

Répondre

1

Il n'y a vraiment aucun moyen raisonnable de dessiner un cube avec des coordonnées de texture de moins de 24 sommets. C'est parce que ... il a 24 sommets, en utilisant la définition de ce qui forme un sommet dans OpenGL, qui est chaque combinaison unique d'attributs de vertex (position, coordonnées de texture, normal, etc).

Vous pourriez être en mesure de réduire légèrement le nombre avec seulement des positions et des coordonnées de texture, puisque les coordonnées de texture dans votre cas ne sont que des combinaisons de valeurs 0 et 1. Si vous ne vous souciez pas de l'orientation de la texture sur chaque face, vous pourriez par exemple avoir 1 vertex qui utilise (0, 0) pour les coordonnées de texture des 3 faces adjacentes. Bien sûr, vous ne pouvez pas faire cela pour tous les sommets, mais vous pourriez réduire légèrement le nombre de sommets.

L'utilisation d'indices en vaut-elle la peine?Comme vous l'avez déjà trouvé, vous pouvez facilement coller 24 sommets lorsque vous utilisez des index, mais vous avez besoin de 36 sommets avec l'utilisation la plus directe de glDrawArrays(), où vous utilisez un seul appel draw avec GL_TRIANGLES comme type primitif. Cela réduit donc le nombre de sommets.

Vous pouvez également le réduire à 24 sommets avec glDrawArrays(), si vous faites un appel de dessin séparé pour chaque face, et dessinez le visage en utilisant le type primitif GL_TRIANGLE_STRIP avec 4 sommets chacun. Cela se traduira par 6 appels de tirage, cependant, et ayant de nombreux petits appels de tirage n'est pas souhaitable non plus.

Même si cela peut sembler discutable dans le cas d'un cube, les tampons d'index sont très utiles en général. Un cube est juste une forme si petite et si simple que la façon dont vous envoyez les sommets ne fera pas beaucoup de différence de toute façon.

Dans la plupart des cas, vous aurez des formes beaucoup plus complexes, avec beaucoup plus de vertices qui définissent souvent des surfaces lisses. Dans ce cas, le même sommet (avec les mêmes coordonnées normales et de texture) est principalement partagé par plusieurs triangles. Esquissant une partie d'un maillage régulier:

_____________ 
| /| /| /| 
|/|/|/| 
|/__|/__|/__| 
| /| /| /| 
|/|/|/| 
|/__|/__|/__| 

vous pouvez voir que les sommets intérieurs sont partagés par 6 triangles chacun. Ainsi, pour une surface relativement grande et lisse, vous pouvez généralement réduire le nombre de sommets d'environ un facteur de 6 en partageant des sommets, ce que vous pouvez faire en utilisant un tableau d'index. Réduire l'utilisation de la mémoire d'un facteur de 6 peut être un gain substantiel si votre géométrie est suffisamment grande.