简体   繁体   中英

Is it necessary to bind all VBOs (and textures) each frame?

I'm following basic tutorial on OpenGL 3.0 . What is not clear to me why/if I have to bind, enable and unbind/disable all vertex buffers and textures each frame.

To me it seems too much gl**** calls which I guess have some overhead. For example here you see each frame several blocks like:

// do this for each mesh in scene
// vertexes
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glVertexAttribPointer(  0, 3, GL_FLOAT,GL_FALSE,0,(void*)0);
// normals
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, normal_buffer );
glVertexAttribPointer(  1, 3, GL_FLOAT,GL_FALSE,0,(void*)0);
// UVs
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, uv_buffer    );
glVertexAttribPointer(  2, 2, GL_FLOAT,GL_FALSE,0,(void*)0);

// ...
glDrawArrays(GL_TRIANGLES, 0, nVerts );
// ...
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);

imagine you have not just one but 100 different meshes each with it's own VBOs for vertexes,normas,UVs. Should I really do this procedure each frame for each of them? Sure I can encapsulate that complexity into some function/objects, but I worry about overheads of this gl**** function calls.

Is it not possible some part of this machinery to move from per frame loop into scene setup ?

Also I read that VAO is a way how to pack corresponding VBOs for one object together. And that binding VAO automatically binds corresponding VBOs. So I was thinking that maybe one VAO for each mesh (not instance) is how it should be done - but according to this answer it does not seems so?

You should use vertex array object (generated by glGenVertexArrays ). Thanks to it you don't have to perform those calls everytime. Vertex buffer object stores:

  • Calls to glEnableVertexAttribArray or glDisableVertexAttribArray .
  • Vertex attribute configurations via glVertexAttribPointer .
  • Vertex buffer objects associated with vertex attributes by calls to glVertexAttribPointer .

Maybe this will be better tutorial.

So that you can generate vao object, then bind it, perform the calls and unbind. Now in drawing loop you just have to bind vao.

Example:

  glUseProgram(shaderId);
  glBindVertexArray(vaoId);
  glDrawArrays(GL_TRIANGLES, 0, 3);
  glBindVertexArray(0);
  glUseProgram(0);

First things first: Your concerns about GL call overhead have been addressed with the introduction of Vertex Array Objects (see @Criss answer). However the real problem with your train of thought is, that you equate VBOs with geometry meshes, ie give each geometry its own VBO.

That's not how you should see and use VBOs. VBOs are chunks of memory and you can put the data of several objects into a single VBO; you don't have to draw the whole thing, you can limit draw calls to subsets of a VBO. And you can coalesce geometries with similar or even identical drawing setup and draw them all at once with a single draw call. Either by having the right vertex index list, or by use of instancing.

When it comes to the binding state of textures… well, yeah, that's a bit more annoying. You really have to do the whole binding dance when switching textures. That's why in general you sort geometry by texture/shader before drawing, so that the amount of texture switches is minimized.

The last 3 or 4 generations of GPUs (as of late 2016) do support bindless textures though, where you can access textures through a 64 bit handle (effectively the address of the relevant data structure in some address space) in the shader. However bindless textures did not yet make it into the core OpenGL standard and you have to use vendor extensions to make use of it.

Another interesting approach (popularized by Id Tech 4) is virtual textures. You can allocate sparsely populated texture objects that are huge in their addressable size, but only part of them actually populated with data. During program execution you determine which areas of the texture are required and swap in the required data on demand.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM