LWJGL Forum

Programming => Lightweight Java Gaming Library => Topic started by: W0x on January 26, 2012, 23:13:11

Title: Concerning graphical glitch in 2d tile rendering [SOLVED]
Post by: W0x on January 26, 2012, 23:13:11
Hi everyone,

I'm programming a simple game using the LWJGL. The game uses a tile-based map.

I implemented an Atlas for my tile textures and wrote some code to generate the proper texture coordinates.

Now, this all seems to be working perfectly fine. The right textures are loaded every time and no bleeding occurs.
When I scroll the map, however, (I do this by translating the scene over a PAN_X and PAN_Y variable), some strange graphical glitches occurr every now and then. I have attached a screenshot of the problem. (the screenshot is of low quality, just a compression result, you will clearly see the graphical glitch I refer to, though.)

Does this look familiar to anyone? What could cause this phenomenon?

I call the general rendering routine as follows:


GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);

GL11.glPushMatrix();

Texture texture = TextureUtils.ATLAS;
texture.bind();

world.renderTiles();

GL11.glPopMatrix();


The tiles are then rendered as such:


GL11.glPushMatrix();

GL11.glTranslatef(PAN_X, PAN_Y, 0f);
GL11.glScalef(World.ZOOM, World.ZOOM, 0f);

for (int y = tileY0; y < tileY1; y++)
{
for (int x = tileX0; x < tileX1; x++)
{
if ((x > MAP_SIZE-1) || (y > MAP_SIZE-1) || (x < 0) || (y < 0))
{
// Do not render
}
else
{
GraphicsUtils.renderTileGraphic(tiles[x][y]);
}
}
}

GL11.glPopMatrix();


I use the following basic rendering code for the tiles:


public static void renderTileGraphic(IRenderable renderObject)
{
int x = renderObject.getLocation().x;
int y = renderObject.getLocation().y;

Point coordinates = TextureUtils.getTileTextureCoordinates(renderObject.getTexture());

double tx0 = coordinates.x*TextureUtils.TEXTURE_STEP_TILE;
double tx1 = (coordinates.x+1)*TextureUtils.TEXTURE_STEP_TILE;

double ty0 = coordinates.y *TextureUtils.TEXTURE_STEP_TILE;
double ty1 = (coordinates.y+1)*TextureUtils.TEXTURE_STEP_TILE;

GL11.glPushMatrix();

GL11.glTranslatef(x, y, 0);
GL11.glRotatef(renderObject.getRotation(), 0f, 0f, 1f);
GL11.glTranslatef(-x, -y, 0);

GL11.glBegin(GL11.GL_QUADS);
   GL11.glTexCoord2d(tx0,ty0);
GL11.glVertex2d(x - (renderObject.getWidth()/2), y - (renderObject.getHeight()/2));

GL11.glTexCoord2d(tx0,ty1);
GL11.glVertex2d(x - (renderObject.getWidth()/2), y + (renderObject.getHeight()/2));

GL11.glTexCoord2d(tx1,ty1);
GL11.glVertex2d(x + (renderObject.getWidth()/2), y + (renderObject.getHeight()/2));

GL11.glTexCoord2d(tx1,ty0);
GL11.glVertex2d(x + (renderObject.getWidth()/2), y - (renderObject.getHeight()/2));
GL11.glEnd();

GL11.glPopMatrix();
}
Title: Re: Concerning graphical glitch in 2d tile rendering
Post by: Fool Running on January 27, 2012, 13:44:20
That artifact is typically caused by some vertexes of your polygon not being in the correct place (i.e. they got calculated to be off the screen somewhere).
This code looks suspicious:

GL11.glTranslatef(x, y, 0);
GL11.glRotatef(renderObject.getRotation(), 0f, 0f, 1f);
GL11.glTranslatef(-x, -y, 0);

Is there a reason you translate to the location of the tile before rotating it?
Title: Re: Concerning graphical glitch in 2d tile rendering
Post by: W0x on January 27, 2012, 14:49:30
Quote
That artifact is typically caused by some vertexes of your polygon not being in the correct place (i.e. they got calculated to be off the screen somewhere).
This code looks suspicious:

GL11.glTranslatef(x, y, 0);
GL11.glRotatef(renderObject.getRotation(), 0f, 0f, 1f);
GL11.glTranslatef(-x, -y, 0);


Is there a reason you translate to the location of the tile before rotating it?

Thanks for your reply.

Perhaps this is the result of my own in-experience. The way I understood it I need to translate the matrix to the position of the rendering object before rotating to ensure it rotates around its own axis, and not around some arbitrary other point (pivoting).

Is this assumption incorrect?
Title: Re: Concerning graphical glitch in 2d tile rendering
Post by: CodeBunny on January 27, 2012, 16:23:20
Actually, why do you rotate at all? It looks like your tiles don't need to rotate; you're wasting a call on something you don't use.
Title: Re: Concerning graphical glitch in 2d tile rendering
Post by: W0x on January 27, 2012, 16:28:10
Very true, I should remove that part for tile rendering (the code was meant to be as generic as possible, hence the interface as an argument to the method). Did I go about the rotation wrong, though? Could this cause the glitches I'm seeing?
Title: Re: Concerning graphical glitch in 2d tile rendering
Post by: CodeBunny on January 27, 2012, 17:13:16
I'm not sure.

No offense, but your render method is very ugly and slow. That's understandable, I assume you're starting out with LWJGL programming - we've all been there. I would look up general tutorials and tips on how to draw a large tilemap.
Title: Re: Concerning graphical glitch in 2d tile rendering
Post by: Fool Running on January 27, 2012, 17:13:48
Quote from: W0x on January 27, 2012, 14:49:30
Thanks for your reply.

