我最近弄明白了如何使用LWJGL和OpenGL渲染3D立方体,我很兴奋,我渲染了2000个,有效地冻结了我的电脑。我听说过Display Lists和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是顶部Texture,side是侧面Texture。
我真正需要帮助的是如何使我的代码与VBO和显示列表兼容,以提高性能。我也认为如果可以只渲染可见的面孔,会节省很多计算量,但想不出如何做到这一点。
EDIT:
我现在通过下面的代码让每个区块创建自己的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个块对象,所以我的输出实际上是 "VBO create with a vboID of n",1000次。
我知道在程序结束时,我需要处理这些VBO(我假定我只需要调用 GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0)
但首先,我需要绘制每个VBO。
绘制VBO的命令是什么?
请不要使用Display Lists,它们已经过时和废弃了。有效地使用VBO需要使用顶点数组。当使用顶点数组时,你把所有的顶点位置和其他属性放入数组中,然后通过调用glDrawArrays(假设数组只是一个长长的顶点列表,需要一个接一个地处理)或glDrawElements(需要一个额外的数组,其中包含一个指向顶点数组中元素的索引列表)来批量绘制大量的三角形。
这里有一个关于顶点数组的教程。
http:/www.songho.caopenglgl_vertexarray.html
一旦你把顶点数组弄好了,就只差一小步就可以到VBOs了。