每个BindBuffer后需要VertexAttribPointer吗?

j r*_*riv 10 opengl opengl-3

我注意到除非我重新调用VertexAttribPointer,否则在BindBuffer之后没有输入到着色器.这有必要吗?着色器可能不会以书面形式更改,而只会使用缓冲区.

Bah*_*bar 24

tibur已经回答了实际的问题,但我想我会添加一些上下文.

glBindBuffer(GL_ARRAY_BUFFER, ...)本身什么都不.把它想象成一个额外的论据glVertexAttribPointer.

请记住,您可以将多个缓冲区绑定到不同的属性(例如,attrib 0使用vbo 1,而attrib 1和2使用vbo 2).您会看到该设置的API顺序是什么?

使用实际的API,它是这样的:

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

glDraw*(...)
Run Code Online (Sandbox Code Playgroud)

为什么规范会这样运作?好吧,它的向后兼容性正在抬头.当VBOs被引入时,glVertexPointer等等.没有任何参数来传递要使用的缓冲区对象.要么每个语义都有许多新的入口点(VertexPointer/NormalPointer/TexCoordPointer ...),要么它本身就是一个额外的入口点,它只是作为*指针调用的额外参数.他们选择后者(作为旁注,这也是为什么你必须在缓冲区内传递一个偏移量作为指针).


tib*_*bur 13

根据OpenGL OpenGL规范,第51页(缓冲区对象状态),对应于数组指针的状态存储缓冲区ID.这意味着如果要更改缓冲区对象以进行绘制,则需要调用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
Run Code Online (Sandbox Code Playgroud)