Трудно понять индексы с glDrawElements - PullRequest
6 голосов
/ 25 апреля 2011

Я пытаюсь нарисовать ландшафт с 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.

  • 0: Индекс координаты x от первой вершины треугольника. Расположение: (-128, -128).
  • 768: Индекс координаты x от второй вершины треугольника. Расположение: (-128, -127)
  • 3: Индекс координаты x из третьей вершины треугольника. Расположение: (-127, -128)
  • 771: Индекс координаты x от четвертой вершины, которая нарисует второй треугольник. Расположение: (-127, -127).

Я думаю, что все имеет смысл до сих пор?

Что не работает, так это то, что указанные выше значения местоположения (которые я дважды проверил на vArray и они правильные) не совпадают с тем, что использует glDrawElements. Два треугольника нарисованы, но они намного больше, чем должны быть. Правильно начинается с (-128, -128), но вместо (-127, -127) идет что-то вроде (-125, -125).

Я не могу понять, что я делаю здесь не так ...

1 Ответ

5 голосов
/ 26 апреля 2011

Использование чего-то вроде следующего решает мою проблему:

unsigned int indices[] = { 0, 256, 1, 257 };

Я думаю, можно с уверенностью предположить, что индекс - это координата x, и что OpenGL ожидает, что за ним последуют y и z, но мы не должны увеличиваться на 3 сами, сервер делает это за нас.

И теперь, когда я думаю об этом, glDrawElements содержит слово element , которое в данном случае является вершиной с 3 координатами, указанными в glVertexPointer, и нам нужно передать индексы к элементу , а не к вершине .

Теперь я чувствую себя так глупо ...

...