opengl - glBindVertexBuffer 与 glBindBuffer

标签 opengl

我发现我可以使用glBindBuffer(GL_ARRAY_BUFFER, vbo);绑定(bind)顶点缓冲区。这可行,我还可以使用 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); 绑定(bind)元素数组。当使用这些时,一切都会根据需要绘制。

在阅读第 10.3.1 节中的 OpenGL 4.4 规范时,我发现提到了 glBindVertexBuffer。看起来这允许绑定(bind)多个顶点缓冲区,然后同时渲染它们。它是否正确?另外,它与使用 glBindBuffer 有什么不同?与此绑定(bind)顶点缓冲区时可以使用元素数组缓冲区吗?

最佳答案

实际上,glBindVertexBuffer (...)的意义完全不同。

GL_ARB_vertex_attrib_binding中引入时的想法的目的是分离顶点缓冲区和指针之间始终存在的固定映射,并将其替换为更灵活的系统,该系统允许您为顶点属性设置格式绑定(bind)位置 em> 要使用的顶点缓冲区/属性,然后简单地交换绑定(bind)到该位置的缓冲区。

您不会简单地用这个新函数替换对 glBindBuffer (...) 的调用,您至少还需要调用两个其他函数来设置通用顶点属性,以便能够利用glBindVertexBuffer (...):

  1. glVertexAttribFormat (...) - 这实际上与 glVertexAttribPointer (...) 相同,只是它不设置指针,而只是确定如何解释与此属性配对的缓冲区。

  2. glVertexAttribBinding (...) - 这将通用属性位置与类型的绑定(bind)位置(顶点缓冲区)相关联绑定(bind)),以便您可以使用 glBindVertexBuffer (...) 将您的 VBO 绑定(bind)到该属性将使用的位置。

  3. glVertexBindingDivisor (...) - 这是 glVertexAttribDivisor() 的替代品。此替换尊重由 glVertexAttribBinding(...) 建立的顶点属性索引和绑定(bind)槽索引之间的绑定(bind)关联。这是值得指出的,因为它的名称与上面列出的其他两个函数有些不符,而旧的 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);

控制顶点属性状态、顶点缓冲区绑定(bind)以及顶点属性与顶点缓冲区绑定(bind)之间的映射。

它们相当于(假设没有生成错误):

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;
// GL_VERTEX_BINDING_STRIDE will be set to effectiveStride
// by glBindVertexBuffer.
glBindVertexBuffer (index, <buffer bound to GL_ARRAY_BUFFER>, 
                 (GLchar *)pointer - (GLchar *)NULL, effectiveStride);
<小时/>

一开始有点难以理解,但归根结底,这与 GL 3.3 中引入采样器对象时采样器状态与纹理对象的分离非常相似。您可以继续使用旧的 API,但这个替代解决方案为您提供了更大的灵 active 。

关于元素数组缓冲区,没有。 API 的这一新部分与此无关,因为顶点数组对象实际上管理唯一的元素数组缓冲区绑定(bind)。

关于opengl - glBindVertexBuffer 与 glBindBuffer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21153729/

相关文章:

c++ - qt,使用freeglut,错误 'glutInit'

opengl - glsl 像素着色器 - 到最近目标像素的距离

OpenGL 压缩纹理和扩展

opengl - Xamarin Android 播放器 : OpenGL server is unreachable

c++ - 在 OpenGL 中的一个输入纹理上使用多个sampler2D

c++ - dll注入(inject): drawing simple game overlay with opengl

opengl - 水平和垂直限制 FOV

opengl - GL_QUERY_BY_REGION_WAIT 和 GL_QUERY_WAIT 有什么区别

opengl - 从窗口转换的深度分量 -> 世界坐标

qt - QQuickFramebufferObject 在 QML 中的 Y 轴上翻转