I am attempting to use vertex arrays to render about 2097152 cubes with LWJGL (no not all of them at once). I have implemented numerous types of polygon culling to enhance my performance from around 2 FPS to about 60 FPS. Throughout this project, I have been working with Immediate Mode rendering, and I think it is time for an upgrade. And here is where vertex arrays come in.
I don't want to use VBOs so I have been experimenting with VAOs for now. I cannot seem to get a practical (or efficient) rendering method down. Everything I try gives me worse FPS than Immediate Mode, sadly to say. Every frame I load up a FloatBuffer for every cube that has visible polygons then draw them using the common vertex array methods. This setup gives me headaches because I get less FPS than while using Immediate Mode and not culling any polygons.
I think I am doing something wrong. So among all you bright, aspiring OpenGL/LWJGL programmers out there, does anyone know how this can be done in a more effective and efficient way?
Here is my code for render (truncated to not be too much of a mess):
for(int z = 0; z < chunk.bpc; z++) {
for(int y = 0; y < chunk.bpc; y++) {
for(int x = 0; x < chunk.bpc; x++) {
if(((z == chunk.bpc - 1 || z == 0) || (y == chunk.bpc - 1 || y == 0) || (x == chunk.bpc - 1 || x == 0))
&& chunk.data[(x * chunk.bpc + z) * chunk.bpc + y] == i) {
List<Float> vertices = new ArrayList<Float>();
float xp = x + locX, yp = y + locY, zp = z + locZ;
if(z == chunk.bpc - 1 && chunk.z$ == null) {
vertices.add(xp); vertices.add(yp); vertices.add(zp + size);
vertices.add(xp + size); vertices.add(yp); vertices.add(zp + size);
vertices.add(xp + size); vertices.add(yp + size); vertices.add(zp + size);
vertices.add(xp); vertices.add(yp + size); vertices.add(zp + size);
}
if(z == 0 && chunk.z_ == null) {
vertices.add(xp); vertices.add(yp); vertices.add(zp);
vertices.add(xp); vertices.add(yp + size); vertices.add(zp);
vertices.add(xp + size); vertices.add(yp + size); vertices.add(zp);
vertices.add(xp + size); vertices.add(yp); vertices.add(zp);
}
if(y == chunk.bpc - 1 && chunk.y$ == null) {
vertices.add(xp); vertices.add(yp + size); vertices.add(zp);
vertices.add(xp); vertices.add(yp + size); vertices.add(zp + size);
vertices.add(xp + size); vertices.add(yp + size); vertices.add(zp + size);
vertices.add(xp + size); vertices.add(yp + size); vertices.add(zp);
}
if(y == 0 && chunk.y_ == null) {
vertices.add(xp); vertices.add(yp); vertices.add(zp);
vertices.add(xp + size); vertices.add(yp); vertices.add(zp);
vertices.add(xp + size); vertices.add(yp); vertices.add(zp + size);
vertices.add(xp); vertices.add(yp); vertices.add(zp + size);
}
if(x == chunk.bpc - 1 && chunk.x$ == null) {
vertices.add(xp + size); vertices.add(yp); vertices.add(zp);
vertices.add(xp + size); vertices.add(yp + size); vertices.add(zp);
vertices.add(xp + size); vertices.add(yp + size); vertices.add(zp + size);
vertices.add(xp + size); vertices.add(yp); vertices.add(zp + size);
}
if(x == 0 && chunk.x_ == null) {
vertices.add(xp); vertices.add(yp); vertices.add(zp);
vertices.add(xp); vertices.add(yp); vertices.add(zp + size);
vertices.add(xp); vertices.add(yp + size); vertices.add(zp + size);
vertices.add(xp); vertices.add(yp + size); vertices.add(zp);
}
float[] verts = new float[vertices.size()];
for(int a = 0; a < verts.length; a++) {
verts[a] = vertices.get(a);
}
FloatBuffer cubeBuffer = BufferUtils.createFloatBuffer(verts.length);
cubeBuffer.put(verts);
cubeBuffer.flip();
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glVertexPointer(3, 0, cubeBuffer);
GL11.glDrawArrays(GL11.GL_QUADS, 0, verts.length / 3);
GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
}
}
}
}
(Just ignore some of those variables, they just cull the different polygons)
So I don't know if there is a more efficient way to do this, but if there is, it would be nice if I could get some pointers. Thanks in advance! Oh and...
THERE IS SOMETHING EXTREMELY WRONG WITH HOW I AM RENDERING.