2
$\begingroup$

If no, Should I create a new VAO for every VBO that has its own vertex attribute configurations?

Could you please give me a snippet code example that shows how to use one VAO for multiple VBOs? All examples I find on the internet call to glVertexAttribPointer before drawing a buffer, but if you have to call that method everytime you want to draw a buffer, then VAOs doesn't make sense.

PS: The tutorial I'm following uses Opengl 3.3

$\endgroup$

2 Answers 2

2
$\begingroup$

Yes, VAO state includes vertex attribute specification for multiple attributes. Each attribute has its own format information and can come from a distinct buffer object. That's part of why you can only bind one VAO at a time.

// two VBOs but one VAO
GLuint points_vbo = 0;
glGenBuffers(1, &points_vbo);
glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), points, GL_STATIC_DRAW);

GLuint colours_vbo = 0;
glGenBuffers(1, &colours_vbo);
glBindBuffer(GL_ARRAY_BUFFER, colours_vbo);
glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), colours, GL_STATIC_DRAW);

GLuint vao = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);


rendering-loop
{
    glBindVertexArray(vao);

    glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
    glBindBuffer(GL_ARRAY_BUFFER, colours_vbo);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);

    glDrawArrays(GL_TRIANGLES, 0, 3);
}

PS: you will need to be careful about the location of the vertex attribute. Those used in the rendering loop need to match those in the vertex shader.

$\endgroup$
2
  • $\begingroup$ Could you please give me a snippet code example that shows how to use one VAO for multiple VBOs? All examples I find on the internet call to glVertexAttribPointer before drawing a buffer, but if you have to call that method everytime you want to draw a buffer, then VAOs doesn't make sense. $\endgroup$
    – Adrian
    Jan 31, 2017 at 7:36
  • $\begingroup$ I added some code per OP's request. Hope it's ok. It will need to be approve by Nicol to show up $\endgroup$
    – user18490
    Jan 31, 2017 at 16:46
3
$\begingroup$

In version 4.3+ the vao layout can be set independently from the VBO buffer which allows you to rebind the vbo without having to call vertexAttribPointer every time:

//in init
glBindVertexArray(vao);

glVertexAttribFormat(posAttrLoc, 3, GL_FLOAT, false, offsetof(Vertex, pos));
// set the details of a single attribute
glVertexAttribBinding(posAttrLoc, 0);
// which buffer binding point it is attached to
glEnableVertexAttribArray(posAttrLoc);

glVertexAttribFormat(normalAttrLoc, 3, GL_FLOAT, false, offsetof(Vertex, normal));
glVertexAttribBinding(normalAttrLoc, 0);
glEnableVertexAttribArray(normalAttrLoc);

glVertexAttribFormat(texAttrLoc, 2, GL_FLOAT, false, offsetof(Texture, tex));
glVertexAttribBinding(texAttrLoc, 1);
glEnableVertexAttribArray(texAttrLoc);

Note that there is no mention of any VBO during init, just the binding points. That binding point is then used during draw to specify which vbo to pull the vertex data from:

//draw

glBindVertexArray(vao);
foreach(mesh in meshes){
    glBindVertexBuffer(0, mesh.vbo, mesh.vboOffset, sizeof(Vertex));
    glBindVertexBuffer(1, mesh.texVbo, mesh.texVboOffset, sizeof(Texture));
    // bind the buffer to the binding point
    glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount);
    //draw
}

In pre 4.3 you would create a VAO per mesh and per mesh call glVertexAttribPointer for each attribute:

glBindVertexArray(mesh.vao);
glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo);

glVertexAttribPointer (posAttrLoc, 3, GL_FLOAT, false, sizeof(Vertex), mesh.vboOffset + offsetof(Vertex, pos));
glEnableVertexAttribArray(posAttrLoc);
//...

Then during draw bind the per mesh vao before drawing it:

foreach(mesh in meshes){        
    glBindVertexArray(mesh.vao);
    glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount);
}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.