Tearing when Scaling a Tilemap

Nibbie
Posts: 3
Joined: 2010.06
Post: #1
I have a 2D platform game in development, using a tilemap. I am currently trying to implement scaling functionality with the map, so that the user can use the pinch and zoom gesture to view more of the tilemap at any one time. However, I am encountering some strange problems. When my tilemap is scrolling, when I adjust the scale of the map, I find that there is tearing between the tiles, revealing the background clear colour beneath the tiles.


I've tried two methods to adjust the scaling effect; by using glScale and scaling each image on screen individually. No matter which method I use, I find the same problem. I have my tiles rendered to float positions, but the tearing still occurs.


I've seen on Angry Birds that this is definitely possible, but I am wondering what could possibly be the issue causing the tearing to occur. When the background does not scroll, the tearing does not occur...
Quote this message in a reply
Member
Posts: 129
Joined: 2009.03
Post: #2
Might want to consider rendering all your tiles first to a off-screen texture buffer (unsure what correct terminology is) at 100% scale, which you can then render to the screen back buffer, at whatever scale you like.

Or, you could try clearing the back buffer, to some neutral colour, before rendering your tiles.

I think the first option probably has more going for it...
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #3
you mean there are 1-pixel gaps between your tiles, sometimes?

that would typically be caused by vertices which are supposed to be coincident, not being exactly the same. Any time they're not exactly the same, they could end up being rasterized to slightly different pixels, leading to gaps.

T junctions have the same effect for similar reasons, but that seems less likely in a tile game.
Quote this message in a reply
Sage
Posts: 1,482
Joined: 2002.09
Post: #4
To further what OSC said, if you want things to line up exactly you have to provide exactly the same vertexes AND exactly the same transformation matrix. Floating point numbers have finite precision, so you can't just assume that 2.3*3.0 will evaluate to exactly 6.9 for instance.

From an irb session using double precision floats:
Code:
>> 2.3*3.0
=> 6.9
>> 2.3*3.0 == 6.9
=> false

For floating point results to be equal, you not only need exactly the same input, but exactly the same order of operations as well.

Are you generating a big array with all the vertexes for all the tiles in it or are you reusing the same geometry for a single tile and just translating it? If you are doing the latter, that can be what is causing your problem.

Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
Quote this message in a reply
Member
Posts: 129
Joined: 2009.03
Post: #5
I suspect there is something else at play here..

Imagine 2 tiles line up, so that the right-hand edge of one tile, aligns perfectly with the left-hand edge of a second tile..

Now, imagine this line (where the 2 tiles join), runs bang down the center of a column of pixels..

Rendering from one tile, will have a 50% affect (after alpha blending etc) on the destination pixels for this shared column. Rendering from the second tile, will aslo have a 50% affect.

50% on 50% equates to a 75% effect on the destination pixels, therefore, there will be a slight trace of the background (i.e. how it was, prior to rendering both tiles).
Quote this message in a reply
Sage
Posts: 1,482
Joined: 2002.09
Post: #6
Also true. If you are using linear filtering with an unpadded tileset or blending, that is also going to cause problems. This can sort of be fixed at the cost of more texture memory by padding your tiles.

Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
Quote this message in a reply
Nibbie
Posts: 3
Joined: 2010.06
Post: #7
Thanks for all of the replies.

I've fiddled around with just about every blending option I can think of, so I'm sure it's not that that's causing the problem.

I think Skorche's post about floating point numbers may be the problem. I am generating one large array and rendering that though.

As a test, I tried rendering the tilemap using solid rectangles as opposed to images. Doing this, there is no tearing.
Quote this message in a reply
Nibbie
Posts: 3
Joined: 2010.06
Post: #8
Skorche Wrote:To further what OSC said, if you want things to line up exactly you have to provide exactly the same vertexes AND exactly the same transformation matrix. Floating point numbers have finite precision, so you can't just assume that 2.3*3.0 will evaluate to exactly 6.9 for instance.

From an irb session using double precision floats:
Code:
>> 2.3*3.0
=> 6.9
>> 2.3*3.0 == 6.9
=> false

For floating point results to be equal, you not only need exactly the same input, but exactly the same order of operations as well.

Are you generating a big array with all the vertexes for all the tiles in it or are you reusing the same geometry for a single tile and just translating it? If you are doing the latter, that can be what is causing your problem.

I use a big array with all the vertexes in and draw that.

I think this issue is likely to be the problem, but I'm not sure how to get around it. I've looked at all of the blending options and that does not appear to be the concern.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Scaling iOS Game: iPhone -> iPad s0ckman 2 1,486 Dec 9, 2013 07:34 AM
Last Post: s0ckman
  Scaling Problem in Cocos2d Jerm #1 7 10,293 May 18, 2011 11:02 AM
Last Post: EvolPenguin
  frame buffer 320x480 scaling images/2=retina? sefiroths 0 4,250 May 10, 2011 05:24 AM
Last Post: sefiroths