[英]Why are my VBOs slower than display lists?
我創建了兩個簡單的體素引擎,實際上只是容納多維數據集的塊。 對於第一個,我使用顯示列表,並且可以以60 FPS渲染數百個塊,這沒問題,盡管事實上它背后的技術已經存在了很長時間,並且現在已經過時了。 在我的VBO版本中,我嘗試渲染27個塊,然后突然降至不到50 FPS。 是什么賦予了? 我將着色器用於VBO版本,但不用於顯示列表一。 如果沒有用於VBO版本的着色器,我仍然可以獲得相同的FPS速率。 我將發布一些相關代碼:
塊的初始化:
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();
循環(不是您一次聲明顏色並完成顏色設置)。 如評論中所述:
嘗試將位置和顏色數據插入單個緩沖區中。 這是對靜態數據的通常建議,因為它在渲染過程中提供了更好的內存訪問模式。 – GuyRT`
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.