使用 glDrawElements 很难理解索引
Posted
技术标签:
【中文标题】使用 glDrawElements 很难理解索引【英文标题】:Hard time understanding indices with glDrawElements 【发布时间】:2011-08-12 01:00:03 【问题描述】:我正在尝试使用GL_TRIANGLE_STRIP
和glDrawElements
绘制地形,但我很难理解glDrawElements
背后的索引...
这是我目前所拥有的:
void Terrain::GenerateVertexBufferObjects(float ox, float oy, float oz)
float startWidth, startLength, *vArray;
int vCount, vIndex = -1;
// width = length = 256
startWidth = (width / 2.0f) - width;
startLength = (length / 2.0f) - length;
vCount = 3 * width * length;
vArray = new float[vCount];
for(int z = 0; z < length; z++)
// vIndex == vIndex + width * 3 || width * 3 = 256 * 3 = 768
for(int x = 0; x < width; x++)
vArray[++vIndex] = ox + startWidth + (x * stepWidth);
vArray[++vIndex] = oy + heights[z][x];
vArray[++vIndex] = oz + startLength + (z * stepLength);
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vCount, vArray, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
void Terrain::DrawVBO(unsigned int texID, float ox, float oy, float oz)
float terrainLight[] = 1.0f, 1.0f, 1.0f, 1.0f ;
if(!generatedVBOs)
GenerateVertexBufferObjects(ox, oy, oz);
generatedVBOs = true;
unsigned int indices[] = 0, 768, 3, 771 ;
glGenBuffers(1, &indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * 4, indices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexPointer(3, GL_FLOAT, 0, 0);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, terrainLight);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
我相信我的vArray
是正确的,我在使用glBegin(GL_TRIANGLE_STRIP)/glEnd
绘图时使用相同的值,效果很好。
我的猜测是只是为每个顶点使用x
坐标的索引。但我不知道这是否是在glDrawElements
中使用索引的正确方法。
我认为到目前为止一切都说得通?
不起作用的是上面的位置值(我在vArray
上加倍检查并且它们是正确的)与glDrawElements
使用的位置值不同。绘制了两个三角形,但它们比应有的大得多。它正确地从 (-128, -128) 开始,但它会变成 (-125, -125) 而不是 (-127, -127)。
我不明白我在这里做错了什么......
【问题讨论】:
如果您调用 glVertex3fv(&vArray[index]),传递给 glDrawElements 的索引应该与您在 glBegin/glEnd 之间使用的索引相同。你确定问题不在其他地方吗?您确定缓冲区创建正确(大小/索引正确)? 我从不使用glBegin/glEnd
的索引,所以我不知道,我将坐标直接传递给glVertex
。我什么都不确定,我才刚开始学习 VBO,例子很少。
您在问题中只提到了二维位置,但使用了 3 维顶点。这是故意的吗?
@pmr:是的,他在 3D 空间中有一个 2D 顶点网格。 @Nazgulled:尝试类似我发布的使用 glBegin/glEnd 索引的语法。这将有助于确定问题出在缓冲区设置还是索引计算中。
【参考方案1】:
使用类似下面的方法可以解决我的问题:
unsigned int indices[] = 0, 256, 1, 257 ;
我认为可以安全地假设索引是 x 坐标并且 OpenGL 期望它后面跟着 y 和 z 但我们自己不应该增加 3,服务器会为我们做这件事。
现在我想起来了,glDrawElements
上面有单词 element,在这种情况下,它是一个具有 3 个坐标的顶点,如 glVertexPointer
中指定的那样,我们需要传递元素的索引,而不是顶点。
我现在感觉很笨......
【讨论】:
以上是关于使用 glDrawElements 很难理解索引的主要内容,如果未能解决你的问题,请参考以下文章
使用 glDrawElements 从 WRL (VRML) 文件中绘制对象
OpenGL - 使用 glDrawElements 错误地映射纹理
glDrawElements中的OpenGL SegFault