opengl
VAOs verwenden
Suche…
Einführung
Das Vertex Array Object speichert, wie opengl eine Gruppe von VBOs interpretieren soll.
Im Wesentlichen können Sie glVertexAttribPointer nicht jedes Mal aufrufen, wenn Sie ein neues Netz rendern möchten.
Wenn Sie nicht mit VAOs arbeiten möchten, können Sie einfach eines erstellen und es während der Programminitialisierung binden.
Syntax
void glEnableVertexAttribArray (GLuint attribIndex);
void glDisableVertexAttribArray (GLuint attribIndex);
void glVertexAttribPointer (GLuint attribIndex, GLint-Größe, GLenum-Typ, GLboolean normalisiert, GLsizei-Schritt, const GLvoid * -Zeiger);
void glVertexAttribFormat (GLuint attribIndex, GLint-Größe, GLenum-Typ, GLboolean-normalisiert, GLuint-Relativoffset);
void glVertexAttribBinding (GLuint attribIndex, GLuint bindingIndex);
void glBindVertexBuffer (GLuint-Bindungsindex, GLuint-Puffer, GLintptr-Offset, GLintptr-Schritt);
Parameter
Parameter | Einzelheiten |
---|---|
attribIndex | Die Position für das Vertex-Attribut, an das das Vertex-Array Daten zuführt |
Größe | Die Anzahl der Komponenten, die aus dem Attribut abgerufen werden sollen |
Art | Der C ++ - Typ der Attributdaten im Puffer |
normalisiert | ob Integer-Typen dem Gleitkommabereich [0, 1] (für vorzeichenlose) oder [-1, 1] (für vorzeichenbehaftet) zugeordnet werden sollen |
Zeiger | der Byte-Versatz in den Puffer zum ersten Byte der Attributdaten (aus void* Gründen in void* ) |
Versatz | das Basisbyte-Offset vom Anfang des Puffers bis zum Beginn der Array-Daten |
relativeOffset | der Versatz zu einem bestimmten Attribut, relativ zum Basisversatz für den Puffer |
schreiten | die Anzahl der Bytes von den Daten eines Scheitelpunkts zum nächsten |
Puffer | das Pufferobjekt, in dem die Vertex-Arrays gespeichert sind |
bindingIndex | der Index, an den das Quellpufferobjekt gebunden wird |
Bemerkungen
Das separate Attributformat-VAO-Setup kann mit glVertexAttribPointer
(letzterer wird als glVertexAttribPointer
definiert). Aber Sie müssen dabei vorsichtig sein.
Die Version des separaten Attributformats weist DSA-Entsprechungen (Direct State Access) in 4.5 auf. Diese haben dieselben Parameter, aber anstatt den gebundenen VAO zu verwenden, wird der VAO, der geändert wird, explizit übergeben. Bei Verwendung von DSA kann der glVertexArrayElementBuffer(vao, ebo);
für glDrawElements
mit glVertexArrayElementBuffer(vao, ebo);
Version 3.0
Jedes Attribut ist einer Komponentenzahl, einem Typ, einem normalisierten Wert, einem Versatz, einem Schritt und einem VBO zugeordnet. Das VBO wird nicht explizit als Parameter übergeben, sondern ist der Puffer, der zum Zeitpunkt des Aufrufs an GL_ARRAY_BUFFER gebunden ist.
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);
}
}
Version 4.3
OpenGL 4.3 (oder ARB_separate_attrib_format) fügt eine alternative Möglichkeit zum Angeben der Scheiteldaten hinzu, wodurch eine Trennung zwischen dem Format der für ein Attribut gebundenen Daten und der Pufferobjektquelle, die die Daten bereitstellt, erstellt wird. Anstelle eines VAO pro Mesh können Sie also ein VAO pro Vertex-Format haben.
Jedes Attribut ist einem Scheitelpunktformat und einem Bindungspunkt zugeordnet. Das Scheitelpunktformat besteht aus dem Typ, der Anzahl der Komponenten, der Normierung und dem relativen Versatz vom Anfang der Daten zu diesem bestimmten Scheitelpunkt. Der Bindungspunkt gibt an, aus welchem Puffer ein Attribut seine Daten bezieht. Durch das Trennen der beiden können Sie Puffer binden, ohne Scheitelpunktformate zu ändern. Sie können den Puffer, der Daten bereitstellt, auch mit einem einzigen Bindungsaufruf in mehrere Attribute ändern.
//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);
Dann halten Sie während des Draws die vao-Bindung und ändern nur die Pufferbindungen.
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
}
}