views:

37

answers:

2

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.

+3  A: 

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
tibur
+3  A: 

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).

Bahbar