LWJGL drawing too many tiles causing lag

Started by Bingo90, October 17, 2013, 07:59:32

Previous topic - Next topic

Bingo90

I'm drawing many tiles on the screen and it's causing much lag. I can't draw all tiles in one glBegin, because they are using different translations.

This is my drawing code:

public static void drawTexture(Texture texture, Vector2f position, Vector2f translation, Vector2f origin, Vector2f scale, float rotation, Color color, FlipState flipState)
	{

		texture.setTextureFilter(GL11.GL_NEAREST);

		float xFlip = (flipState == FlipState.Both || flipState == FlipState.Horizontal) ? -1 : 1;
		float yFlip = (flipState == FlipState.Both || flipState == FlipState.Vertical) ? -1 : 1;

		color.bind();
		texture.bind();

		GL11.glTranslatef(position.x, position.y, 0);
		GL11.glTranslatef(-translation.x, -translation.y, 0);
		GL11.glRotated(rotation, 0f, 0f, 1f);

		GL11.glScalef(scale.x, scale.y, 1);

		GL11.glScalef(xFlip, yFlip, 1);

		GL11.glBegin(GL11.GL_QUADS);
		
		GL11.glTexCoord2f(0, 0);
		GL11.glVertex2f(0, 0);
		GL11.glTexCoord2f(1, 0);
		GL11.glVertex2f(texture.getTextureWidth(), 0);
		GL11.glTexCoord2f(1, 1);
		GL11.glVertex2f(texture.getTextureWidth(), texture.getTextureHeight());
		GL11.glTexCoord2f(0, 1);
		GL11.glVertex2f(0, texture.getTextureHeight());

		GL11.glEnd();

		GL11.glLoadIdentity();
	}


Is it possible to make this drawing faster? I'm drawing the tiles in a loop. I tried putting glBegin before the loop, but it didn't translate correctly.

Fool Running

Easiest things:
1) Change your two glTranslatef calls into one: GL11.glTranslatef(position.x - translation.x, position.y - translation.y, 0);
2) Change your two glScalef calls into one: GL11.glScalef(scale.x * xFlip, scale.y * yFlip, 1);
3) Only set the texture filter once (where you create the texture) and remove it from your draw.
4) Only bind the texture/color if they are different then the last one you drew.
5) Call glRotatef instead of glRotated
6) Don't call glRotatef or glScalef if they won't do anything.

Here are harder things that will give you a much bigger speed boost:
1) Use a single texture for all your tiles and just change the texture coordinates to select a tile (also called a tile map or tileset).
2) Assuming most of your tiles don't move every frame, calculate all the translations, rotations and scaling yourself and create a big VBO with all the vertexes in it and just draw that big VBO each frame. If you don't want to mess with VBOs, then create a display list with all your tiles that don't move (this will allow you to use your existing draw code). Note that display lists may not always handle texture switching well (i.e. you need to bind the texture outside your display list).

In general, the way you get speedups in OpenGL is to call OpenGL less (i.e. less calls to a method on a GLXX class) by caching the data in the video ram.
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

Bingo90

Ok how to get the currently bound texture with slick?

Fool Running

It's best to keep track of that yourself (i.e. don't ask OpenGL what it's current state is).
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

Bingo90

Wow, thanks to your texture binding hint the fps are dropping only 1% rather than 50%!