user1887053
user1887053

Reputation: 13

Display Lists and VBO OpenGL/LWJGL

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

Answers (2)

rentheprogrammer
rentheprogrammer

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

datenwolf
datenwolf

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

Related Questions