使用 glDrawElements 很难理解索引

发布于 2024-11-03 10:16:14 字数 2749 浏览 7 评论 0原文

我正在尝试使用 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 中使用索引的正确方法。

  • 0:从三角形第一个顶点开始的 x 坐标索引。位置:(-128,-128)。
  • 768:从三角形第二个顶点开始的 x 坐标索引。位置:(-128, -127)
  • 3:从三角形第三个顶点开始的 x 坐标索引。位置:(-127, -128)
  • 771:从第四个顶点开始的 x 坐标索引,这将绘制第二个三角形。地点:(-127,-127)。

我认为到目前为止一切都有意义?

不起作用的是上面的位置值(我在 vArray 上进行了双重检查,它们是正确的)与 glDrawElements 使用的不同。绘制了两个三角形,但它们比应有的大得多。它从 (-128, -128) 正确开始,但它会转到 (-125, -125) 而不是 (-127, -127)。

我不明白我在这里做错了什么......

I'm trying to draw a terrain with GL_TRIANGLE_STRIP and glDrawElements but I'm having a really hard time understanding the indices thing behind glDrawElements...

Here's what I have so far:

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);
}

I believe my vArray is correct, I use the same values when drawing with glBegin(GL_TRIANGLE_STRIP)/glEnd which works just fine.

My guess was to use just the index of the x coordinate for each vertex. But I have no idea if that's the right way to use indices with glDrawElements.

  • 0: Index of the x coordinate from the first vertex of the triangle. Location: (-128, -128).
  • 768: Index of the x coordinate from the second vertex of the triangle. Location: (-128, -127)
  • 3: Index of the x coordinate from the third vertex of the triangle. Location: (-127, -128)
  • 771: Index of the x coordinate from the fourth vertex, which will draw a second triangle. Location: (-127, -127).

I think everything is making sense so far?

What's not working is that the location values above (which I doubled checked on vArray and they are correct) are not the same which glDrawElements is using. Two triangles are drawn but they are a lot bigger than what they should be. It starts correctly at (-128, -128) but it goes to something like (-125, -125) instead of (-127, -127).

I can't understand what I'm doing wrong here...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

燕归巢 2024-11-10 10:16:14

使用类似下面的内容可以解决我的问题:

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

我认为可以安全地假设索引是 x 坐标,并且 OpenGL 期望后面跟着 y 和 z,但我们不应该自己增加 3,服务器会这样做我们。

现在我想了一下,glDrawElements 上有单词 element,在本例中是一个具有 3 个坐标的顶点,如 glVertexPointer 中指定的那样> 我们需要将索引传递给元素,而不是顶点

我现在感觉自己好傻……

Using something like the following solves my problem:

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

I think it's safe to assume that the index is the x coordinate and that OpenGL is expecting that to be followed by y and z but we shouldn't increase by 3 ourselves, the server does it for us.

And now that I think about it, glDrawElements has the word element on it, which in this case is a vertex with 3 coordinates as specified in glVertexPointer and we need to pass the indices to the element, not the vertex.

I feel so dumb now...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文