Sök…


Introduktion

Vertex Array Object lagrar hur opengl ska tolka en uppsättning VBO: er.

I huvudsak låter det dig undvika att ringa glVertexAttribPointer varje gång du vill göra ett nytt nät.

Om du inte vill ta itu med VAO: er kan du helt enkelt skapa en och binda den under programinitieringen och låtsas att de inte finns.

Syntax

  • void glEnableVertexAttribArray (GLuint attribIndex);

  • void glDisableVertexAttribArray (GLuint attribIndex);

  • void glVertexAttribPointer (GLuint attribIndex, GLint storlek, GLenum typ, GLboolean normaliserad, GLsizei steg, const GLvoid * pointer);

  • void glVertexAttribFormat (GLuint attribIndex, GLint storlek, GLenum typ, GLboolean normaliserad, GLuint relative offset);

  • void glVertexAttribbindning (GLuint attribIndex, GLuint bindingIndex);

  • void glBindVertexBuffer (GLuint bindingIndex, GLuint buffert, GLintptr offset, GLintptr steg);

parametrar

parameter detaljer
attribIndex platsen för vertexattributet till vilket vertexfältet matar data
storlek antalet komponenter som ska dras från attributet
typ C ++ -typen för attributdata i bufferten
normaliserad huruvida man ska kartlägga heltalstyper till flytpunktsområdet [0, 1] (för osignerad) eller [-1, 1] (för signerad)
pekare byteförskjutningen i bufferten till den första byten av attributets data (kastas till void* av äldre skäl)
offset basbyteförskjutningen från början av bufferten till där matrisdata startar
relativeOffset förskjutningen till ett visst attribut, relativt basförskjutningen för bufferten
kliva antalet byte från en toppunkt till nästa
buffert buffertobjektet där vertexmatriserna lagras
bindingIndex det index som källbuffertobjektet kommer att vara bundet till

Anmärkningar

Den separata attributformatet VAO-inställningen kan samverka med glVertexAttribPointer (det senare definieras i termer av det förra). Men du måste vara försiktig när du gör det.

Den separata attributformatversionen har ekvivalenter med direkttillstånd (DSA) i 4.5. Dessa kommer att ha samma parametrar men istället för att använda den bundna VAO, skickas VAO som modifieras uttryckligen. När du använder DSA de glDrawElements för glDrawElements kan ställas in med glVertexArrayElementBuffer(vao, ebo);

Version 3.0

Varje attribut är associerat med ett komponentantal, typ, normaliserat, offset, steg och VBO. VBO passeras inte uttryckligen som en parameter utan är istället bufferten bunden till GL_ARRAY_BUFFER vid samtalet.

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

4,3

OpenGL 4.3 (eller ARB_separate_attrib_format) lägger till ett alternativt sätt att specificera vertexdata, vilket skapar en åtskillnad mellan formatet för data som är bundet för ett attribut och buffertobjektkällan som tillhandahåller data. Så istället för att ha en VAO per nät, kan du ha ett VAO per vertexformat.

Varje attribut är associerat med ett toppunktformat och en bindningspunkt. Vertexformatet består av typen, komponenträkningen, oavsett om den är normaliserad, och den relativa förskjutningen från början av data till det specifika toppunktet. Bindningspunkten anger vilken buffert ett attribut tar sina data från. Genom att separera de två kan du binda buffertar utan att respektera några toppformat. Du kan också ändra bufferten som tillhandahåller data till flera attribut med ett enda bindande samtal.

//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);

Sedan under dragningen håller du vao bunden och ändrar bara buffertbindningarna.

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
    }
}


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow