41 votes

Quand dois-je utiliser des tableaux indexés de OpenGL sommets?

Je suis en train de vous faire une idée de quand je devrais être à l'aide de tableaux indexés de OpenGL sommets, dessinés avec de la gl[Multi]DrawElements et autres, par rapport à quand je dois simplement utiliser contiguë tableaux de sommets, dessinés avec de la gl[Multi]DrawArrays.

(Mise à jour: Le consensus dans les réponses que j'ai est qu'il faut toujours être indexés à l'aide de sommets.)

Je suis allé en arrière et en avant sur ce sujet à plusieurs reprises, donc je vais vous décrire ma compréhension actuelle, dans l'espoir que quelqu'un pouvez me dire que je suis maintenant, enfin, plus ou moins corrects, ou d'autre point où mes restants de malentendus sont. Plus précisément, j'ai trois conclusions, en caractères gras. Veuillez les corriger si elles sont mauvaises.

Un cas simple est si mon géométrie est constituée de mailles pour former une surface courbe. Dans ce cas, les sommets au milieu de la maille ont les mêmes attributs (position normale, la couleur, la texture coord, etc) pour chaque triangle, qui utilise le sommet.

Ce qui m'amène à conclure que:

1. Pour la géométrie avec peu de coutures, les tableaux indexés sont une grande victoire.

Suivre la règle est toujours de 1, à l'exception:

Pour la géométrie qui est très "carrées", dans lequel chaque arête représente une couture, l'avantage des tableaux indexés est moins évident. Pour prendre un simple cube par exemple, bien que chaque sommet est utilisé dans trois visages différents, nous ne pouvons pas partager les sommets entre eux, parce que pour un seul sommet, les normales de la surface (et éventuellement d'autres choses, comme la couleur et la texture de la co-ord) sera différent sur chaque face. Donc nous avons besoin d'introduire explicitement redondant positions des sommets dans notre tableau, de sorte que la même position peuvent être utilisées plusieurs fois avec différents normales, etc. Cela signifie que les tableaux indexés sont de moins.

par exemple, Lors du rendu d'une seule face d'un cube:

 0     1
  o---o
  |\  |
  | \ |
  |  \|
  o---o
 3     2

