Rendu à partir de tampons de vertex et d’index (Direct3D 9)

Les méthodes de dessin indexées et non indexées sont prises en charge par Direct3D. Les méthodes indexées utilisent un ensemble unique d’index pour tous les composants de vertex. Les données de vertex sont stockées dans des tampons de vertex et les données d’index sont stockées dans des mémoires tampons d’index. Voici quelques scénarios courants de dessin de primitives à l’aide de tampons de vertex et d’index.

Ces exemples comparent l’utilisation de IDirect3DDevice9::D rawPrimitive et IDirect3DDevice9::D rawIndexedPrimitive

Scénario 1 : Dessin de deux triangles sans indexation

Supposons que vous souhaitiez dessiner le quad qui est illustré dans l’illustration suivante.

illustration d’un carré composé de deux triangles

Si vous utilisez le type primitif Liste triangle pour afficher les deux triangles, chaque triangle est stocké sous la forme de 3 sommets individuels, ce qui génère une mémoire tampon de vertex similaire à l’illustration suivante.

diagramme d’une mémoire tampon de vertex qui définit trois sommets pour deux triangles

L’appel de dessin est très simple; à partir de l’emplacement 0 dans la mémoire tampon de vertex, dessinez deux triangles. Si l’élimination est activée, l’ordre des sommets est important. Cet exemple suppose l’état d’élimination par défaut dans le sens inverse des aiguilles d’une montre, de sorte que les triangles visibles doivent être dessinés dans l’ordre dans le sens des aiguilles d’une montre. Le type primitif Liste triangle lit simplement trois sommets dans l’ordre linéaire à partir de la mémoire tampon pour chaque triangle, de sorte que cet appel dessine les triangles (0, 1, 2) et (3, 4, 5) :

DrawPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
               0,                  // StartVertex
               2 );                // PrimitiveCount

Scénario 2 : Dessin de deux triangles avec indexation

Comme vous le remarquerez, la mémoire tampon de vertex contient des données en double aux emplacements 0 et 4, 2 et 5. Cela est logique, car les deux triangles partagent deux sommets communs. Ces données en double sont gaspiller et la mémoire tampon de vertex peut être compressée à l’aide d’une mémoire tampon d’index. Une mémoire tampon de vertex plus petite réduit la quantité de données de vertex qui doivent être envoyées à la carte graphique. Plus important encore, l’utilisation d’une mémoire tampon d’index permet à l’adaptateur de stocker les sommets dans un cache de vertex ; si la primitive en cours de dessin contient un vertex récemment utilisé, ce vertex peut être extrait du cache au lieu de le lire à partir de la mémoire tampon de vertex, ce qui entraîne une augmentation importante des performances.

Une mémoire tampon d’index « indexe » dans la mémoire tampon de vertex, de sorte que chaque vertex unique ne doit être stocké qu’une seule fois dans la mémoire tampon de vertex. Le diagramme suivant montre une approche indexée du scénario de dessin précédent.

diagramme d’une mémoire tampon d’index pour la mémoire tampon de vertex précédente

La mémoire tampon d’index stocke les valeurs d’index VB, qui font référence à un sommet particulier dans la mémoire tampon de vertex. Une mémoire tampon de vertex peut être considérée comme un tableau de sommets, de sorte que l’index VB est simplement l’index dans la mémoire tampon de vertex pour le sommet cible. De même, un index IB est un index dans la mémoire tampon d’index. Cela peut devenir très rapidement confus si vous ne faites pas attention. Assurez-vous donc que vous êtes clair sur le vocabulaire utilisé : les valeurs d’index VB sont indexées dans la mémoire tampon de vertex, les valeurs d’index IB dans la mémoire tampon d’index et la mémoire tampon d’index elle-même stocke les valeurs d’index VB.

L’appel de dessin est illustré ci-dessous. Les significations de tous les arguments sont abordées en détail pour le scénario de dessin suivant ; pour l’instant, notez simplement que cet appel indique à nouveau à Direct3D d’afficher une liste de triangles contenant deux triangles, en commençant à l’emplacement 0 dans la mémoire tampon d’index. Cet appel dessine les deux mêmes triangles dans le même ordre qu’auparavant, ce qui garantit une orientation correcte dans le sens des aiguilles d’une montre :

   
DrawIndexedPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
                    0,                  // BaseVertexIndex
                    0,                  // MinIndex
                    4,                  // NumVertices
                    0,                  // StartIndex
                    2 );                // PrimitiveCount

Scénario 3 : Dessin d’un triangle avec indexation

