【问题标题】: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 创建索引缓冲区之间有什么区别吗?
【发布时间】:2020-11-11 16:37:04
【问题描述】:

我一直在研究 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,效果很好,但我不知道为什么我认为索引缓冲区也必须使用 GL_ELEMENT_ARRAY_BUFFER 创建,但是.. . 实际上有什么“内在”的不同吗?

【问题讨论】:

  • 如果您使用的是glCreateBuffers,那么您使用的是DSA,所以您不应该调用glBindBuffer永远
  • GL_ARRAY_BUFFER for index 可能在某些机器上工作,而在其他机器上不起作用......至少在过去的 ATI 卡和后来的 AMD 中,如果不使用 GL_ELEMENT_ARRAY_BUFFER 和/或数据类型,则在某些情况下会抛出异常不是特定类型,或者索引数量超过某个阈值(IIRC 大约 37 或 57 KByte)

标签: opengl graphics opengl-3 opengl-4


【解决方案1】:

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

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

所以一般来说,只有当您打算将缓冲区附加到当前绑定的 VAO 时,您才应该绑定到该点。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-01
      • 1970-01-01
      • 2011-04-19
      • 2016-03-05
      相关资源
      最近更新 更多