使用glDrawElements时难以理解索引的含义

6
我正在尝试使用GL_TRIANGLE_STRIPglDrawElements绘制地形,但我很难理解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的正确方法。
以下是每个顶点的位置和x坐标的索引:
  • 0:三角形第一个顶点的x坐标的索引。位置:(-128, -128)。
  • 768:三角形第二个顶点的x坐标的索引。位置:(-128, -127)。
  • 3:三角形第三个顶点的x坐标的索引。位置:(-127, -128)。
  • 771:将绘制第二个三角形的第四个顶点的x坐标的索引。位置:(-127, -127)。
到目前为止,我认为一切都很清晰明了。
问题在于上面的位置值(我已经在vArray中进行了双重检查,并且它们是正确的)与glDrawElements使用的不同。两个三角形被绘制出来,但它们比应该的要大得多。它从(-128, -128)开始,但是它到达了(-125, -125),而不是(-127, -127)。
我无法理解我在这里做错了什么...

传递给 glDrawElements 的索引应与在调用 glVertex3fv(&vArray[index]) 时在 glBegin/glEnd 之间使用的索引相同。您确定问题不是在其他地方吗?您确定缓冲区是否被正确创建(大小/索引正确)? - Asher Dunn
我从未在glBegin/glEnd中使用过索引,所以我不知道,我直接将坐标传递给glVertex。我对任何事情都不确定,我只是开始学习VBO,并且缺乏示例。 - rfgamaral
你在问题中只提到了二维位置,但使用了三维顶点。这是有意为之吗? - pmr
@pmr:是的,他有一个三维空间中的二维网格顶点。 @Nazgulled:尝试使用我发布的带有glBegin/glEnd索引的语法,这将有助于确定问题是在缓冲设置还是索引计算中。 - Asher Dunn
1个回答

5
使用以下类似的内容可以解决我的问题:
unsigned int indices[] = { 0, 256, 1, 257 };

我认为可以假设索引是x坐标,OpenGL期望后面跟随y和z,但我们不应该自己增加3,服务器会为我们执行。
现在我想起来了,glDrawElements上有“element”这个词,在这种情况下,它是一个具有3个坐标的顶点,如glVertexPointer中所指定的那样,我们需要将索引传递给“element”,而不是“vertex”。
我感到很愚蠢...

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