簡體   English   中英

為什么我的VBO比顯示列表慢?

[英]Why are my VBOs slower than display lists?

我創建了兩個簡單的體素引擎,實際上只是容納多維數據集的塊。 對於第一個,我使用顯示列表,並且可以以60 FPS渲染數百個塊,這沒問題,盡管事實上它背后的技術已經存在了很長時間,並且現在已經過時了。 在我的VBO版本中,我嘗試渲染27個塊,然后突然降至不到50 FPS。 是什么賦予了? 我將着色器用於VBO版本,但不用於顯示列表一。 如果沒有用於VBO版本的着色器,我仍然可以獲得相同的FPS速率。 我將發布一些相關代碼:

VBO

塊的初始化:

public void initGL() {
    rand = new Random();

    sizeX = (int) pos.getX() + CHUNKSIZE;
    sizeY = (int) pos.getY() + CHUNKSIZE;
    sizeZ = (int) pos.getZ() + CHUNKSIZE;

    tiles = new byte[sizeX][sizeY][sizeZ];

    vCoords = BufferUtils.createFloatBuffer(CHUNKSIZE * CHUNKSIZE * CHUNKSIZE * (3 * 4 * 6));
    cCoords = BufferUtils.createFloatBuffer(CHUNKSIZE * CHUNKSIZE * CHUNKSIZE * (4 * 4 * 6));

    createChunk();

    verticeCount = CHUNKSIZE * CHUNKSIZE * CHUNKSIZE * (4 * 4 * 6);

    vCoords.flip();
    cCoords.flip();

    vID = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, vID);
    glBufferData(GL_ARRAY_BUFFER, vCoords, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    cID = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, cID);
    glBufferData(GL_ARRAY_BUFFER, cCoords, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}
private void createChunk() {
    for (int x = (int) pos.getX(); x < sizeX; x++) {
        for (int y = (int) pos.getY(); y < sizeY; y++) {
            for (int z = (int) pos.getZ(); z < sizeZ; z++) {
                if (rand.nextBoolean() == true) {
                    tiles[x][y][z] = Tile.Grass.getId();
                } else {
                    tiles[x][y][z] = Tile.Void.getId();
                }
                vCoords.put(Shape.createCubeVertices(x, y, z, 1));
                cCoords.put(Shape.getCubeColors(tiles[x][y][z]));
            }
        }
    }
}

然后渲染:

public void render() {
    glBindBuffer(GL_ARRAY_BUFFER, vID);
    glVertexPointer(3, GL_FLOAT, 0, 0L);

    glBindBuffer(GL_ARRAY_BUFFER, cID);
    glColorPointer(4, GL_FLOAT, 0, 0L);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);

    shader.use();
    glDrawArrays(GL_QUADS, 0, verticeCount);
    shader.release();

    glDisableClientState(GL_COLOR_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);
}

我知道我使用四邊形,這很糟糕,但是我也將四邊形用於顯示列表引擎。 着色器非常簡單,它們所要做的就是將一種顏色着色並將其應用到頂點,我什至不會發布它們那么簡單。

顯示清單

初始化:

public void init() {
    rand = new Random();

    opaqueID = glGenLists(1);

    tiles = new byte[(int) lPosition.x][(int) lPosition.y][(int) lPosition.z];

    genRandomWorld();
    rebuild();
}
public void rebuild() {
    glNewList(opaqueID, GL_COMPILE);
    glBegin(GL_QUADS);
    for (int x = (int) sPosition.x; x < (int) lPosition.x; x++) {
        for (int y = (int) sPosition.y; y < (int) lPosition.y; y++) {
            for (int z = (int) sPosition.z; z < (int) lPosition.z; z++) {
                if (checkCubeHidden(x, y, z)) {
                    // check if tiles hidden. if not, add vertices to
                    // display list
                    if (type != 0) {
                        Tile.getTile(tiles[x][y][z]).getVertices(x, y, z, 1, spritesheet.getTextureCoordsX(tiles[x][y][z]), spritesheet.getTextureCoordsY(tiles[x][y][z]));
                    } else {
                        Tile.getTile(tiles[x][y][z]).getVertices(x, y, z, 1);
                    }
                }
            }
        }
    }
    glEnd();
    glEndList();
    spritesheet.bind();
}

我應該注意,在顯示列表版本中,我僅添加可見的多維數據集。 因此,這可能是一個不公平的優勢,但它不應將VBO版本降低到只有27個塊(而顯示列表版本為500個)的FPS。 我這樣渲染:

public void render() {
    if (tiles.length != -1) {
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glCallList(opaqueID);
    }
}

因此,經過所有這些代碼之后,我真的仍然想知道為什么我的VBO版本太慢了嗎? 當我調用它們進行渲染時,我在顯示列表版本中確實有一個一維的塊列表,在我的VBO版本中確實有一個三維的塊,但是我認為JVM幾乎消除了額外尺寸的任何滯后。 那么,我在做什么錯呢?

沒有實際的項目和分析器很難回答這樣的問題,所以這些是理論:

  • 您沒有詳細顯示“顯示列表”生成代碼,因此我假設您正在做類似glColor(); glVertex3f(); glColor(); glVertex3f(); 循環(不是您一次聲明顏色並完成顏色設置)。
  • 顯示列表實現是特定於實現的,但通常是交錯的頂點屬性數組,因為它對緩存更友好(所有頂點屬性緊密對齊16個字節,而不是按數組大小散布)。 另一方面,您使用的VBO分為兩個非交織的塊-坐標和顏色。 這可能會導致過度使用不友好的緩存(尤其是大量數據)。

如評論中所述:

嘗試將位置和顏色數據插入單個緩沖區中。 這是對靜態數據的通常建議,因為它在渲染過程中提供了更好的內存訪問模式。 – GuyRT`

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM