glDrawElements中的第四个论点是WHAT

The 4th argument in glDrawElements is WHAT?

本文关键字:四个 WHAT glDrawElements      更新时间:2023-10-16

我对glDrawElements()感到困惑。我在学习一个教程,里面说glDrawElements()的第四个参数是"GL_ELEMENT_ARRAY_BUFFER内的偏移"。但我有一个错误"访问voilation:尝试读取0x0000",如果我通过0作为偏移量。

因此,我深入研究了这个问题,发现OpenGL文档对第四个参数提供了两种不同的定义:

第一:

indexes:将字节偏移量(强制转换为指针类型)指定到绑定到GL_ELEMENT_ARRAY_buffer的缓冲区​开始读取索引从…起

(可在此找到:https://www.opengl.org/wiki/GLAPI/glDrawElements)

第二:

indexes:指定指向存储索引的位置的指针。

(可在此找到:https://www.opengl.org/sdk/docs/man4/index.php以及此处:http://www.khronos.org/opengles/sdk/docs/man/xhtml/glDrawElements.xml)

哪一个是真的?如何正确使用它?

编辑:这是我的代码:http://pastebin.com/fdxTMjnC

两者都是正确的。这两种情况涉及如何将索引缓冲区上传到GL硬件以及如何使用它进行绘制。这些描述如下:

(1) 不使用VBO(顶点缓冲区对象):

在这种情况下,参数指示指向索引数组的指针。每次调用glDrawElements时,缓冲区都会上传到GL HW。

(2) 使用VBO:

对于这种情况,请参阅Index的定义,即"将字节偏移量(强制转换为指针类型)指定到绑定到GL_ELEMENT_ARRAY_buffer的缓冲区​开始从"读取索引。这意味着数据已经使用glBufferData单独上传,并且索引仅用作偏移。每次调用glDrawElements时,缓冲区都不会上传,但只有偏移量可以在需要时更改。这使其更高效,尤其是在涉及大量顶点的情况下。

如果使用直接绘图,则

索引​定义索引缓冲区对象的偏移量(绑定到GL_ELEMENT_ARRAY_buffer​,存储在VAO中)以开始读取数据。

这意味着,您需要创建VAO,绑定到它,然后使用glDrawElements()来渲染

该参数的解释取决于内部数组是否已绑定到GL状态机中。如果这样的数组被绑定,那么它就是一个偏移。如果没有绑定这样的数组,那么它就是指向内存的指针。

使用内部数组更具性能,因此最近的文档(尤其是wiki)强烈倾向于这种用法。然而,还有很长的歌曲和舞蹈来安排他们。

绑定或取消绑定内部数组的函数是glBindVertexArray。检查这些相关功能的文档:

  • glGenVertexArrays
  • glBufferData

(这是一个不完整的列表。我必须运行,所以我以后必须编辑。)

opengl.org/wiki上的内容最有可能是正确的。我可以从工作项目中告诉你,它确实定义如下:

Specifies a byte offset (cast to a pointer type) into the buffer bound to
GL_ELEMENT_ARRAY_BUFFER​ to start reading indices from.

只需将一些整数强制转换为GLvoid*,就可以开始了。至少对于现代可编程管道来说,我不知道固定管道(也不应该使用它!)。

如果您使用的是现代流水线,在没有进一步信息的情况下,我敢打赌实际的函数没有正确加载。这是因为GLEW没有正确初始化,或者如果你正在手动尝试在win32上使用GetProcAddress(因为glDrawElements自1.1以来就是核心,1.0/1.1不应该在win32中使用GetProcAddress加载)。

确实要注意,您应该像其他人所说的那样,将元素缓冲区绑定到绑定点。尽管在实践中,你可以在不绑定VAO的情况下逃脱惩罚。我在NVidia、AMD甚至英特尔上都做过这件事。但在生产中,你应该使用VAO。