Fastest way to render 2D tiles

I am trying to write 2D tile based game, tiles are 10 x 10 pixels. And when i am rendering blocks my fps is 40… So, what is best way render 2D tiles? Currently, i am using LWJGL, but maybe there is faster library than LWJGL? I heard something about libGDX, it is faster?

what code are you using to render blocks?

I’m rendering over 2000 objects per frame in my MMO and it runs at 200 FPS on average consumer hardware (LWJGL) and 160 FPS (Java2D) so you’re clearly doing something wrong…

Also the objects I render are a LOT bigger than 10x10 pixels.

 for(int x = 0; x < blocks.length; x++){
		        	for(int y = 0; y < blocks[0].length; y++){
		        		if(x + 30 > player.x/Block.blockSize && x - 30 < Player.x /Block.blockSize){
			        		if(y + 30 > player.y / Block.blockSize && y - 30 < Player.y /Block.blockSize){
			        			blocks[x][y].draw();		      
			        		}
		        		}
		        	}
			 }
public void draw(){
			
			if(id == ids.dirt){
				GL11.glColor3f(1.5f, 0.25f, 0.1f);
			}
			if(id == ids.tree){
	
				GL11.glColor3f(0.35f, 0.2f, 0.1f);
	
			}
			if(id == ids.rock){
				GL11.glColor3f(0.9f, 0.9f, 0.9f);
			}
			if(id == ids.water){
				GL11.glColor3f(0.0f, 0.2f, 1.0f);
			}
			
		GL11.glPushMatrix();
			
			
			GL11.glBegin(GL11.GL_QUADS);
				GL11.glVertex2f(x , y );
				GL11.glVertex2f(x + Block.blockSize, y );
				GL11.glVertex2f(x + Block.blockSize, y + Block.blockSize);
				GL11.glVertex2f(x , y + Block.blockSize);
			GL11.glEnd();
		GL11.glPopMatrix();
		
			GL11.glColor3f(1f, 1f, 1f);

		}

I think i can edit this:

if(id == ids.dirt){
				GL11.glColor3f(1.5f, 0.25f, 0.1f);
			}
			if(id == ids.tree){
	
				GL11.glColor3f(0.35f, 0.2f, 0.1f);
	
			}
			if(id == ids.rock){
				GL11.glColor3f(0.9f, 0.9f, 0.9f);
			}
			if(id == ids.water){
				GL11.glColor3f(0.0f, 0.2f, 1.0f);
			}

Because its fps wasting, but it’s can’t be main problem

Oh yeah… immediate mode.

You dont want to use immediate mode, you want to use glDrawArrays or glDrawElements to draw your tiles. Also, you should be using a textureAtlas to cut down on the amount of glBindTexture calls you need to make.

Do you know what push and pop matrix does? Probably not as you are doing nothing with them. LWJGL is JUST opengl bindings. Libgdx is an actually engine of sorts.

Even in immediate mode you should get 10k plus tiles on ancient computers.

It doesn’t look like you are doing any texturing so that can’t be the performance drop. How many are you trying to render?

If you want more then 10-20k tiles, then you need to batch everything.

Come out of the immediate mode and use VBOs.

Thanks for help to everyone, but is VBO best opinion for render tiles?

And one more thing what i just remembered. I am creating a rectangle for each tile, because i need to build or destroy tiles. Is rectangles best opinion for tiles?

Ok, a bunch of things.

  1. Don’t use plain immediate mode, at least use display lists which are incredibly easy to implement using your code.
  2. Don’t call glPushMatrix and glPopMatrix unless you are translating, rotating or scaling (or any of those other operations) a tile. Pushing and popping the matrix basically saves the state of the matrix before you translate, rotate etc… and then loads the old matrix after. I’ve tried to put it into simple terms. So basically, if you need to only rotate one quad, wrap it in the push and pop matrix calls. That way it doesn’t affect the other tiles.
  3. Don’t call glBegin and glEnd every time you render a tile. Do something like this:

for(int x = 0; x < mapWidth; x++){
    for(int y = 0; y < mapHeight; y++){
        glBegin();
        draw();
        glEnd();
    }
}

This should increase performance.

  1. Statically create your tiles. This might be a bit over your head, but do something like this:
	
public static final Tile Grass = new TileGrass();

And then TileGrass just extends Tile. I just horribly explained that, but basically if you have a tile class, you need to only create your tiles once.

if the tiles don’t change a lot, I would use fbos: http://lwjgl.org/wiki/index.php?title=Using_Frame_Buffer_Objects_(FBO)

Thanks for help, now i understand how i should create my game :slight_smile:

VBO for everything !
You might want to take a look at the VertexBatch class of LibGDX for a good VBO example / code base.

VBO is not for everything. Just because it seems the fastest does not mean you should use it for every situation. Plus, OP here is obviously new to OpenGL and probably couldn’t grasp the concept yet as its advanced OpenGL. Let him warm up to the easy stuff first before he has to learn the hard stuff.

But everything else is rightfully deprecated. =P

8 redudant branch and 10 opengl calls per tile.

Ps.
Also solve visibilty outside of loop. You got uniform grid, its acceleration structure so use that.

I already solved visibility outside loop, but thanks :slight_smile:

Since every tile is just a rectangle, you can even do like this to increase the speed.


glBegin(GL_QUADS);
{
    for (int x = 0; x < mapWidth; x++)
    {
        for (int y = 0; y < mapHeight; y++)
        {
            draw();
        }
    }
}
glEnd();

In this way, you can even increase the performance by decreasing the gl calls. Even though, I recommend VBOs since they are much faster. If you need even more performance, you may look into topics like Sprite Batching.

Nice and simple, but i will try to use VBO for this game.

No you didn’t you solve it. You do it per tile aka brute force.
It can be done in constant time. You calculate first and last tile per axis that you can see and then just loop only those. No need for branches at inner loop and tiles out of sight don’t waste any performance.