glDrawElements中的index参数是啥意思?

Posted

技术标签:

【中文标题】glDrawElements中的index参数是啥意思?【英文标题】:What is the meaning of the index argument in glDrawElements?glDrawElements中的index参数是什么意思? 【发布时间】:2016-11-27 08:03:00 【问题描述】:

有两个 OpenGL 文档页面对 glDrawElements 函数的“索引”参数的描述略有不同。在 www.opengl.org/sdk/docs/man4/ 上它说:

indices
    Specifies a pointer to the location where the indices are stored. 

在 www.khronos.org/opengles/sdk/docs/man3 上它说:

indices
    Specifies a byte offset (cast to a pointer type) into the buffer bound 
    to GL_ELEMENT_ARRAY_BUFFER to start reading indices from. If no buffer
    is bound, specifies a pointer to the location where the indices are stored. 

顺便说一句,我在 Windows 上,使用 OpenGL 4+。

所以我已经将我的索引数组复制到我创建的元素缓冲区对象中,我需要提供的索引指针参数是第一个索引的字节偏移量吗?因此,如果我想从索引 3 开始绘制,参数将是 2 * sizeof(GLuint),转换为指针?

我实际上为此努力创建了一个 EBO,但从它的外观来看,如果没有绑定 EBO,则指针直接指向索引所在的位置,而不是 EBO。我是对的,这意味着它将指向系统 RAM 上的阵列吗? (编辑:我刚刚意识到这没有意义,如果指针位于 0x00000008 它不能转到系统内存中的那个地址。)如果是这样,它是否每次都将索引数组复制到显卡为了能够使用它?谢谢。

【问题讨论】:

indices:索引数组的基地址。您应该只提供基地址。第三个参数指定每个索引的大小。它通常设置为 GL_UNSIGNED_INT @Asesh 谢谢,我想我明白了。但它表示如果元素缓冲区对象未绑定,则索引指针直接指向存储索引数组的位置。这让我觉得系统 RAM,但这没有意义,它不是总是从 GPU 上的元素缓冲区对象获取索引吗?好困惑。 【参考方案1】:

根据 OpenGL 4.5 核心配置文件,不支持从客户端内存读取(第 10.3.10 节 OpenGL 4.5 核心规范):

DrawElementsDrawRangeElementsDrawElementsInstanced 从名称绑定到的缓冲区对象中获取索引 ELEMENT_ARRAY_BUFFER,使用它们的 indices 参数作为缓冲区对象的偏移量,其方式与第 10.3.9 节中描述的方式相同。 [...] 如果零绑定到ELEMENT_ARRAY_BUFFER,则这些绘图命令的结果是未定义的。

因此,您创建 EBO 的方法是正确的。除非您的第 0 个索引位于偏移量零,否则第 3 个索引位于偏移量 3*sizeof(type)

至于您的第二个引用:在较旧的 OpenGL 版本中,您可以将指针传递给客户端内存(在您的进程虚拟地址空间中,而不是物理地址中)并保持 ELEMENT_ARRAY_BUFFER 未绑定。

【讨论】:

@ybundaloBill 第一个索引在偏移量 0,第二个索引在偏移量 4,第三个索引在偏移量 8,不是吗? 如果你从一开始数,那么是的。我建议你从零开始计数,这样就不会那么混乱了:偏移量n*sizeof(type) 处的第n 个索引。注意type 不需要是GLuint,你也可以使用 8 位或 16 位索引。

以上是关于glDrawElements中的index参数是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

使用 glDrawElements、Index Buffer 和启用的 GL_CULL_FACE 横向绘制圆柱体

使用 LWJGL 在 glDrawElements 中偏移

glDrawElements中的OpenGL SegFault

glDrawElements 抛出 GL_INVALID_VALUE 错误

OpenGL - glDrawElements vs 顶点数组对象

index函数的使用方法是啥?