我正在尝试学习如何处理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个矢量A B C组成,每个矢量定义一个顶点。在第一行中,我为顶点分配空间,每个三角形有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());
行,但我找不到我的错误......
答案 0 :(得分:2)
您需要在代码中添加buffer.flip ()
。
Java中的缓冲区具有内部当前位置,这是LWJGL在您调用glVertexPointer (...)
时用于标记数据开头的位置。每次拨打buffer.put (...)
时,都会增加缓冲区的大小,并将当前位置设置为缓冲区的 end 。
调用flip (...)
会将当前位置移至缓冲区的 开头 。这样,当您尝试绘制capacity (...)
时,不会超出缓冲区 - 许多顶点从"当前"开始。位置。
此外,每个顶点都是由 3 浮点数构建的。此处的容量是根据浮点组件的数量来衡量的,因此缓冲区中存储的顶点数实际上是其容量除以 3 。