6

示例代码:

1. glGenBuffers(1, &VboId);
2. glBindBuffer(GL_ARRAY_BUFFER, VboId);
3. glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
4. glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);

所以我们生成一个通用的 VBO 句柄,然后我们使用“GL_ARRAY_BUFFER”绑定它。绑定它似乎有两个目的:

  1. 我们必须先绑定缓冲区,然后才能通过以下方式将数据复制到 GPUglBufferData
  2. 我们必须先绑定缓冲区,然后才能通过glVertexAttribPointer

而且我认为这是您需要绑定 VBO 的唯一 2 次。我的问题是,是否存在目标(GL_ARRAY_BUFFER、GL_ELEMENT_ARRAY_BUFFER、GL_PIXEL_PACK_BUFFER 或 GL_PIXEL_UNPACK_BUFFER)在第 2 行和第 3 行不同的情况?或者我们想在第 4 行之前将它重新绑定到不同的目标?

我们可以将多个缓冲区目标绑定到单个 VBO 吗?

4

1 回答 1

11

您不将目标绑定到缓冲区对象。目标是 OpenGL 上下文中可以绑定事物(如缓冲区对象)的位置。因此,您将缓冲区对象绑定目标,而不是相反。

缓冲区对象(没有像 VBO 这样的东西。只有缓冲区对象)只是 OpenGL 驱动程序拥有的未格式化的线性内存数组。GL_ARRAY_BUFFER通过将缓冲区绑定到并调用其中一个gl*Pointer函数,您可以将其用作顶点数组数据的源。这些函数适用于当前绑定到的缓冲区GL_ARRAY_BUFFERGL_ELEMENT_ARRAY_BUFFER通过将它们绑定到并调用其中一个glDrawElements函数,您可以将它们用作索引数据的源。

用于修改缓冲区对象内容(、、、等)的函数glBufferDataglMapBuffer专门glBufferSubData为其操作指定了一个目标。glBufferData(GL_ARRAY_BUFFER, ...)对于当前绑定到的任何缓冲区,它的内容也是如此GL_ARRAY_BUFFER

所以有两种函数会影响缓冲区对象:修改其内容的函数,以及在操作中使用它们的函数。后者是特定于来源的;glVertexAttribPointer 总是使用当前绑定到的缓冲区GL_ARRAY_BUFFER。你不能让它使用不同的目标。同样,glReadPixels始终使用绑定到 的缓冲区GL_PIXEL_PACK_BUFFER。等等。如果一个函数处理缓冲区对象但不将目标作为参数,那么它的文档会告诉你它从哪个目标中寻找它的缓冲区。

注意:顶点数组有点奇怪。顶点属性和缓冲区对象之间的关联是通过调用glVertexAttribPointer. 该函数所做的是使用当前绑定到 GL_ARRAY_BUFFER 的缓冲区对象为该属性设置适当的数据。“当前绑定”是指在调用此函数时绑定。所以在调用这个函数之后,你可以立即调用glBindBuffer(GL_ARRAY_BUFFER, 0),它不会改变你去渲染时发生的事情它会渲染得很好。

这样,您可以为不同的属性使用不同的缓冲区对象。该信息将被保留,直到您再次glVertexAttribPointer调用该特定属性来更改它。

于 2012-01-01T03:32:55.643 回答