显示列表和VBO OpenGL / LWJGL

时间:2013-02-12 08:53:43

标签: java opengl lwjgl vbo

我最近想出了如何使用LWJGL和OpenGL渲染3D立方体,我非常兴奋,我渲染了2000并有效地冻结了我的计算机。我听说过显示列表和VBO之类的东西,但即使在谷歌搜索之后,我也不知道如何使用它们。

目前,我有

for (Block b : blocks) {
    GL11.glTranslatef(b.position.x, b.position.y, b.position.z); // Translate to draw the cube.
    GL11.glBegin(GL_QUADS); // Start to draw the quad.
    b.render(); // Renders the quad.
    GL11.glEnd(); // Finishes rendering.
}

渲染我的立方体。调用b.render只是呈现一个多维数据集

@Override
public void render() {
    //front face
    GL11.glNormal3f(0f, 0f, 1f);
    GL11.glTexCoord2f(0f, 1f);
    GL11.glVertex3f(1f, 0f, 0f);
    GL11.glTexCoord2f(1f, 1f);
    GL11.glVertex3f(0f, 0f, 0f);
    GL11.glTexCoord2f(1f, 0f);
    GL11.glVertex3f(0f, 1f, 0f);
    GL11.glTexCoord2f(0f, 0f);
    GL11.glVertex3f(1f, 1f, 0f);

    //back face
    GL11.glNormal3f(0f, 0f, -1f);
    GL11.glTexCoord2f(0f, 1f);
    GL11.glVertex3f(0f, 0f, 1f);
    GL11.glTexCoord2f(1f, 1f);
    GL11.glVertex3f(1f, 0f, 1f);
    GL11.glTexCoord2f(1f, 0f);
    GL11.glVertex3f(1f, 1f, 1f);
    GL11.glTexCoord2f(0f, 0f);
    GL11.glVertex3f(0f, 1f, 1f);

    cap.bind(); // top texture
    //top face
    GL11.glNormal3f(0f, -1f, 0f);
    GL11.glTexCoord2f(0f, 1f);
    GL11.glVertex3f(1f, 1f, 0f);
    GL11.glTexCoord2f(1f, 1f);
    GL11.glVertex3f(0f, 1f, 0f);
    GL11.glTexCoord2f(1f, 0f);
    GL11.glVertex3f(0f, 1f, 1f);
    GL11.glTexCoord2f(0f, 0f);
    GL11.glVertex3f(1f, 1f, 1f);

    //bottom face
    GL11.glNormal3f(0f, 1f, 0f);
    GL11.glTexCoord2f(0f, 1f);
    GL11.glVertex3f(1f, 0f, 1f);
    GL11.glTexCoord2f(1f, 1f);
    GL11.glVertex3f(0f, 0f, 1f);
    GL11.glTexCoord2f(1f, 0f);
    GL11.glVertex3f(0f, 0f, 0f);
    GL11.glTexCoord2f(0f, 0f);
    GL11.glVertex3f(1f, 0f, 0f);

    side.bind(); // left texture
    //left face
    GL11.glNormal3f(-1f, 0f, 0f);
    GL11.glTexCoord2f(0f, 1f);
    GL11.glVertex3f(1f, 0f, 1f);
    GL11.glTexCoord2f(1f, 1f);
    GL11.glVertex3f(1f, 0f, 0f);
    GL11.glTexCoord2f(1f, 0f);
    GL11.glVertex3f(1f, 1f, 0f);
    GL11.glTexCoord2f(0f, 0f);
    GL11.glVertex3f(1f, 1f, 1f);

    //right face
    GL11.glNormal3f(1f, 0f, 0f);
    GL11.glTexCoord2f(0f, 1f);
    GL11.glVertex3f(0f, 0f, 0f);
    GL11.glTexCoord2f(1f, 1f);
    GL11.glVertex3f(0f, 0f, 1f);
    GL11.glTexCoord2f(1f, 0f);
    GL11.glVertex3f(0f, 1f, 1f);
    GL11.glTexCoord2f(0f, 0f);
    GL11.glVertex3f(0f, 1f, 0f);
}

其中cap是顶部纹理,side是侧面纹理。

我真正需要帮助的是弄清楚如何使我的代码VBO和/或显示列表兼容以提高性能。我也认为如果只能渲染可见的面部,它会节省许多计算但却无法想到如何做这样的事情。

编辑:

我现在让每个块通过以下代码创建自己的VBO对象......

private int vboID;
private FloatBuffer vertices;
private float[] verts = {0, 1, 2, 2, 3, 0, 0, 3, 4, 4, 5, 0, 0, 5, 6, 6, 1, 0, 1, 6, 7, 7, 2, 1, 7, 4, 3, 3, 2, 7, 4, 7, 6, 6, 5, 4}; // Not sure on the numbers for making a cube?

private void generateVBO() {
    vertices = BufferUtils.createFloatBuffer(verts.length); // Create a FloatBuffer...
    vertices.put(verts); // Add all the vertices in...
    vboID = GL15.glGenBuffers(); // Generate the VBO...
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID); // Bind it...
    GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertices, GL15.GL_STATIC_DRAW); // Buffer in the data...
    verts = null; // Free up memory allocation because these are unnecessary now...
    vertices = null;
    System.out.println("VBO created with a vboID of '"+vboID+"'.");
}

在我的程序开始时,我创建了1000个块对象,因此我的输出实际上是“使用vboID为n的VBO创建”,1000次。

我理解在程序结束时,我需要处理VBO(我假设我只是为每个VBO调用GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,0)?)但首先,我需要绘制每个VBO VBO。

绘制VBO的命令是什么?

谢谢!

1 个答案:

答案 0 :(得分:1)

请不要使用显示列表,它们已过时且已弃用。有效地使用VBO需要使用Vertex Arrays。当使用顶点数组时,您将所有顶点位置和其他属性放入数组中,然后使用对glDrawArrays的单个调用批量绘制许多三角形(假设数组只是一个接一个地处理的长顶点列表)或glDrawElements(接受一个额外的数组,其中包含引用顶点数组中元素的索引列表。)

这是关于顶点数组的教程:

http://www.songho.ca/opengl/gl_vertexarray.html

一旦你有顶点数组工作,它只是VBO的一小步。