首先,我的代码没有优化。我也使用旧的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。我的硬件不是问题,它的体面。我知道我需要像疯了一样优化我的代码,但我担心即使有优化,它仍然会很慢!谁能告诉我这里我做错了什么?
答案 0 :(得分:7)
在其中使用带有单个多维数据集的VBO并glTranslate()
它将无法帮助您实现 。
给定块的VBO应该包含多个立方体(16 3 ,最坏情况下棋盘体积最多2048)。您应该只在块级别发出glTranslate()
,而不是每个多维数据集。
修改强>
您拥有卷数据库,通常存储在某种3D数组中。数组的每个元素都是一个类/结构(甚至只是int
或char
!),它保存您的块类型信息(草,泥土,岩石等)和其他状态。您还需要一个像bool IsOpaque( const BlockType& block)
这样的函数来告诉您给定的块是否是图形不透明的。
迭代给定块中的所有块。如果块IsOpaque()
检查其六个邻居(±X,±Y,±Z)。如果邻居!IsOpaque()
为多维数据集的那一侧生成两个三角形(或一个四边形)的顶点(适当地翻译(不通过glTranslatef()
!),具体取决于位置块)并将它们附加到缓冲区。
当您完成对块的迭代时,将顶点的缓冲区上传到VBO。
或者你可以获得fancier。