Utilisation des VAO
Sur cette page
L’objet Vertex Array stocke comment opengl doit interpréter un ensemble de VBO.
Essentiellement, cela vous évitera d’appeler glVertexAttribPointer chaque fois que vous souhaitez rendre un nouveau maillage.
Si vous ne voulez pas gérer les VAO, vous pouvez simplement en créer un et le lier lors de l’initialisation du programme et prétendre qu’ils n’existent pas.
Syntaxe
-
annuler glEnableVertexAttribArray(GLuint attribIndex);
-
void glDisableVertexAttribArray(GLuint attribIndex);
-
void glVertexAttribPointer(GLuint attribIndex, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * pointer);
-
void glVertexAttribFormat(GLuint attribIndex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);
-
void glVertexAttribBinding(GLuint attribIndex, GLuint bindingIndex);
-
void glBindVertexBuffer(GLuint bindingIndex, GLuint buffer, GLintptr offset, GLintptr stride);
Paramètres
paramètre | Détails |
---|---|
indexattribut | l’emplacement de l’attribut de sommet auquel le tableau de sommets alimentera les données |
taille | le nombre de composants à extraire de l’attribut |
typer | Le type C++ des données d’attribut dans le tampon |
normalisé | s’il faut mapper les types entiers sur la plage à virgule flottante [0, 1] (pour non signé) ou [-1, 1] (pour signé) |
pointeur | le décalage d’octet dans le tampon au premier octet des données de l’attribut (transformé en void* pour des raisons d’héritage) |
décalage | le décalage d’octet de base entre le début du tampon et l’endroit où les données du tableau commencent |
décalagerelatif | le décalage d’un attribut particulier, par rapport au décalage de base du tampon |
foulée | le nombre d’octets entre les données d’un sommet et le suivant |
tampon | l’objet tampon où les tableaux de sommets sont stockés |
index de reliure | l’index auquel l’objet tampon source sera lié |
La configuration VAO du format d’attribut séparé peut interagir avec glVertexAttribPointer
(ce dernier est défini en fonction du premier). Mais vous devez être prudent lorsque vous le faites.
La version de format d’attribut séparé a des équivalents d’accès direct à l’état (DSA) dans 4.5. Ceux-ci auront les mêmes paramètres mais au lieu d’utiliser le VAO lié, le VAO en cours de modification est passé explicitement. Lors de l’utilisation de DSA, le tampon d’index pour glDrawElements
peut être défini avec glVertexArrayElementBuffer(vao, ebo);
##Version 4.3
OpenGL 4.3 (ou ARB_separate_attrib_format) ajoute une autre façon de spécifier les données de sommet, qui crée une séparation entre le format des données liées à un attribut et la source de l’objet tampon qui fournit les données. Ainsi, au lieu d’avoir un VAO par maille, vous pouvez avoir un format VAO par sommet.
Chaque attribut est associé à un format de sommet et à un point de liaison. Le format de sommet comprend le type, le nombre de composants, s’il est normalisé et le décalage relatif entre le début des données et ce sommet particulier. Le point de liaison spécifie de quel tampon un attribut tire ses données. En séparant les deux, vous pouvez lier les tampons sans respécifier aucun format de sommet. Vous pouvez également modifier le tampon qui fournit des données à plusieurs attributs avec un seul appel de liaison.
//accessible constant declarations
constexpr int vertexBindingPoint = 0;
constexpr int texBindingPoint = 1;// free to choose, must be less than the GL_MAX_VERTEX_ATTRIB_BINDINGS limit
//during initialization
glBindVertexArray(vao);
glVertexAttribFormat(posAttrLoc, 3, GL_FLOAT, false, offsetof(Vertex, pos));
// set the details of a single attribute
glVertexAttribBinding(posAttrLoc, vertexBindingPoint);
// which buffer binding point it is attached to
glEnableVertexAttribArray(posAttrLoc);
glVertexAttribFormat(normalAttrLoc, 3, GL_FLOAT, false, offsetof(Vertex, normal));
glVertexAttribBinding(normalAttrLoc, vertexBindingPoint);
glEnableVertexAttribArray(normalAttrLoc);
glVertexAttribFormat(texAttrLoc, 2, GL_FLOAT, false, offsetof(Texture, tex));
glVertexAttribBinding(texAttrLoc, texBindingPoint);
glEnableVertexAttribArray(texAttrLoc);
Ensuite, pendant le tirage, vous gardez le vao lié et ne modifiez que les liaisons de tampon.
void drawMesh(Mesh[] mesh){
glBindVertexArray(vao);
foreach(mesh in meshes){
glBindVertexBuffer(vertexBindingPoint, mesh.vbo, mesh.vboOffset, sizeof(Vertex));
glBindVertexBuffer(texBindingPoint, mesh.texVbo, mesh.texVboOffset, sizeof(Texture));
// bind the buffers to the binding point
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.ebo);
glDrawElements(GL_TRIANGLES, mesh.vertexCount, GL_UNSIGNED_INT, mesh.indexOffset);
//draw
}
}
##Version 3.0 Chaque attribut est associé à un nombre de composants, un type, une normalisation, un décalage, une foulée et un VBO. Le VBO n’est pas passé explicitement en tant que paramètre mais est plutôt le tampon lié à GL_ARRAY_BUFFER au moment de l’appel.
void prepareMeshForRender(Mesh mesh){
glBindVertexArray(mesh.vao);
glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo);
glVertexAttribPointer (posAttrLoc, 3, GL_FLOAT, false, sizeof(Vertex), mesh.vboOffset + offsetof(Vertex, pos));//will associate mesh.vbo with the posAttrLoc
glEnableVertexAttribArray(posAttrLoc);
glVertexAttribPointer (normalAttrLoc, 3, GL_FLOAT, false, sizeof(Vertex), mesh.vboOffset + offsetof(Vertex, normal));
glEnableVertexAttribArray(normalAttrLoc);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.ebo); //this binding is also saved.
glBindVertexArray(0);
}
void drawMesh(Mesh[] meshes){
foreach(mesh in meshes){
glBindVertexArray(mesh.vao);
glDrawElements(GL_TRIANGLES, mesh.vertexCount, GL_UNSIGNED_INT, mesh.indexOffset);
}
}