0

我正在尝试学习如何处理 VBO(VertexBufferObjects),但我无法比 Vertex Arrays 更进一步。我遵循了一些关于这个主题的基本教程,每个教程都以不同的方式进行教学,这让我很难理解和实施。

问题:渲染glDrawArrays();应该与立即模式渲染相同。因此,我尝试通过songho.ca测试代码,但我得到的只是本机代码中的 JVM 崩溃。询问谷歌根本没有帮助,因为这种方法有几十种变体。但我认为我的参数是主要问题。

这是我到目前为止得到的:

我使用 LWJGL,所以我将数据存储在 FloatBuffer 中:

FloatBuffer buffer = BufferUtils.createFloatBuffer(triangles.size() * 3 * 3);

for(Triangle tri : triangles) {
    buffer.put((float) tri.getA().x);
    buffer.put((float) tri.getA().y);
    buffer.put((float) tri.getA().z);

    buffer.put((float) tri.getB().x);
    buffer.put((float) tri.getB().y);
    buffer.put((float) tri.getB().z);

    buffer.put((float) tri.getC().x);
    buffer.put((float) tri.getC().y);
    buffer.put((float) tri.getC().z);
}

我的三角形类由 3 个向量 ABC 组成,每个向量定义一个顶点。在第一行中,我为顶点分配空间,每个三角形 9 个浮点数(每个顶点 3 个浮点数,每个三角形 3 个顶点)。到目前为止没有什么异常,放入缓冲区的浮点数正好等于分配的大小。

立即模式渲染:

    glBegin(GL_TRIANGLES);
    for (Triangle tri : this.triangles) {
        glVertex3d(tri.getA().x, tri.getA().y, tri.getA().z);
        glVertex3d(tri.getB().x, tri.getB().y, tri.getB().z);
        glVertex3d(tri.getC().x, tri.getC().y, tri.getC().z);
    }
    glEnd();

也没什么特别的,到目前为止看到的一切对我来说都很好。但是 Array 变体让我头疼......

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, 0, buffer);

    glDrawArrays(GL_TRIANGLES, 0, buffer.capacity());

    glDisableClientState( GL_VERTEX_ARRAY );

崩溃的 JVM 产生的错误日志指向该glDrawArrays(GL_TRIANGLES, 0, buffer.capacity());行,但我找不到我的错误...

4

1 回答 1

2

您需要buffer.flip ()为一件事添加到代码中。

Java 中的缓冲区有一个内部当前位置,这是 LWJGL 在调用glVertexPointer (...). 每次调用时buffer.put (...),它都会增加缓冲区的大小,并将当前位置设置为缓冲区的末尾

调用flip (...)会将当前位置移动到缓冲区的开头。这样,当您尝试绘制capacity (...)从“当前”位置开始的许多顶点时,您将不会超出缓冲区。

此外,每个顶点都是由3 个浮点数构建的。这里的容量是根据浮点组件的数量来衡量的,因此存储在缓冲区中的顶点数实际上是它的容量除以3

于 2014-04-12T16:27:53.970 回答