Hello,
I'm building a game based around the graphics style of minecraft to start with (simple shapes to learn the basics :D). But I find myself in a big deal that the code is using awfully much resources (cpu). I've already spend quite some time trying to optimize the coding of the rendering but its just not enough ): In a perfect situation on a 16x16x64 block field (only need to render outsides) I can push a 70 fps. (i5 2500, ATI HD 6870 1GB, 8GB DDR3 ram).
Is there a way I can improve the coding to increase the framerate? I'm really new into OpenGL so I don't know that much about it yet. I hope I'll recieve some help :)
And now for the coding:
For the rendering I use a couple of part of code.
To start the main rendering of the chunks of the world:
public void render() {
GL11.glEnable(GL_TEXTURE_2D);
GL11.glDisable(GL11.GL_CULL_FACE);
Launcher.getTextureManager().getTexture("terrain").bind();
for(Entry<Long, Chunk> entry : chunkMap.entrySet()) {
entry.getValue().render();
}
GL11.glDisable(GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_CULL_FACE);
}
For the chunk rendering:
public void render() {
for(Entry<Short, Block> entry : blockMap.entrySet()) {
entry.getValue().render();
}
}
And for the blocks:
public abstract boolean isTransparant();
public boolean shouldRenderSide(byte side) {
try {
if(side == RenderStatic.TOP)
return Launcher.getWorld().getBlockAt(x, y + 1, z).isTransparant();
else if(side == RenderStatic.BOTTOM)
return Launcher.getWorld().getBlockAt(x, y - 1, z).isTransparant();
else if(side == RenderStatic.LEFT)
return Launcher.getWorld().getBlockAt(x - 1 , y, z).isTransparant();
else if(side == RenderStatic.RIGHT)
return Launcher.getWorld().getBlockAt(x + 1, y, z).isTransparant();
else if(side == RenderStatic.FRONT)
return Launcher.getWorld().getBlockAt(x, y, z + 1).isTransparant();
else if(side == RenderStatic.BACK)
return Launcher.getWorld().getBlockAt(x, y, z - 1).isTransparant();
else
throw new RuntimeException("Illegal Side: (byte)" + side );
} catch (NullPointerException e) {
return true;
}
}
public boolean isConsealed() {
try {
boolean left = Launcher.getWorld().getBlockAt(x - 1, y, z).isTransparant();
boolean right = Launcher.getWorld().getBlockAt(x + 1, y, z).isTransparant();
boolean up = Launcher.getWorld().getBlockAt(x, y + 1, z).isTransparant();
boolean down = Launcher.getWorld().getBlockAt(x, y - 1, z).isTransparant();
boolean forward = Launcher.getWorld().getBlockAt(x, y, z + 1).isTransparant();
boolean backward = Launcher.getWorld().getBlockAt(x, y, z - 1).isTransparant();
if(left || right || up || down || forward || backward)
return false;
return true;
} catch (NullPointerException e) {
return false;
}
}
public boolean shouldRenderBlock() {
if(!isTransparant() && !isConsealed())
return true;
return false;
}
public void render() {
if(shouldRenderBlock())
super.render();
}
And now for the actual rendering of the block:
private void renderSide(byte side) {
if(!shouldRenderSide(side))
return;
float indexInTexture = getTextureForSide(side);
float x = 0.0625F * indexInTexture;
float xMax = 0.0625F * (1 + indexInTexture);
float y = 0.0625F * ((int)(indexInTexture / 16));
float yMax = y + 0.0625F;
if(side == TOP) {
glTexCoord2f(x, y); glVertex3f(0, height, 0);
glTexCoord2f(x, yMax); glVertex3f(0, height, depth);
glTexCoord2f(xMax, yMax); glVertex3f(width, height, depth);
glTexCoord2f(xMax, y); glVertex3f(width, height, 0);
} else if (side == BOTTOM) {
glTexCoord2f(x, y); glVertex3f(0, 0, 0);
glTexCoord2f(x, yMax); glVertex3f(0, 0, depth);
glTexCoord2f(xMax, yMax); glVertex3f(width, 0, depth);
glTexCoord2f(xMax, y); glVertex3f(width, 0, 0);
} else if (side == BACK) {
glTexCoord2f(x, y); glVertex3f(0, height, 0);
glTexCoord2f(xMax, y); glVertex3f(width, height, 0);
glTexCoord2f(xMax, yMax); glVertex3f(width, 0, 0);
glTexCoord2f(x, yMax); glVertex3f(0, 0, 0);
} else if (side == FRONT) {
glTexCoord2f(x, y); glVertex3f(0, height, depth);
glTexCoord2f(xMax, y); glVertex3f(width, height, depth);
glTexCoord2f(xMax, yMax); glVertex3f(width, 0, depth);
glTexCoord2f(x, yMax); glVertex3f(0, 0, depth);
} else if (side == LEFT) {
glTexCoord2f(x, yMax); glVertex3f(0, 0, depth);
glTexCoord2f(x, y); glVertex3f(0, height, depth);
glTexCoord2f(xMax, y); glVertex3f(0, height, 0);
glTexCoord2f(xMax, yMax); glVertex3f(0, 0, 0);
} else if (side == RIGHT) {
glTexCoord2f(x, yMax); glVertex3f(width, 0, depth);
glTexCoord2f(x, y); glVertex3f(width, height, depth);
glTexCoord2f(xMax, y); glVertex3f(width, height, 0);
glTexCoord2f(xMax, yMax); glVertex3f(width, 0, 0);
} else
throw new RuntimeException("Invalid Side to Render on RenderSquare((byte)" + side + ");");
}
public void render() {
glPushMatrix();
glTranslatef(getX(), getY(), getZ());
glBegin(GL_QUADS);
{
renderSide(LEFT);
renderSide(RIGHT);
renderSide(BOTTOM);
renderSide(TOP);
renderSide(FRONT);
renderSide(BACK);
}
glEnd();
glPopMatrix();
}
Greetings,
Johnnei