使用 GL_ARRAY_BUFFER 创建索引缓冲区和使用 GL_ELEMENT_ARRAY_BUFFER 创建索引缓冲区在 OpenGL 中有什么区别吗?

Is there any difference in OpenGL between creating Index Buffers with GL_ARRAY_BUFFER and creating them with GL_ELEMENT_ARRAY_BUFFER?

我研究 OpenGL 有一段时间了,现在,在做一个项目时,我发现,当我创建索引缓冲区时,如果我将它绑定到 GL_ARRAY_BUFFER 而不是GL_ELEMENT_ARRAY_BUFFER 有(显然)相同的结果。

我的意思是,顶点缓冲区总是绑定到 GL_ARRAY_BUFFER,但是如果我创建这样的索引缓冲区:

glCreateBuffers(1, &m_BufferID);
glBindBuffer(GL_ARRAY_BUFFER, m_BufferID);
glBufferData(GL_ARRAY_BUFFER, count * sizeof(uint), vertices, GL_STATIC_DRAW);

然后,例如在绘制几何图形时,我将其绑定到 GL_ELEMENT_ARRAY_BUFFER,工作正常,但我不知道为什么我认为必须使用 [=14= 创建索引缓冲区] 也是,但是……其实有什么“内在”的区别吗?

是的。 ARRAY_BUFFER 绑定是全局状态,而 ELEMENT_ARRAY_BUFFER 绑定在顶点数组对象中说明。参见 Index buffers
因此,glBindBuffer(GL_ELEMENT_ARRAY_BUFFER m_BufferID) 更改当前绑定的顶点数组对象中的状态。

请注意,与 index buffer (ELEMENT_ARRAY_BUFFER), the vertex buffer 绑定 (ARRAY_BUFFER) 相比,它是一个全局状态。
VAOs 状态向量中声明的每个属性可能引用不同的 ARRAY_BUFFER。在调用 glVertexAttribPointer 时存储此引用。然后将当前绑定到目标ARRAY_BUFFER的缓冲区关联到指定的属性索引,并将对象的名称(值)存储在当前绑定的VAO的状态向量中。
然而,索引缓冲区是 VAO 的一种状态。如果缓冲区绑定到目标 ELEMENT_ARRAY_BUFFER,则此缓冲区分配给当前绑定的顶点数组对象。

就缓冲区对象本身的性质而言?不。所有缓冲区对象都是相同的,并且可以用于适合缓冲区对象的任何任务。缓冲区对象不具有最初用于绑定的特殊属性。

但是,GL_ELEMENT_ARRAY_BUFFER 绑定点本身有点不寻常。它不是全局上下文状态的一部分;它是 VAO 州的一部分。因此,如果您没有绑定 VAO(在核心配置文件上下文下),那么您无法将任何内容绑定到该绑定点。当您绑定到该绑定点时,您正在影响当前绑定的 VAO 的状态。如果您更改当前绑定的 VAO,您将更改哪个缓冲区绑定到元素数组绑定点。

所以一般来说,如果您打算要做的是将缓冲区附加到当前绑定的 VAO,那么您应该只绑定到那个点。