Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

glBindVertexBuffer vs glBindBuffer

Tags:

opengl

I see that I can bind a vertex buffer using glBindBuffer(GL_ARRAY_BUFFER, vbo);. This works, and I can also bind an element array using glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);. When using these everything draws as desired.

In reading the OpenGL 4.4 specification in section 10.3.1 I find mention of glBindVertexBuffer. It looks like this permits binding multiple vertex buffers and then having them all rendered at once. Is this correct? Also, how does it differ from using glBindBuffer? Can you use an element array buffer when binding vertex buffers with this?

like image 983
Graznarak Avatar asked Jan 16 '14 05:01

Graznarak


People also ask

What is a Vertexarray?

A Vertex Array Object (or VAO) is an object that describes how the vertex attributes are stored in a Vertex Buffer Object (or VBO). This means that the VAO is not the actual object storing the vertex data, but the descriptor of the vertex data.

What is a vertex attribute?

A vertex attribute is an input variable to a shader that is supplied with per-vertex data. In OpenGL core profile, they are specified as in variables in a vertex shader and are backed by a GL_ARRAY_BUFFER . These variable can contain, for example, positions, normals or texture coordinates.

What is an index in OpenGL?

Indices is defined as a GLubyte array of 48 elements; GLubyte is the OpenGL data type for an unsigned byte ( unsigned char ). You could use any of the following unsigned integral OpenGL data types: GLubyte , GLushort , and GLuint , since indices are never negative (signed) or fractional (float/double).


1 Answers

Actually, the point of glBindVertexBuffer (...) is entirely different.

The idea when it was introduced in GL_ARB_vertex_attrib_binding was to separate the fixed mapping that has always existed between vertex buffer and pointer and replace it with a more flexible system that allows you to setup a format for a vertex attribute, a binding location for the vertex buffer/attribute to use and then simply swap out the buffer bound to that location.

You will not simply be replacing a call to glBindBuffer (...) with this new function, you have at least two other functions you need to call to setup a generic vertex attribute to be able to take advantage of glBindVertexBuffer (...):

  1. glVertexAttribFormat (...)

    • This is effectively the same thing as glVertexAttribPointer (...) except it does not setup a pointer, it merely establishes how the buffer that will be paired with this attribute is to be interpreted.

  2. glVertexAttribBinding (...)

    • This associates the generic attribute location with a new type of binding location (vertex buffer binding) so that you can use glBindVertexBuffer (...) to bind your VBO to a location this attribute will use.

To put this into perspective, I have included some pseudo-code from the extension specification that shows how glVertexAttribPointer (...) works in relation to this new API addition.

The commands:

     void glVertexAttribPointer (GLuint index, GLint size, GLenum type,
                                 GLboolean normalized, GLsizei stride, 
                                 const GLvoid *pointer);
     void glVertexAttribIPointer (GLuint index, GLint size, GLenum type,
                                  GLsizei stride, const GLvoid *pointer);
     void glVertexAttribLPointer (GLuint index, GLint size, GLenum type,
                                  GLsizei stride, const GLvoid *pointer);

Control vertex attribute state, a vertex buffer binding, and the mapping between a vertex attribute and a vertex buffer binding.

They are equivalent to (assuming no errors are generated):

     if (no buffer is bound to GL_ARRAY_BUFFER and pointer != NULL) {
       generate GL_INVALID_OPERATION;
     }
     glVertexAttrib*Format (index, size, type, {normalized, }, 0);
     glVertexAttribBinding (index, index);
     if (stride != 0) {
       effectiveStride = stride;
     } else {
       compute effectiveStride based on size/type;
     }
     GL_VERTEX_ATTRIB_ARRAY_STRIDE[index] = stride;
     // GL_VERTEX_BINDING_STRIDE will be set to effectiveStride
     // by glBindVertexBuffer.
     glBindVertexBuffer (index, <buffer bound to GL_ARRAY_BUFFER>, 
                         (GLchar *)pointer - (GLchar *)NULL, effectiveStride);

It is a little difficult to wrap your head around at first, but what it boils down to is very similar to the separation of sampler state from Texture Objects when Sampler Objects were introduced in GL 3.3. You can continue using the old API, but this alternative solution gives you some more flexibility.

Regarding element array buffers, no. This new part of the API has nothing to do with that, because Vertex Array Objects actually manage the one-and-only element array buffer binding.

like image 169
Andon M. Coleman Avatar answered Sep 29 '22 18:09

Andon M. Coleman