Android Rendering platform Chunk tiles.

Dear JGO-community,

I’ve came across a big issue in the devolpment in my game, the rendering of the tiles within the chunks are causing some FPS drops. So really my question is how to render the tiles of the chunk cpu-efficient? I’ve already tried some solutions but they didn’t really fit the job…

What’ve tried so far:
Code in Chunk.java

public void render(Canvas canvas, Level level){
    	for(int x = 0; x < 16; x++){
    		for(int y = 0; y < 16; y++){
    			if((cx*16+x)*16*level.scale >= level.xOffset - 16*level.scale && (cx*16+x)*16*level.scale <= level.xOffset + level.gameView.width){
        			if((cy*16+y)*16*level.scale >= level.yOffset - 16*level.scale && (cy*16+y)*16*level.scale <= level.yOffset + level.gameView.height){
        				Tile.getTile(tiles[x + y*16]).render(canvas, level, (cx*16 + x)*16*level.scale - level.xOffset, (cy*16 + y)*16*level.scale - level.yOffset);	
        			}
    			}
        	}
    	}
    }

This gave a FPS from 30 to around 20 and was pretty instable, so I rewrote the whole code to something that didn’t used that much forloops:

Code in Level.java

public void render(Canvas c) {
		for(int tileX = (int)((xOffset)/scale)/1; tileX < (int)((xOffset + gameView.width)/scale)/16; tileX++){
			for(int tileY = (int)((xOffset)/scale)/1; tileY < (int)((yOffset + gameView.height)/scale)/16; tileY++){
				for(Chunk chunk : chunkListOpen){
					if(chunk.cx == (int)(tileX/16) && chunk.cy == (int)(tileY/16)){
						chunk.renderTile(c, this, Math.abs(tileX%16), Math.abs(tileY%16));
					}
				}
			}
		}
}

While running this script the FPS was around 3…

chunkListOpen are 3x3 chunks (in which the center chunk is the chunck which the player is located at)

So really the question is how do you render the visible tiles (most times around 20x8tiles) in 9 chunks efficient?
If you have any questions, feel free to ask them.

Edit:
These are all the tiles visible on the screen

for(int tileX = (int)((xOffset)/scale)/1; tileX < (int)((xOffset + gameView.width)/scale)/16; tileX++){
			for(int tileY = (int)((xOffset)/scale)/1; tileY < (int)((yOffset + gameView.height)/scale)/16; tileY++){

Greetings,
Roseslayer

You probaby need a more efficient data structure

also, what does the getTile method look like.

The best way to solve your problem is to use a profiler and see exactly where the CPU is being eating up. For Android it is quite easy, use DDMS

JRenner, thanks for the reply.

The getTile is pretty straight-forward:

public static Tile getTile(byte id) {
		for(Tile t: tiles){
			if(t.getId() == id){
				return t;
			}
		}
		return null;
	}

And using DDMS, how can you find the location where the CPU is being eaten up?

Greetings,
Roseslayer

Firstly , you are performing 32 (I think) Multiplications per tile! most of the operations are exactly the same! Create a variable and store the result in that and use the variable , much more efficient you should see a moderate improvement from that alone. If you have a map where there are a lot of widely seperated tiles , do not store them in a 2d array with each coordinate instead have each tile store its coordinate and the array just stores tiles consecutively. If you fix your first method just to see how that performs it would seem to work better. I would just give it a go. If you get any success with that please tell me , also show us Tile.rener() if possible and chunk.render_tile().

Hope this helps

tiles[x + y*16] The tiles are already stored consecutively

Tile.render():

	public void render(Canvas c, Level level, float x, float y) {
		level.gameView.gfx.renderBitmap(c, bmp, x, y, level.scale, false, false);
	}

Graphics.renderBitmap():

	public void renderBitmap(Canvas c, Bitmap bmp, float x, float y, float scale, boolean centeredX, boolean centeredY){
		Matrix m = new Matrix();
		m.postTranslate((centeredX ? (-bmp.getWidth() / 2) : 0), (centeredY ? (-bmp.getHeight() / 2) : 0));
		m.postScale(scale, scale);
		m.postTranslate((float)x, (float)y);
		c.drawBitmap(bmp, m, null);
	}

chunk.render_tile() isn’t used, it was just a simple Tile.getTile(tiles[x + y*16]).render(canvas, level, x, y);

But it’s true I am performing 32(probably more) multiplications per tile, which is insanly inefficient.
I think the problem is also the way I am getting the Bitmap that correspond with the TileId…

[edit]:

	public static Tile getTile(byte id) {
		return tiles[id];
	}

This are already some iterations less…

[edit 2:]
Found some websites, after a long time searching:
Voxel 3D Chunk management
Topic about chunk management

Greetings,
Roseslayer.