Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is VertexAttribPointer needed after each BindBuffer?

I noticed that unless I re-call VertexAttribPointer, there's not input to shaders after a BindBuffer. Is that necessary? The shaders may not change in writing but only the buffers used.

like image 581
j riv Avatar asked Sep 08 '10 07:09

j riv


People also ask

When should I call Enablevertexattribarray?

If you're not using VAOs, then you would usually call glVertexAttribPointer (and the corresponding glEnableVertexAttribArray ) right before rendering to setup the state properly.

What kind of data is stored in a VAO?

A Vertex Array Object (VAO) is an OpenGL Object that stores all of the state needed to supply vertex data (with one minor exception noted below). It stores the format of the vertex data as well as the Buffer Objects (see below) providing the vertex data arrays.

What do vertex array objects store?

A Vertex Array Object (VAO) is an object which contains one or more Vertex Buffer Objects and is designed to store the information for a complete rendered object. In our example this is a diamond consisting of four vertices as well as a color for each vertex.

What are vertex attributes in OpenGL?

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.


2 Answers

tibur already answered to the actual question, but I thought I'd add some context.

glBindBuffer(GL_ARRAY_BUFFER, ...) by itself does not do anything. Think of it as an extra argument to glVertexAttribPointer.

Remember, you can bind multiple buffers to different attributes (say attrib 0 uses vbo 1, while attrib 1 and 2 use vbo 2). What API order would you see for that setup ?

With the actual API, it's something like:

glBindBuffer(GL_ARRAY_BUFFER, 1);
glVertexAttribPointer(0, ...)
glBindBuffer(GL_ARRAY_BUFFER, 2);
glVertexAttribPointer(1, ...)
glVertexAttribPointer(2, ...)

glDraw*(...)

Why would the specification work that way ? Well, it's backwards compatibility rearing its head. When VBOs were introduced, glVertexPointer et al. did not have any parameter to pass which buffer object to use. Either it was many new entrypoints for each semantic (VertexPointer/NormalPointer/TexCoordPointer...), or it was an extra entrypoint by itself, which just was acting as an extra parameter to the *Pointer calls. They chose the latter (as a side note, this is also why you have to pass an offset inside the buffer as a pointer).

like image 134
Bahbar Avatar answered Sep 26 '22 07:09

Bahbar


According to OpenGL OpenGL specifications, page 51 (Buffer Object State), the state corresponding to the array pointers stores the buffer ID. That means that if you want to change the buffer object to draw with, you need to recall glVertexAttribPointer function.

glBindBuffer(1);
glVertexPointer(...);
glDrawArrays(...); /// Drawing will use buffer 1

glBindBuffer(2);
glDrawArrays(...); /// Drawing will still use buffer 1

glVertexPointer(...);
glDrawArrays(...); /// Drawing will now use buffer 2
like image 44
tibur Avatar answered Sep 25 '22 07:09

tibur