web-dev-qa-db-fra.com

Utilisation d'objets Vertex Array et Vertex Buffer Objects

J'essaie de comprendre ces deux, comment les utiliser et comment ils sont liés. Disons que je veux créer un terrain simple et un cube texturé. Pour les deux objets, j'ai le tableau de sommets de triangles et pour le cube, j'ai un tableau contenant les données de la texture. Ma question est: comment utiliser les VAO et les VBO pour créer et rendre ces deux?

  1. Dois-je créer un VAO et un VBO pour chaque objet?
  2. ou faut-il créer un VAO pour le VBO de chaque objet (sommets, données de texture, etc.)?

Il existe de nombreux didacticiels et livres, mais je ne comprends toujours pas comment ces concepts doivent être compris et utilisés.

35
ali

Fondamentalement, vous devez comprendre deux choses:

  1. Les objets Vertex Array (VAO) ne sont conceptuellement que des wrappers d'état minces.

  2. Les objets tampons Vertex (VBO) stockent les données réelles.

Une autre façon de penser à ce sujet est que les VAO décrivent les données stockées dans un ou plusieurs VBO.

Considérez les VBO (et les objets tampons en général) comme des tableaux non structurés de données stockées dans la mémoire du serveur (GPU). Si vous le souhaitez, vous pouvez disposer vos données de sommet dans plusieurs tableaux, ou les regrouper dans un seul tableau. Dans les deux cas, les objets tampons se résument aux emplacements où vous stockerez les données.

Les objets Vertex Array suivent le réel pointeurs vers la mémoire VBO nécessaire pour les commandes de dessin.

Ils sont un peu plus sophistiqués que les pointeurs car vous les connaissez dans un langage comme C, cependant. Les pointeurs de sommet gardent une trace de l'objet tampon qui était lié quand ils ont été spécifiés, du décalage dans son espace d'adressage, de la marche entre les attributs de sommet et de la façon d'interpréter les données sous-jacentes ( par exemple s'il faut conserver les valeurs entières ou pour les convertir en virgule flottante [ 0,0 , 1,0 ] par normalisation à la plage du type de données).

Par exemple, les données entières sont généralement converties en virgule flottante, mais c'est la commande que vous utilisez pour spécifier le pointeur de sommet ( glVertexAttribPointer (...) vs glVertexAttribIPointer (...) ) qui détermine ce comportement.

Les objets Vertex Array suivent également l'objet tampon actuellement lié à GL_ELEMENT_ARRAY_BUFFER.

GL_ELEMENT_ARRAY_BUFFER Est l'endroit où la commande: glDrawElements (...) tire sa liste d'indices (en supposant une liaison non nulle) et il n'y en a pasglElementArrayPointer (...) commande. glDrawElements (...) combine la commande pointeur et dessin en une seule opération et utilisera la liaison stockée dans l'objet Vertex Array actif pour accomplir cela.


Avec cela à l'écart, à moins que vos objets partagent des données de vertex, vous aurez généralement besoin d'un ensemble unique de VBO pour chacun.

Vous pouvez utiliser un seul VAO pour l'ensemble de votre logiciel si vous le souhaitez, ou vous pouvez profiter du fait que la modification du VAO lié modifie presque l'ensemble des états nécessaires pour dessiner différents objets.

Ainsi, dessiner votre terrain et votre cube pourrait être aussi simple que de changer la VAO liée. Vous devrez peut-être faire plus que cela si vous devez appliquer des textures différentes à chacun d'eux, mais le VAO s'occupe de toutes les configurations liées aux données de vertex.

59
Andon M. Coleman

Votre question n'est pas facile à répondre ici, mais plutôt dans un tutoriel. Vous connaissez probablement déjà ces deux sites, mais sinon, je laisse les références.

OGLDEV

OpenGL-Tutorial.org

Maintenant que nous essayons d'élucider vos questions, un objet tableau de vertex est un objet OpenGL conçu dans le but de réduire la surcharge de l'API pour les appels de tirage. Vous pouvez le considérer comme un conteneur pour un tampon de sommet et ses états associés. Quelque chose de similaire peut-être aux anciennes listes d'affichage. Normalement, il existe une relation 1 à 1 entre un VAO et un VBO; c'est-à-dire que chaque VAO contient un VBO unique. Mais ce n'est pas strictement nécessaire. Vous pouvez avoir plusieurs VAO référençant le même VBO.

La façon la plus simple de modéliser cela dans le code, je pense, serait que vous ayez une classe/type VAO et une méthode pour y attacher un VBO. Donnez ensuite une instance de VAO à chaque maillage. Le maillage à son tour peut avoir une référence à un type VBO qui peut être le sien ou partagé.

8
glampert