Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Drawing scaled tile-based terrain - artifacts

This thread is locked; no one can reply to it. rss feed Print
Drawing scaled tile-based terrain - artifacts
kovarex
Member #14,203
April 2012

Hello,
we are developing a game that has tile-based background.
Problem arises, when we try to scale (zoom) out/in the whole game (it is also used to make minimap so it is quite important).
We compute everything (coordinates) in floating point numbers (doubles) and give it to the allegro functions (it accepts floats there).
The result is, that there are small (1 px) gaps between tiles sometimes (every 5th tile sometimes, random with some other zoom settings).

Tiles without zoom (scale = 1)
<img src="http://www.kovarex.com/download/no-scale.png">

Zoomed scene without using sampling
<img src="http://www.kovarex.com/download/scale-no-multisampling.png">

Zoomed scene with using sampling
<img src="http://www.kovarex.com/download/scale-multisampling.png">

I would expect, that when graphic cards works with floats, there shouldn't be any gap like this.
I would also expect that sampling would solve this, but I was wrong, it makes those artifact even wierder.

Any idea what could be wrong?

www.factorio.com - a factory building game.

Luiji99
Member #12,254
September 2010

I have that in a Wolfenstein-style game that I'm development. There are occasional gaps at certain distances that I can't get rid of. They appear on my ATI but not my Nvidia for some reason. In my case I'm using OpenGL directly (though Allegro sets it up), so I think we can rule out something with Allegro's drawing API...

Programming should be fun. That's why I hate Java.

kovarex
Member #14,203
April 2012

I tested it on another two computers (one windows with different graphics card and one mac), it behaved differently on each one.

The mac had no gaps at all (it is using opengl), and the second one had even more gaps.

www.factorio.com - a factory building game.

someone972
Member #7,719
August 2006
avatar

Are you using a tile sheet? Sometimes when filtering is enabled the textures bleed together on the edges. You could try turning any filtering off if you haven't already and see if it gets rid of the problem. If it does and you still want filtering, you may have to put a border around your images (but there might be a better way I don't know about too).

______________________________________
As long as it remains classified how long it took me to make I'll be deemed a computer game genius. - William Labbett
Theory is when you know something, but it doesn't work. Practice is when something works, but you don't know why. Programmers combine theory and practice: Nothing works and they don't know why. -Unknown
I have recklessly set in motion a chain of events with the potential to so-drastically change the path of my life that I can only find it to be beautifully frightening.

Audric
Member #907
January 2001

Isn't it the issue of counting pixels in OpenGL ?
http://www.allegro.cc/manual/5/primitives.html#pixel-precise-output

SiegeLord
Member #7,827
October 2006
avatar

How are you computing where to draw the tiles? It'd be nice to see that code.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

kovarex
Member #14,203
April 2012

someone972:

Yes, we are using tile sheet (atlas).
I have not enabled filtering, but when I use the MIPMAP (that is kind of filtering, I guess), the brown gap between tile is part of the neighbour tile in the atlas.
When I made 1px transparent border around tiles the gap is now always black :)

Audric:
I would guess that it would be this kind of problem.

Edit:
The question is, what mode ensures, that when I draw bitmap between two pixels, it draws iteslf partially on one pixel and partially on second one?

www.factorio.com - a factory building game.

Neil Roy
Member #2,229
April 2002
avatar

I can't think of the code for this, but this looks like it might have something to do with texture clamping to me. There is a setting where you can turn it on/off which solves this on most systems. There is also opengl code you can add that will also enable/disable this (I can't recall which it is, turning it off or on). I'll see if I can find some code I once used for this in one of my old projects, I know I entered something for it somewhere... been a while. ;)

EDIT:
Here's some code I found

#define GL_CLAMP_TO_EDGE  0x812F

   glBindTexture (GL_TEXTURE_2D, texture[12]);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   glBegin(GL_TRIANGLE_STRIP);

I added in the line before and after to show where I used it. After binding a texture I used the glTexParameteri() with that define to enable it.

Look at your graphic card settings though, there is a setting for setting the clamp.

Oh and while I am on the subject of "clamps", and I can't help it, I just have to post this ;)

606624

---
“I love you too.” - last words of Wanda Roy

Elias
Member #358
May 2000

kovarex said:

When I made 1px transparent border around tiles the gap is now always black

Does the black come from the background or from the tile-sheet? I.e. if you do an al_clear_to_color(red) first, are the gaps now red? If not, what if you make the border around the tiles red instead? Are the gaps now (always) red?

--
"Either help out or stop whining" - Evert

Neil Roy
Member #2,229
April 2002
avatar

I just got done programming my own Level Editor and I adjusted the code so it scales to a fullscreen window mode with some code Mathew provided and I am noticing the lines between my tiles now as well.

