示例代码:
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”绑定它。绑定似乎有两个目的:
glBufferData
glVertexAttribPointer
我认为这是你需要绑定VBO的唯一两次。我的问题是,是否存在第2和第3行的目标(GL_ARRAY_BUFFER,GL_ELEMENT_ARRAY_BUFFER,GL_PIXEL_PACK_BUFFER或GL_PIXEL_UNPACK_BUFFER)不同的情况?或者我们想在第4行之前将它重新绑定到另一个目标?
我们可以将多个缓冲区目标绑定到单个VBO吗?
答案 0 :(得分:11)
您不会将目标绑定到缓冲区对象。目标是OpenGL上下文中的位置,您可以将事物(如缓冲区对象)绑定到。因此,您将缓冲区对象绑定到目标,而不是相反。
A buffer object(没有VBO这样的东西。只有缓冲区对象)只是OpenGL驱动程序拥有的无格式线性内存数组。您可以将缓冲区绑定到GL_ARRAY_BUFFER
并调用其中一个gl*Pointer
函数,将其用作顶点数组数据的源。这些函数仅与当前绑定到GL_ARRAY_BUFFER
的缓冲区一起使用。您可以将它们绑定到GL_ELEMENT_ARRAY_BUFFER
并调用其中一个glDrawElements
函数,将它们用作索引数据的来源。
用于修改缓冲区对象内容(glBufferData
,glMapBuffer
,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)
,并且它将更改 nothing ,以了解当您进行渲染时会发生什么。它会渲染得很好。
通过这种方式,您可以为不同的属性使用不同的缓冲区对象。该信息将保留,直到您通过对该特定属性的另一个glVertexAttribPointer
调用进行更改。