Slick2D Rendering Lots of Polygons
- by Hazzard
I'm writing an little isometric game using Slick. The world terrain is made up of lots of quadrilaterals. In a small world that is 128 by 128 squares, over 16,000 quadrilaterals need to be rendered. This puts my pretty powerful computer down to 30 fps.
I've though about caching "chunks" of the world so only single chunks would ever need updating at a time, but I don't know how to do this, and I am sure there are other ways to optimize it besides that.
Maybe I'm doing the whole thing wrong, surely fancy 3D games that run fine on my machine are more intensive than this.
My question is how can I improve the FPS and am I doing something wrong?
Or does it actually take that much power to render those polygons?
--
Here is the source code for the render method in my game state. It iterates through a 2d array or heights and draws polygons based on the height.
public void render(GameContainer container, StateBasedGame game, Graphics gfx) throws SlickException {
gfx.translate(offsetX * d + container.getWidth() / 2, offsetY * d + container.getHeight() / 2);
gfx.scale(d, d);
for (int y = 0; y < placeholder.length; y++) {// x & y are isometric
// diag
for (int x = 0; x < placeholder[0].length; x++) {
Polygon poly;
int hor = TestState.TILE_WIDTH * (x - y);// hor and ver are orthagonal
int W = TestState.TILE_HEIGHT * (x + y) - 1 * heights[y + 1][x];//points to go off of
int S = TestState.TILE_HEIGHT * (x + y) - 1 * heights[y + 1][x + 1];
int E = TestState.TILE_HEIGHT * (x + y) - 1 * heights[y][x + 1];
int N = TestState.TILE_HEIGHT * (x + y) - 1 * heights[y][x];
if (placeholder[y][x] == null) {
poly = new Polygon();//Create actual surface polygon
poly.addPoint(-TestState.TILE_WIDTH + hor, W);
poly.addPoint(hor, S + TestState.TILE_HEIGHT);
poly.addPoint(TestState.TILE_WIDTH + hor, E);
poly.addPoint(hor, N - TestState.TILE_HEIGHT);
float z = ((float) heights[y][x + 1] - heights[y + 1][x]) / 32 + 0.5f;
placeholder[y][x] = new Tile(poly, new Color(z, z, z));
//ShapeRenderer.fill(placeholder[y][x]);
}
if (true) {//ONLY draw tile if it's on screen
gfx.setColor(placeholder[y][x].getColor());
ShapeRenderer.fill(placeholder[y][x]);
//gfx.fill(placeholder[y][x]);
//placeholder[y][x].
//DRAW EDGES
if (y + 1 == placeholder.length) {//draw South foundation edges
gfx.setColor(Color.gray);
Polygon found = new Polygon();
found.addPoint(-TestState.TILE_WIDTH + hor, W);
found.addPoint(hor, S + TestState.TILE_HEIGHT);
found.addPoint(hor, TestState.TILE_HEIGHT * (x + y + 1));
found.addPoint(-TestState.TILE_WIDTH + hor, TestState.TILE_HEIGHT * (x + y));
gfx.fill(found);
}
if (x + 1 == placeholder[0].length) {//north
gfx.setColor(Color.darkGray);
Polygon found = new Polygon();
found.addPoint(TestState.TILE_WIDTH + hor, E);
found.addPoint(hor, S + TestState.TILE_HEIGHT);
found.addPoint(hor, TestState.TILE_HEIGHT * (x + y + 1));
found.addPoint(TestState.TILE_WIDTH + hor, TestState.TILE_HEIGHT * (x + y));
gfx.fill(found);
}//*/
}
}
}
}