Prétendez maintenant que vous souhaitez dessiner uniquement le deuxième triangle, mais que vous souhaitez utiliser la mémoire tampon de vertex et la mémoire tampon d’index utilisées lors du dessin du quad entier, comme illustré dans le diagramme suivant.

diagramme de la mémoire tampon d’index et de la mémoire tampon de vertex pour le deuxième triangle

Pour cet appel de dessin, le premier index IB utilisé est 3 ; cette valeur est appelée StartIndex. L’index VB le plus bas utilisé est 0 ; cette valeur est appelée MinIndex. Bien que seuls trois sommets soient nécessaires pour dessiner le triangle, ces trois sommets sont répartis sur quatre emplacements adjacents dans la mémoire tampon de vertex; le nombre d’emplacements dans le bloc contigu de mémoire tampon de vertex requis pour l’appel de dessin est appelé NumVertices et sera défini sur 4 dans cet appel. Les valeurs MinIndex et NumVertices ne sont en fait que des conseils pour aider Direct3D à optimiser l’accès à la mémoire pendant le traitement du vertex logiciel, et peuvent simplement être définies pour inclure l’ensemble de la mémoire tampon de vertex au prix des performances.

Voici l’appel de dessin pour le cas de triangle unique ; la signification de l’argument BaseVertexIndex sera expliquée ensuite :

   
DrawIndexedPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
                    0,                  // BaseVertexIndex
                    0,                  // MinIndex
                    4,                  // NumVertices
                    3,                  // StartIndex
                    1 );                // PrimitiveCount

Scénario 4 : Dessin d’un triangle avec indexation de décalage

BaseVertexIndex est une valeur qui est effectivement ajoutée à chaque index VB stocké dans la mémoire tampon d’index. Par exemple, si nous avions passé la valeur 50 pour BaseVertexIndex lors de l’appel précédent, cela serait fonctionnellement identique à l’utilisation de la mémoire tampon d’index dans le diagramme suivant pendant la durée de l’appel DrawIndexedPrimitive :

diagramme d’une mémoire tampon d’index avec la valeur 50 pour basevertexindex

Cette valeur est rarement définie sur autre chose que 0, mais peut être utile si vous souhaitez dissocier la mémoire tampon d’index de la mémoire tampon de vertex : si, lors du remplissage de la mémoire tampon d’index pour un maillage particulier, l’emplacement du maillage dans la mémoire tampon de vertex n’est pas encore connu, vous pouvez simplement prétendre que les sommets de maillage seront situés au début de la mémoire tampon de vertex ; quand vient le temps d’effectuer l’appel de tirage, il vous suffit de passer l’emplacement de départ réel en tant que BaseVertexIndex.

Cette technique peut également être utilisée lors du dessin de plusieurs instances d’un maillage à l’aide d’une mémoire tampon d’index unique ; par exemple, si la mémoire tampon de vertex contenait deux maillages avec un ordre de dessin identique mais des sommets légèrement différents (peut-être des couleurs diffuses ou des coordonnées de texture différentes), les deux maillages peuvent être dessinés à l’aide de valeurs différentes pour BaseVertexIndex. En approfondissant ce concept, vous pouvez utiliser une mémoire tampon d’index pour dessiner plusieurs instances d’un maillage, chacune contenue dans une mémoire tampon de vertex différente, simplement en effectuant un cycle de la mémoire tampon de vertex active et en ajustant le BaseVertexIndex en fonction des besoins. Notez que la valeur BaseVertexIndex est également ajoutée automatiquement à l’argument MinIndex, ce qui est logique lorsque vous voyez comment il est utilisé :

Prétendez maintenant que nous voulons à nouveau dessiner uniquement le deuxième triangle du quad à l’aide du même tampon d’index qu’auparavant; toutefois, une mémoire tampon de vertex différente est utilisée dans laquelle le quad se trouve à l’index VB 50. L’ordre relatif des sommets quad reste inchangé, seul l’emplacement de départ dans la mémoire tampon de vertex est différent. La mémoire tampon d’index et la mémoire tampon de vertex ressemblent au diagramme suivant.

diagramme de la mémoire tampon d’index et de la mémoire tampon de vertex avec un index vb de 50

Voici l’appel de tirage approprié; Notez que BaseVertexIndex est la seule valeur qui a changé par rapport au scénario précédent :

   
DrawIndexedPrimitive( D3DPT_TRIANGLELIST, // PrimitiveType
                    50,                 // BaseVertexIndex
                    0,                  // MinIndex
                    4,                  // NumVertices
                    3,                  // StartIndex
                    1 );                // PrimitiveCount

Rendu des primitives