Perhaps this is the result of my own in-experience. The way I understood it I need to translate the matrix to the position of the rendering object before rotating to ensure it rotates around its own axis, and not around some arbitrary other point (pivoting).

Is this assumption incorrect?
Yes, normally you want to translate before rotating, but you are not using the translation (you are un-translating right after the rotation). In essence you are translating after the rotation because you are doing the un-translating. I think this might be causing your problem. A quick way to check if this is, indeed, your problem is to comment out those 3 lines and see if the glitches go away.

EDIT: To get more of what you are probably looking for, you probably need to do something like:
public static void renderTileGraphic(IRenderable renderObject)
{
int x = renderObject.getLocation().x;
int y = renderObject.getLocation().y;

Point coordinates = TextureUtils.getTileTextureCoordinates(renderObject.getTexture());

double tx0 = coordinates.x*TextureUtils.TEXTURE_STEP_TILE;
double tx1 = (coordinates.x+1)*TextureUtils.TEXTURE_STEP_TILE;

double ty0 = coordinates.y *TextureUtils.TEXTURE_STEP_TILE;
double ty1 = (coordinates.y+1)*TextureUtils.TEXTURE_STEP_TILE;

GL11.glPushMatrix();

GL11.glTranslatef(x, y, 0);
GL11.glRotatef(renderObject.getRotation(), 0f, 0f, 1f);

GL11.glBegin(GL11.GL_QUADS);
    GL11.glTexCoord2d(tx0,ty0);
GL11.glVertex2d(-(renderObject.getWidth()/2), -(renderObject.getHeight()/2));

GL11.glTexCoord2d(tx0,ty1);
GL11.glVertex2d(-(renderObject.getWidth()/2), (renderObject.getHeight()/2));

GL11.glTexCoord2d(tx1,ty1);
GL11.glVertex2d((renderObject.getWidth()/2), (renderObject.getHeight()/2));

GL11.glTexCoord2d(tx1,ty0);
GL11.glVertex2d((renderObject.getWidth()/2), -(renderObject.getHeight()/2));
GL11.glEnd();

GL11.glPopMatrix();
}
Title: Re: Concerning graphical glitch in 2d tile rendering
Post by: W0x on January 27, 2012, 17:27:10
Quote from: CodeBunny on January 27, 2012, 17:13:16
I'm not sure.

No offense, but your render method is very ugly and slow. That's understandable, I assume you're starting out with LWJGL programming - we've all been there. I would look up general tutorials and tips on how to draw a large tilemap.

You do indeed assume correctly. I do not feel that it is appropriate to post this type of response, though.
Constructive critisism only, please.
Title: Re: Concerning graphical glitch in 2d tile rendering
Post by: W0x on January 27, 2012, 17:28:20
Quote from: Fool Running on January 27, 2012, 17:13:48
Quote from: W0x on January 27, 2012, 14:49:30
Thanks for your reply.

Perhaps this is the result of my own in-experience. The way I understood it I need to translate the matrix to the position of the rendering object before rotating to ensure it rotates around its own axis, and not around some arbitrary other point (pivoting).

Is this assumption incorrect?
Yes, normally you want to translate before rotating, but you are not using the translation (you are un-translating right after the rotation). In essence you are translating after the rotation because you are doing the un-translating. I think this might be causing your problem. A quick way to check if this is, indeed, your problem is to comment out those 3 lines and see if the glitches go away.

EDIT: To get more of what you are probably looking for, you probably need to do something like:
public static void renderTileGraphic(IRenderable renderObject)
{
int x = renderObject.getLocation().x;
int y = renderObject.getLocation().y;

Point coordinates = TextureUtils.getTileTextureCoordinates(renderObject.getTexture());

double tx0 = coordinates.x*TextureUtils.TEXTURE_STEP_TILE;
double tx1 = (coordinates.x+1)*TextureUtils.TEXTURE_STEP_TILE;

double ty0 = coordinates.y *TextureUtils.TEXTURE_STEP_TILE;
double ty1 = (coordinates.y+1)*TextureUtils.TEXTURE_STEP_TILE;

GL11.glPushMatrix();

GL11.glTranslatef(x, y, 0);
GL11.glRotatef(renderObject.getRotation(), 0f, 0f, 1f);

GL11.glBegin(GL11.GL_QUADS);
    GL11.glTexCoord2d(tx0,ty0);
GL11.glVertex2d(-(renderObject.getWidth()/2), -(renderObject.getHeight()/2));

GL11.glTexCoord2d(tx0,ty1);
GL11.glVertex2d(-(renderObject.getWidth()/2), (renderObject.getHeight()/2));

GL11.glTexCoord2d(tx1,ty1);
GL11.glVertex2d((renderObject.getWidth()/2), (renderObject.getHeight()/2));

GL11.glTexCoord2d(tx1,ty0);
GL11.glVertex2d((renderObject.getWidth()/2), -(renderObject.getHeight()/2));
GL11.glEnd();

GL11.glPopMatrix();
}


Thanks, I was at work earlier and did not have the change to try it. I'll mess around with it for a bit more and hopefully fix my problems. :)
Title: Re: Concerning graphical glitch in 2d tile rendering [SOLVED]
Post by: W0x on January 27, 2012, 19:33:18
My problem was fixed when I loaded the map into video-card memory using Display Lists. The framerate has obviously increased, but as a friendly side-effect the graphical glitching is gone. :)