Reputation: 13
I have recently figured out how to render 3D cubes using LWJGL and OpenGL and I was so excited, I rendered 2000 and effectively froze my computer. I've heard of things such as Display Lists and VBO but even after googling, I have no idea how to use them.
Currently, I have
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.
}
Rendering my cubes. The call b.render
just renders a cube
@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);
}
Where cap is the top Texture and side is the side Texture.
What I really need help with is figuring out how to make my code VBO and/or Display List compatible in order to increase performance. I also think if it were possible to render only visible faces it would save many computations but can't think of how to do such a thing.
EDIT:
I now have each block creating its own VBO object via the following code...
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+"'.");
}
At the start of my program, I create 1000 block objects so my output is effectively "VBO create with a vboID of n", 1000 times.
I understand at the end of the program, I need to dispose of the VBOs (I'm presuming I just call GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0)
for each VBO?) but first, I need to draw each VBO.
What is the command to draw VBOs?
Upvotes: 1
Views: 2763
Reputation: 11
display list only store opengl primitive which means it only store glVertex/glTexCoord etc. And does not store any client functions like glEnableClientState/glDisableClientSate/glDrawArrays etc.
To setup display list here are the example code:
int var = glGenLists(1);
glNewList(var, GL_COMPILE);
// put your vertex/primitives here
glEndList();
glCallList(var) // execute/draw them
TIP: Don't put the glNewList/glEndList in a loop it will cause performance drop, only glCallList
Fun Fact: Display List can improve performance by about 5-10%.
However Display Lists is now deprecated/removed in earlier version of opengl so don't use that in modern OpenGL instead use VBO.
Upvotes: 0
Reputation: 162184
Please don't use Display Lists, they're outdated and deprecated. Using VBOs effectively requires using Vertex Arrays. When using a vertex array you put all the vertex positions and other attributes into arrays and then batch the drawing of a lot of triangles using a single call to glDrawArrays (assumes the arrays are just a long list of vertices to be processed one after another) or glDrawElements (takes an additional array, that contains a list of indices referring to the elements in the vertex arrays).
Here's a tutorial about vertex arrays:
http://www.songho.ca/opengl/gl_vertexarray.html
Once you got vertex arrays working, its only a small step to VBOs.
Upvotes: 1