0

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

在此处输入图像描述

现在,如果我打电话:

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

我明白了:

在此处输入图像描述

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

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

在此处输入图像描述

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

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

它看起来像这样:

在此处输入图像描述

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

此外,我已经阅读了这些函数中“索引”参数的矛盾含义:

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

我读过索引指针使您可以通过提供指针直接引用索引缓冲区,如果它为空,则索引缓冲区取自当前绑定的 GL_ELEMENT_ARRAY_BUFFER。然而,从一个版本的文档中它说:

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

在另一个版本中它说:

indices 指定一个指向索引存储位置的指针。

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

我无法理解这一切。那么这个参数,indices,是不是一个可选的指针,指向你希望使用的索引,而不是使用当前绑定的元素数组缓冲区?

4

3 回答 3

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 的索引缓冲区,则它是该数组的字节偏移量。
于 2020-05-24T23:03:29.213 回答
0

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

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

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

于 2019-09-29T12:10:08.440 回答
0

回复有点晚了,但我只是遇到了调用这个 GL 函数的需要,我也为它的行为而苦苦挣扎。

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

在此处输入图像描述

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

因此,当 basevertex为零时,调用 glDrawElementsBaseVertex() 会执行以下操作:

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

引用glDrawElementsBaseVertex()的文档

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

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

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

希望这可以帮助。

于 2020-05-15T04:41:19.310 回答