{"name":"606626","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/0\/d0be1797966324a83a7c00f04f90679e.png","w":1920,"h":1080,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/0\/d0be1797966324a83a7c00f04f90679e"}606626

The line tiles are one solid strip, no gaps, transparent...

{"name":"606627","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/9\/a903c07c68a7652bff748269fe96baab.png","w":512,"h":32,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/9\/a903c07c68a7652bff748269fe96baab"}606627

When you view the full screenshot (1920x1080) you see this... (a section magnified here)

{"name":"606628","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/2\/1203dfbf51913b2e156edd60a0f325b8.png","w":386,"h":340,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/2\/1203dfbf51913b2e156edd60a0f325b8"}606628

It does look as though portions of the texture are bleeding over. The code I used to draw them with has no errors in it:

(this is the condensed version of my code)

for(int y = 0; y < MAPY; y++)
{
   for(int x = 0; x < MAPX; x++)
   {
      xpos = 12 + x * 32;
      ypos = 48 + y * 32;
      tile = level.map[y][x].tile - 1;
      al_draw_bitmap_region(lines, tile * 32, 0, 32, 32, xpos, ypos, 0);
    }
}

Edit: Oh yes, I also use the following settings...

   al_set_new_bitmap_flags(ALLEGRO_MAG_LINEAR | ALLEGRO_VIDEO_BITMAP);
   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA);
   al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST);
   al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST);

Edit2: Okay, I removed the above lines and it vanished so, I'll have to play around with these settings. Be a pity if I can't use them though.

Edit3: After extensive testing, it is happening specifically with either of the two options below enabled.

al_set_new_bitmap_flags(ALLEGRO_MAG_LINEAR | ALLEGRO_VIDEO_BITMAP);
al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST);

---
“I love you too.” - last words of Wanda Roy

Peter Wang
Member #23
April 2000

When using a sprite sheet you'll need to add a one pixel border around each edge of the sprite, with the same colour as its nearest neighbour.

http://blogs.msdn.com/b/shawnhar/archive/2009/10/21/texture-filtering-sprite-sheets.aspx

Elias
Member #358
May 2000

Yeah, in case the pixels come from the sprite-sheet, that's kovarex' issue as well. But he said he's not using filtering, in which case it has to be something else.

--
"Either help out or stop whining" - Evert

AMCerasoli
Member #11,955
May 2010
avatar

I was having the same problem with some PCs. I was going to solve it by reducing the width and height spacing that I was using. Ex, if the tile is 100X100 I was going to duplicated them as if they were 99X99.

{"name":"606629","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/e\/b\/eb11c301394ba28686e2c2f276d4773b.png","w":795,"h":600,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/e\/b\/eb11c301394ba28686e2c2f276d4773b"}606629

Neil Roy
Member #2,229
April 2002
avatar

When using a sprite sheet you'll need to add a one pixel border around each edge of the sprite, with the same colour as its nearest neighbour.

I'll have to try that. I used TileStudio to create them, so it will be a simple matter of loading and resaving with a border as it has that option.

kovarex, post some of your graphics you use (the actual graphic file you load from) as well as some example code (as I did) you use to display it along with any display settings you use. It would help a good deal more.

You can show images in a message here by dropping them (drag and drop) on the box above, then once uploaded, right click them and select "Save Link Location", then in your message paste the link location surrounded by [] so it would look something like:

[ http://www.allegro.cc/theme/default/icon/67890 ]

(no spaces, that isn't a valid link by the way)

That will cause the images to appear in a message and perhaps we can better help you.

Edit: I may just divide up my sprite sheet at load time, separate the tiles into an array of individual bitmaps.

Edit2: I ended up loading my sprite sheet into a temporary bitmap pointer, then copying the individual tiles over into an array of bitmaps so they can be used without the filtering artifacts. Only tiles that had non-transparent pixels sharing the border with a neighbouring tile on the same sheet needed to be copied. Here's some of the code:

   ALLEGRO_BITMAP *tbmp = NULL;

   tbmp = al_load_bitmap("Graphics/Backgrounds.png");
   if(!tbmp) {
      printf("%s(%d): Error loading backgrounds.\n", __FILE__, __LINE__);
      goto SHUTDOWN;
   }
   for(int i = 0; i < 20; i++) {
      background[i] = al_create_bitmap(TILE_SIZE, TILE_SIZE);
      al_set_target_bitmap(background[i]);
      al_draw_bitmap_region(tbmp, i * 32, 0, 32, 32, 0, 0, 0);
   }
   al_destroy_bitmap(tbmp);
   tbmp = NULL;

Works like a charm. No more artifacts.

---
“I love you too.” - last words of Wanda Roy

Go to: