user1650305
user1650305

Reputation:

VBO performance and chunks

First off, my code is in no way optimized. I'm also using old glTranslatf() and all that because I don't know the new way of doing things. Here's my code:

public class GenChunk {

Chunk c;
VBO vbo = new VBO();

int worldSize = 16;
int var4 = 16; // x
int var5 = 16; // z
int var6 = 16; // y

int xOffSet = 0;
int zOffSet = 0;

public GenChunk() {
    gen();
}

public void gen() {
    for (int x = xOffSet; x < worldSize; x++) {
        for (int z = zOffSet; z < worldSize; z++) {
            for (int y = 0; y < worldSize; y++) {
                glPushMatrix();
                glTranslatef(x, z, y);
                newChunk();
                glPopMatrix();
                xOffSet += 16;
                zOffSet += 16;
            }
        }
    }
}

private void newChunk() {

    vbo = new VBO();

    glBindBuffer(GL_ARRAY_BUFFER, vbo.vboVHandle);
    glVertexPointer(3, GL_FLOAT, 0, 0L);

    glBindBuffer(GL_ARRAY_BUFFER, vbo.vboCHandle);
    glColorPointer(3, GL_FLOAT, 0, 0);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    for (int y = 0; y < var6; y++) {
        for (int x = 0; x < var5; x++) {
            for (int z = 0; z < var6; z++) {
                glPushMatrix();
                glTranslatef(x, z, y);
                glDrawArrays(GL_QUADS, 0, 24);
                glPopMatrix();
            }
        }

    }
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
}

}

And the VBO class:

public class VBO {

public int vboVHandle;

public int vboCHandle;

public float size = 0.5f;
public float color = 0.5f;

public FloatBuffer vertices;
public FloatBuffer colorData;

public VBO(){

colorData = BufferUtils.createFloatBuffer(3 * 4 * 6);
colorData.put(new float[]{
        -color, color, color,
        color, color, color,
        -color, color, color,
        color, color, color,

        -color, color, color,
        color, color, color,
        -color, color, color,
        color, color, color,

        -color, color, color,
        color, color, color,
        -color, color, color,
        color, color, color,

        -color, color, color,
        color, color, color,
        -color, color, color,
        color, color, color,

        -color, color, color,
        color, color, color,
        -color, color, color,
        color, color, color,

        -color, color, color,
        color, color, color,
        -color, color, color,
        -color, color, color
});
colorData.flip();

vertices = BufferUtils.createFloatBuffer(3 * 4 * 6);
vertices.put(new float[] {
        -size, -size, size,
        size, -size, size,
        size, size, size,
        -size, size, size,

        -size, -size, -size,
        -size, size, -size,
        size, size, -size,
        size, -size, -size,

        -size, size, -size,
        -size, size, size,
        size, size, size,
        size, size, -size,

        -size, -size, -size,
        size, -size, -size,
        size, -size, size,
        -size, -size, size,

        size, -size, -size,
        size, size, -size,
        size, size, size,
        size, -size, size,

        -size, -size, -size,
        -size, -size, size,
        -size, size, size,
        -size, size, -size});
vertices.flip();

vboVHandle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboVHandle);
glBufferData(GL_ARRAY_BUFFER, vertices, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);


vboCHandle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboCHandle);
glBufferData(GL_ARRAY_BUFFER, colorData, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

}

} I render out two chunks, so approximately 8000 cubes. I've heard of people rendering out 10,000 cubes and still maintaining 60 FPS, yet when I render two chunks, I get 1 FPS. My hardware is not the problem, its decent. I know I need to optimize my code like crazy, but I'm worried that even with optimizations, it'll still be slow! Can anyone tell me what I'm doing wrong here?

Upvotes: 4

Views: 835

Answers (1)

genpfault
genpfault

Reputation: 52084

Using a VBO with a single cube in it and glTranslate()ing it around will not help your performance at all.

A VBO for a given chunk should contain multiple cubes (at 163, up to 2048 for the worst-case checkerboard volume). You should only issue glTranslate()s at the chunk level, not per-cube.

EDIT:

You have your volume database, generally stored in a 3D array of some sort. Each element of the array is a class/struct (or even just an int or char!) that holds your block type information (grass, dirt, rock, etc.) and other state. You also need a function like bool IsOpaque( const BlockType& block) that can tell you if the given block is graphically opaque or not.

Iterate over all the blocks in a given chunk. If a block IsOpaque() check its six neighbors (±X, ±Y, ±Z). If a neighbor !IsOpaque() generate the vertexes for two triangles (or one quad) for that side of a cube (translated appropriately (not via glTranslatef()!) depending on the position in the chunk) and append them to a buffer.

When you're done iterating over the chunk upload the buffer of vertexes to a VBO.

Or you can get fancier.

Upvotes: 8

Related Questions