我注意到在绑定缓冲区后,除非重新调用VertexAttribPointer,否则着色器中没有输入。这是必须的吗?着色器代码可能不会改变,只会使用不同的缓冲区。
tibur已经回答了实际问题,但我想补充一些背景。
glBindBuffer(GL_ARRAY_BUFFER, ...)
本身并没有做任何事情。将其视为glVertexAttribPointer
的额外参数。
请记住,您可以将多个缓冲区绑定到不同的属性(例如属性0使用vbo 1,而属性1和2使用vbo 2)。 对于这种设置,您会看到什么API顺序?
使用实际的API,类似于:
glBindBuffer(GL_ARRAY_BUFFER, 1);
glVertexAttribPointer(0, ...)
glBindBuffer(GL_ARRAY_BUFFER, 2);
glVertexAttribPointer(1, ...)
glVertexAttribPointer(2, ...)
glDraw*(...)
规范为什么会这样工作呢?嗯,这是向后兼容性出现的问题。当VBO被引入时,glVertexPointer
等函数没有任何参数可以传递要使用哪个缓冲区对象。要么就是为每个语义(VertexPointer/NormalPointer/TexCoordPointer等)添加许多新的入口点,要么就是添加一个额外的入口点,它只是作为*Pointer调用的一个额外参数。他们选择了后者(顺便说一句,这也是为什么您必须将缓冲区内的偏移量作为指针传递的原因)。
glVertexAttribPointer
函数。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