glBindVertexBuffer (...)
函数的目标完全不同。
当它在GL_ARB_vertex_attrib_binding
中引入时,其想法是分离始终存在的顶点缓冲区与指针之间的固定映射,并用更灵活的系统替换它,该系统允许您为顶点属性设置格式,为顶点缓冲区/属性设置绑定位置,然后只需交换绑定到该位置的缓冲区即可。
您不能仅使用此新功能替换对glBindBuffer (...)
的调用,您至少需要调用两个其他函数来设置通用顶点属性以利用glBindVertexBuffer (...)
:
glVertexAttribFormat (...)
- 这与glVertexAttribPointer (...)
实际上相同,只是它不设置指针,而是仅建立将与此属性配对的缓冲区如何被解释。
glVertexAttribBinding (...)
- 这将通用属性位置与新类型的绑定位置(顶点缓冲区绑定)关联起来,以便您可以使用glBindVertexBuffer (...)
将您的VBO绑定到此属性将使用的位置。
glVertexBindingDivisor (...)
- 这是glVertexAttribDivisor()
的替代品。此替换品尊重由glVertexAttribBinding(...)
制定的顶点属性索引与绑定槽索引之间的绑定关系。这值得指出,因为它的名称与上面列出的其他两个函数有些不符,而旧的glVertexAttribDivisor()
则更加一致,但不能使用。
为了让您了解情况,我在扩展规范中包含了一些伪代码,显示了glVertexAttribPointer (...)
如何与此新API添加相关。
命令:
void glVertexAttribPointer (GLuint index, GLint size, GLenum type,
GLboolean normalized, GLsizei stride,
const GLvoid *pointer);
void glVertexAttribIPointer (GLuint index, GLint size, GLenum type,
GLsizei stride, const GLvoid *pointer);
void glVertexAttribLPointer (GLuint index, GLint size, GLenum type,
GLsizei stride, const GLvoid *pointer);
控制顶点属性状态、顶点缓冲区绑定以及顶点属性与顶点缓冲区绑定之间的映射。
假设没有生成错误,则它们是等效的:
if (no buffer is bound to GL_ARRAY_BUFFER and pointer != NULL)
{
generate GL_INVALID_OPERATION;
}
glVertexAttrib*Format (index, size, type, {normalized, }, 0);
glVertexAttribBinding (index, index);
if (stride != 0) {
effectiveStride = stride;
} else {
compute effectiveStride based on size/type;
}
GL_VERTEX_ATTRIB_ARRAY_STRIDE[index] = stride;
glBindVertexBuffer (index, <buffer bound to GL_ARRAY_BUFFER>,
(GLchar *)pointer - (GLchar *)NULL, effectiveStride);
一开始可能有点难以理解,但其实它的核心思想与当 Sampler Objects 在 GL 3.3 中被引入时将采样状态从纹理对象中分离出来非常相似。你仍然可以继续使用旧的 API,但这种替代方案会为您提供更多的灵活性。
关于元素数组缓冲区,不是的。这个新的 API 部分与此无关,因为顶点数组对象实际上管理唯一的元素数组缓冲区绑定。