(cela peut-être considéré de manière isolée, car les joints entre ce visage et toutes les faces adjacentes dire qu'aucune de ces sommets peuvent être partagés entre les faces)

si le rendu à l'aide de GL_TRIANGLE_FAN (ou _STRIP), puis chaque face du cube peut être traduit ainsi:

verts  = [v0, v1, v2, v3]
colors = [c0, c0, c0, c0]
normal = [n0, n0, n0, n0]

L'ajout d'indices ne nous permettent pas de le simplifier.

D'où je conclus que:

2. Lors du rendu de la géométrie qui est toutes les coutures ou presque coutures, lors de l'utilisation de GL_TRIANGLE_STRIP ou _FAN, alors je ne devriez pas utiliser des tableaux indexés, et de toujours utiliser gl[Multi]DrawArrays.

(Mise à jour: Réponses indiquent que cette conclusion est erronée. Même si les indices ne permettent pas de réduire la taille des tableaux ici, ils doivent toujours être utilisés en raison de d'autres avantages, comme mentionné dans les commentaires)

La seule exception à la règle 2 est:

Lors de l'utilisation de GL_TRIANGLES (au lieu de bandes ou de fans), alors la moitié de l'sommets peuvent encore être ré-utilisé deux fois, à l'identique les normales et les couleurs, etc, parce que chaque face du cube est rendu en deux triangles. Encore une fois, pour la même face du cube:

 0     1
  o---o
  |\  |
  | \ |
  |  \|
  o---o
 3     2

Sans indices, à l'aide de GL_TRIANGLES, les tableaux serait quelque chose comme:

verts =   [v0, v1, v2,  v2, v3, v0]
normals = [n0, n0, n0,  n0, n0, n0]
colors =  [c0, c0, c0,  c0, c0, c0]

Depuis un sommet et un normal sont souvent de 3 flotteurs de chacun, et d'une couleur est souvent de 3 octets, ce qui donne, pour chaque face du cube, à propos de:

verts   = 6 * 3 floats = 18 floats
normals = 6 * 3 floats = 18 floats
colors  = 6 * 3 bytes  = 18 bytes

= 36 floats and 18 bytes per cube face.

(Je comprends le nombre d'octets pourrait changer si les différents types sont utilisés, les chiffres exacts sont juste pour l'illustration).

Avec les indices, on peut simplifier un peu, en donnant:

verts   = [v0, v1, v2, v3]     (4 * 3 = 12 floats)
normals = [n0, n0, n0, n0]     (4 * 3 = 12 floats)
colors  = [c0, c0, c0, c0]     (4 * 3 = 12 bytes)
indices = [0, 1, 2,  2, 3, 0]  (6 shorts)

= 24 floats + 12 bytes, and maybe 6 shorts, per cube face.

Voir comment dans ce dernier cas, les sommets 0 et 2 sont utilisées deux fois, mais seulement représenté une fois dans chacun des verts, les normales et les couleurs des tableaux. Cela sonne comme une petite victoire pour l'aide d'indices, même dans le cas extrême de chaque géométrie d'arête étant une couture.

Ce qui m'amène à conclure que:

3. Lors de l'utilisation de GL_TRIANGLES, on devrait toujours utiliser des tableaux indexés, même pour la géométrie qui est toutes les coutures.

Merci de corriger mes conclusions en gras si elles sont mauvaises.

33voto

Luca Points 5487

D'où je conclus que lors du rendu de la géométrie qui est toutes les coutures ou presque coutures, lors de l'utilisation de GL_TRIANGLE_STRIP ou _FAN, alors je ne devriez pas utiliser des tableaux indexés, et de toujours utiliser gl[Multi]DrawArrays.

Non, et la raison en est très simple.

Votre conclusion est basée sur le fait que vous avez analysé un seul quad composé de deux triangles. Ces deux triangles dessinés à l'aide du triangle de ventilateur/bande ne peut pas être simplifiée en utilisant des tableaux indexés.

Mais essayez de penser à un grand terrain de géométrie. Chaque terrain de bloc est dessiné comme un quad, à l'aide du triangle de ventilateur/bande de primitifs. Par exemple:

Chaque triangle strip dans la figure a en commun tous les sommets adjacents triangle bandes, et à l'aide d'indices permettent de compresser la géométrie de la définition, au lieu de répéter les sommets de chaque triangle strip.


Fondamentalement, le dessin primitives (les triangles, les fans et les bandes) à l'aide d'indices sont utiles chaque fois que vous pouvez partager le plus de sommets d'une seule primitive avec un autre.

Le partage de l'information permettent d'enregistrer des informations de transmission de la bande passante, mais il n'est pas le seul avantage. En fait des tableaux indexés permettre:

  • Éviter la synchronisation de l'information appartenant à la même "conceptuel" vertex, a précisé à de nombreuses reprises
  • Permettent d'effectuer la même opération de shader sur un seul sommet au lieu d'exécuter de nombreuses fois, une pour chaque sommet de la duplication.
  • En outre, en combinant l'utilisation du triangle bandes/les fans et les indices de permettre à l'application de compresser les indices de la mémoire tampon, depuis la bande de ventilateur/spécification nécessite moins d'indices (un triangle implique toujours 3 indices pour chaque face).

Tableau indexé, ne peut pas être utilisé, comme vous l'avez spécifié, chaque fois qu'un sommet ne peut pas partager toutes les informations associées (couleur, texture, coordonnées et ainsi de suite) coïncide avec un autre sommet.


Juste pour le plaisir de l'exhaustivité, de la taille de l'information nécessaire pour la spécification géométrique n'est pas le seul facteur qui déterminent la meilleure opération de rendu.

En effet, un autre facteur fondamental pour primitif le rendu est le cache de la localisation des données. Mal spécifié de données de géométrie (non entrelacé tampon objets, long triangle bandes...) provoque beaucoup de défauts de cache, de la dégradation de la carte graphique de la performance.

Afin d'optimiser le rendu de l'opération, le sommet cahier des charges doivent être réorganisées de manière à réutiliser spécifié précédemment sommets, avec le plus de probabilité. De cette façon, la carte graphique de ligne de cache peut réutiliser spécifié précédemment sommets sans chercher à partir de la mémoire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X