Je me demandais quel état est stocké dans un VAO OpenGL. J'ai compris qu'un VAO contient un état lié aux spécifications des sommets des sommets tamponnés (quels attributs sont dans les tampons et quels tampons sont liés, ...). Pour mieux comprendre l'utilisation correcte des VAO, j'aimerais savoir exactement dans quel état ils se trouvent.
Comment je suppose que les VAO doivent être utilisés
À partir d'exemples simples, j'ai compris que l'utilisation correcte des VAO est la suivante:
Installer
Generate VAO
BindVAO
---- Specify vertex attributes
---- Generate VBO's
---- BindVBO's
-------- Buffer vertex data in VBO's
---- Unbind VBO's
Unbind VAO
Le rendu
Bind VAO
---- Draw
Unbind VAO
De cela, je suppose qu'au moins les liaisons de tampon de sommet et les spécifications d'attribut de sommet sont stockées dans le VAO. Je ne sais pas cependant comment ce modèle d'utilisation s'étend aux situations où (plusieurs) textures et (multiples) programmes de shader entrent en jeu. Le programme de shader actif est-il stocké dans le VAO? Et les liaisons de texture (avec leurs paramètres d'échantillonnage / d'emballage ) sont-elles également stockées dans le VAO? Idem pour les uniformes ?
Par conséquent, mes questions sont les suivantes:
- Quel état exact est stocké dans un VAO OpenGL ? (Liaisons VBO, spécifications d'attributs, programme de shader actif, liaisons de texture, paramètres d'échantillonnage / habillage de texture, uniformes ...?)
- Comment utiliser correctement les VAO dans une configuration de rendu plus complexe où (plusieurs) textures avec des paramètres d'échantillonnage / habillage associés, (plusieurs) programmes de shader et uniformes sont impliqués?
Réponses:
VAO stocke des données sur les emplacements des attributs de sommet. (Et certaines autres données qui leur sont liées.)
"VBO bindings, active shader program, texture bindings, texture sampling/wrapping settings, uniforms"
N'y sont absolument pas liées.Vous pouvez vous demander pourquoi il ne se souvient pas de la liaison VBO. Parce que vous n'avez pas besoin de lier VBO pour dessiner quelque chose, vous devez seulement le lier lors de la création de VAO: Lorsque vous appelez
glVertexAttribPointer(...)
, VAO se souvient de quel VBO est actuellement lié. Et VAO prendra les attributs de ces VBO lorsque vous le dessinerez, même si ces VBO ne sont pas liés actuellement.De plus, les VAO et les VBO doivent être utilisés légèrement différemment:
Cela ne fonctionnera pas
car vous devez lier VBO pour spécifier les emplacements des attributs.
Donc, vous devriez le faire comme ceci:
Vous pouvez modifier les données de VBO à tout moment, mais vous devez les lier avant.
Et le dessin devrait ressembler à ceci:
Comme vous l'avez peut-être remarqué, j'ai supprimé les
unbind
appels de vos listes. Ils sont presque complètement inutiles et ils ralentiront légèrement votre programme, donc je ne vois aucune raison de les appeler.la source
gl{Enable|Disable}VertexAttribArray()
), leurs valeurs par défaut (glVertexAttrib*()
), leur mode d'instanciation (glVertexAttribDivisor()
) et probablement autre chose.Il stocke uniquement la liaison de sommet et la liaison de tampon d'index
Il s'agit de tous les paramètres de
glVertexAttribPointer
plus le tampon lié à Vertex_Array_buffer au moment de l'appel àglVertexAttribPointer
et le Element_Array_buffer lié.Les uniformes font partie du programme actuel.
Tout le reste est un état global.
Dans le doute, vous pouvez vérifier les tables d'état dans les spécifications de la version que vous utilisez.
la source
Voici une explication simple mais efficace, fondamentalement, un objet tampon contient des informations qui peuvent être interprétées comme de simples bits de données brutes, ce qui en soi ne signifie rien, il s'agit donc purement et simplement de données qui peuvent être consultées de toute façon.
et la façon dont OpenGL a été conçu pour fonctionner est que vous devez DÉFINIR à quoi les données que votre passage aux différents shaders va ressembler pour les shaders
en ce que vous devez également définir comment il lira ces données, dans quel format elles sont, et quoi en faire et comment elles seront utilisées et pour quoi, toutes ces informations sont stockées dans le VAO
par exemple, vous pouvez déclarer des données stockées dans un tableau comme celui-ci
float vbo = {11.0,2.0,3.0,4.0}
ce qui est nécessaire ensuite à ce stade est de savoir comment interpréter ces données du VBO dans le VAO, et ce que cela signifie est comme suit
le VAO peut être réglé pour lire 2 flotteurs par sommet (ce qui en ferait 2 vecteurs à deux dimensions x, y) ou vous pouvez dire au vao de l'interpréter comme 1 vecteur à 4 dimensions, c'est-à-dire x, y, z, w, etc.
mais aussi d'autres attributs de ces données sont définis et stockés dans le VAO tels que le format de données (malgré que vous ayez déclaré un tableau de float, vous pouvez dire au shader de le lire sous forme d'entier, avec bien sûr le système convertissant les données brutes en le processus de float à integer et a son propre ensemble de règles que faire dans de telles circonstances)
Donc, fondamentalement, le VBO est les données, et le VAO stocke comment interpréter ces données, car les shaders et le serveur OpenGL sont conçus pour être très curieux et doivent tout savoir avant de décider comment les traiter et quoi en faire et où pour le dire
bien sûr, ce n'est pas vraiment curieux, il semble en fait être le plus efficace car il doit stocker ces données dans la mémoire du serveur graphique afin d'obtenir le traitement le plus efficace et le plus rapide (à moins qu'il ne décide qu'il n'a pas besoin de le faire si les données ne doivent pas être traitées de cette manière et utilisées pour d'autres informations qui ne sont pas souvent consultées), et donc pourquoi les détails de ce qu'il faut faire avec les données et comment les traiter doivent être stockés dans le VAO, donc le VAO est comme un en-tête et le VBO est comme les données brutes pures que l'en-tête utilise et définit (dans ce cas, passe aux attributs de vertex du shader) à l'exception que le VBO n'est pas limité à être utilisé uniquement par un VAO, il peut être utilisé et réutilisé et lié à de nombreux VAO, par exemple:
ce que vous pouvez faire, c'est que vous pouvez lier un objet tampon à VAO1 et également (séparément) lier le même objet tampon à VAO2 avec chacun l'interprétant différemment de sorte que si votre shader où traiter les données, selon quel VAO est celui qui est lié, il traiterait les mêmes données brutes différemment du frambuffer (dessin des pixels dans la fenêtre) résultant en un affichage différent des mêmes données qui serait basé sur la façon dont vous avez défini leur utilisation dans le VAO
la source