【问题标题】:VBO performance and chunksVBO 性能和块
【发布时间】:2013-02-08 23:14:02
【问题描述】:

首先,我的代码没有经过优化。我也在使用旧的 glTranslatf() 和所有这些,因为我不知道新的做事方式。这是我的代码:

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);
}

}

还有 VBO 类:

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);

}

} 我渲染出两个块,大约 8000 个立方体。我听说有人渲染 10,000 个立方体并仍然保持 60 FPS,但是当我渲染两个块时,我得到 1 FPS。我的硬件不是问题,它还不错。我知道我需要疯狂地优化我的代码,但我担心即使进行了优化,它仍然会很慢!谁能告诉我我在这里做错了什么?

【问题讨论】:

  • 尝试使用GL_STATIC_DRAW
  • 不,没用。仍然在 1 fps 左右。
  • 再看一遍你的代码,你有 3 个嵌套循环调用另外 3 个嵌套循环来渲染 24 个四边形。每个循环经过 16 次,因此您实际上渲染了 1600 万个四边形,而 10000 个立方体只有 60000 个四边形(或 120000 个三角形)。
  • 这里有个秘密:Minecraft 不渲染立方体。它只是看起来和它一样。
  • 嗯,有道理。但是,我不知道如何翻译我的块和立方体!我怎么翻译它们?

标签: java opengl lwjgl vbo


【解决方案1】:

使用带有 单个 立方体的 VBO 并 glTranslate()ing 它不会对您的性能有所帮助

给定块的 VBO 应包含多个立方体(在 163 处,最坏情况下棋盘体积最大为 2048)。你应该只在块级别发出glTranslate()s,而不是每个立方体。

编辑:

您有卷数据库,通常存储在某种 3D 数组中。数组的每个元素都是一个类/结构(或者甚至只是一个intchar!),其中包含您的块类型信息(草、泥土、岩石等)和其他状态。你还需要一个像bool IsOpaque( const BlockType&amp; block) 这样的函数,它可以告诉你给定的块是否在图形上不透明。

遍历给定块中的所有块。如果一个块IsOpaque() 检查它的六个邻居(±X、±Y、±Z)。如果邻居!IsOpaque() 为立方体的那一侧生成两个三角形(或一个四边形)的顶点(根据块中的位置适当地翻译(不是通过glTranslatef()!))和将它们附加到缓冲区。

完成对块的迭代后,将顶点缓冲区上传到 VBO。

或者你可以得到fancier

【讨论】:

  • 我认为这可能与此有关。那么我将如何在我的 VBO 中放置多个立方体?每个人都告诉我我现在这样做的方式很好..
  • 不要吝啬@opiop65,但如果你的表现很差,你所做的就不好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-15
  • 1970-01-01
相关资源
最近更新 更多