glDrawElements中的索引参数是什么意思?

3

有两个OpenGL文档页面,它们对glDrawElements函数的“index”参数有略微不同的描述。在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. 

顺便说一下,我在使用OpenGL 4+的Windows系统。

所以我把索引数组复制到了我创建的元素缓冲对象中,我需要提供的indices指针参数是第一个索引的字节偏移量吗?那么如果我要从索引3开始绘制,这个参数会是2 * sizeof(GLuint),转换为指针吗?

我实际上费了一番力气来创建EBO,但看起来好像说如果没有绑定EBO,指针就直接指向索引所在的位置,而不是EBO。我对吗?这是否意味着它将指向系统RAM中的数组?(编辑:我刚才意识到这是不合理的,如果指针在0x00000008处,它不能去到系统内存中的那个地址)。如果是这样,它是否会每次复制索引数组到显卡上才能使用?谢谢。


1
索引:您的索引数组的基地址。您只需提供基地址即可。第三个参数指定每个索引的大小。通常设置为GL_UNSIGNED_INT。 - Asesh
@Asesh 谢谢,我想我明白了。但是它说如果一个元素缓冲对象没有绑定,索引指针直接指向索引数组存储的位置。这让我想到系统RAM,但这不合理,难道它不总是从GPU上的元素缓冲对象获取索引吗?所以困惑了。 - Zebrafish
1个回答

5
根据OpenGL 4.5核心规范,从客户端内存中读取是不支持的(§10.3.10 OpenGL 4.5 core spec):
DrawElements、DrawRangeElements和DrawElementsInstanced从名为ELEMENT_ARRAY_BUFFER的缓冲对象中获取它们的索引,并使用它们的indices参数作为偏移量进入缓冲对象,方式与第10.3.9节中描述的相同。如果将0绑定到ELEMENT_ARRAY_BUFFER,则这些绘图命令的结果未定义。
因此您创建EBO的方法是正确的。除非您的第0个索引位于偏移量0处,否则第3个索引位于偏移量3 * sizeof(type)处。
至于您的第二个引用:在旧版OpenGL版本中,您可以传递指向客户端内存的指针(在您的进程虚拟地址空间中而不是物理地址),并使ELEMENT_ARRAY_BUFFER未绑定。

@ybundaloBill 第一个索引位于偏移量0,第二个索引位于偏移量4,第三个索引位于偏移量8,对吧? - Zebrafish
如果你从1开始计数,那么是的。我建议你从0开始计数,这样会更少混淆:第n个索引在偏移量n*sizeof(type)处。请注意,type不一定是GLuint,你也可以使用8位或16位的索引。 - Yakov Galka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接