glDrawElementsBaseVertex如何工作?

时间:2018-02-02 13:32:02

标签: opengl graphics index-buffer

我有一个平面和一个索引缓冲区,或EBO,图像上标有索引:

enter image description here

现在,如果我打电话:

glDrawElementsBaseVertex(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0, 0);

我明白了:

enter image description here

我明白了。此外,如果我这样做:

glDrawElementsBaseVertex(GL_TRIANGLES, 9, GL_UNSIGNED_INT, 0, 0);

enter image description here

这也是有道理的。但是当我改变其中一个参数时,我的理解完全崩溃了。如果我这样做:

glDrawElementsBaseVertex(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0, 3);

看起来像这样:

enter image description here

因此,通过将参数3传递给basevertex参数(最后一个参数),它开始使用不是从3个位置到索引的索引,甚至从3个三角形到索引,但它&#39 ; s开始大约有6个三角形,或者更确切地说是索引编号18.我无法理解这种行为。

另外,我读过" indices"的论点的矛盾含义。在这些功能中:

void glDrawElements(GLenum mode,  GLsizei count,  GLenum type,  const GLvoid * indices);
void glDrawElementsBaseVertex(GLenum mode​, GLsizei count​, GLenum type​, GLvoid *indices​, GLint basevertex​);

我已经读过index指针使你可以通过提供指针直接引用索引缓冲区,如果它是null,则索引缓冲区取自当前绑定的GL_ELEMENT_ARRAY_BUFFER。但是从一个版本的文档中可以看出:

  

指数       指定绑定到GL_ELEMENT_ARRAY_BUFFER的缓冲区中的字节偏移量(强制转换为指针类型)以开始读取索引。

在另一个版本中它说:

  

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

如果我用第二个最后一个参数(索引)调用glDrawElementsBaseVertex作为(void *)3,我得到第一个绘制为红色的三角形。如果我指定(void *)6我没有突出显示三角形。如果我指定(void *)9,我会突出显示第二个三角形。

我无法理解这一点。那么这个参数index是不是指向你想要使用的索引的可选指针而不是使用当前绑定的元素数组缓冲区的情况呢?

3 个答案:

答案 0 :(得分:2)

如果要为索引设置偏移量,则可以像这样简单地使用glDrawElements:

glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, (void*)(sizeof(GLuint)*6));

它将绘制3个元素,索引的偏移量为6。

glDrawElements的最后一个参数可以是两个不同的东西:

  1. 如果您没有绑定到GL_ELEMENT_ARRAY_BUFFER的索引缓冲区,则它是指向存储索引位置的指针。
  2. 如果确实有绑定到GL_ELEMENT_ARRAY_BUFFER的索引缓冲区,则该数组的偏移量以字节为单位

答案 1 :(得分:0)

您还应该向我们展示如何对顶点进行编号。从屏幕截图看来,顶点是按行对齐的。在那种情况下,它可以正确地在第三个像元中渲染顶点,因为这是第三个顶点所在的地方。

如果要渲染单元2的前半部分,则应将基本顶点设置为1,因为那是顶点2所在的地方。

类似地,如果要渲染单元格2的后半部分,则应将基本指针设置为1,将索引指针设置为3。

答案 2 :(得分:0)

回复有点晚,但是我遇到了调用此GL函数的需要,而我也为它的行为而苦恼。

我敢打赌,您在第一张图片中包含的数字不是索引缓冲区中的实际索引值,而只是指示要指定顶点的ORDER。假设您的顶点缓冲区的组织方式如下:

enter image description here

我添加的红色数字是顶点缓冲区数组索引,您实际的索引缓冲区内容应以{0,1,6,1,7,6,...}开头。

因此,当 basevertex 等于零时,调用glDrawElementsBaseVertex()将执行以下操作:

当i = 0时,索引缓冲区中的元素零(其值为零)使顶点缓冲区中的元素零(上图中的红色数字)用作第一个三角形的第一个顶点。在i = 2的情况下,索引缓冲区中的元素2(值为6)使顶点缓冲区中的元素6完成第一个三角形。

引用glDrawElementsBaseVertex()的文档

相应绘制调用传输的第ith个元素将从每个已启用数组的元素索引[i] + basevertex中获取。

是的,这有点令人困惑,但这意味着从索引缓冲区中检索索引值后,将 basevertex 添加到其中。因此,当 basevertex 为3时,我们具有以下行为:

当i = 0时,从索引缓冲区中检索元素零。和以前一样,它的值为零,但现在又添加了三个。因此,顶点缓冲区中的元素3(同样,上图中的红色数字)用作第一个三角形的第一个顶点。在i = 2的情况下,将检索索引缓冲区中的元素2,该元素的值为6,但将其添加为三个,因此,将顶点缓冲区中的元素9用于完成第一个三角形。

希望这会有所帮助。