Scaling + Tiled Images = Gaps
Posted: Fri Jun 15, 2012 4:23 pm
Before I post my .love file and beg you all for help, I'd like to provide a little context. I'm trying to build a rather rudimentary 2D adventure game. Something that would let the player make a character walk around in a walkable area, click on things to look at them, pick them up, use them etc. The game is an exercise for me to learn about Love's capabilities and limitations.
Unfortunately, I'm not even at the point where I have ego moving around the screen. I hit a bit of a snag scaling the background image to make my game resolution independent.
Thinking about games I'd played recently with smooth, beautiful, high-resolution background artwork (like Lost Horizon), I thought I'd use high resolution background images and scale them down (maintaining aspect ratio) to the user's resolution in full screen mode. Before I even got started, I ran into issues that were (thankfully!) well documented and fixed in builds > 0.80.
After sorting out full screen mode, my first attempt at drawing the background was to do things as simply as possible -- load the image and then scale, translate and draw it every frame. This worked fine on my Windows 7 desktop with its 8800 GTX that gobbles up and spits out large textures at lightning speeds. When I fired it up on a test Windows XP machine in Virtual PC, however, I got this:
I promptly checked out a few of the community articles on the power of 2 problem (PO2) and deduced that this might be the culprit. Indeed if I limited the source image size to 1024x1024, my test background magically appeared in Virtual PC. Thinking I'd solved the problem, I went about building a function that took a really high-res background image and split it into 512x512 (1 PO2 smaller for safety) textures.
Note: I call the 512x512 blocks that Love processes 'textures' because that's what I think they are. I'm not sure if that's the correct term, but it makes the most sense to me. As I understand it, they're stored in VRAM and their size is constrained by video card limitations, not Love ones.
Anyway, I built a similar function to piece the background back together from the smaller textures. So now I had a draw function that:
1. Scaled everything down to fit the full screen resolution
2. Translated everything down or right so that the letterboxing/pillarboxing (if any) around the content was equal
3. Drew the background in 512x512 blocks
4. Drew the cursor
Whew! I thought everything was complete. My 3200x2000 (16:10) source image was still being scaled down nicely on my 1600x1200 monitor. But (shock, horror!) on the Virtual PC Windows XP machine at 1280x1024, I noticed this:
Basically I'm seeing little gaps between the 512x512 textures. At different resolutions they can be more / less pronounced in other areas. I thought about the problem a bit.
- My original resolution was 3200x2000
- I was trying to scale to 1280x1024
- This would mean each 512x512 block would actually be (0.4 x 512) x (0.4 x 512) ... or 204.8x204.8
I thought this could be the problem. Love might be drawing the first texture at (0,0) then the second one at 204.8x204.8 and so on, causing the weird gaps between textures. I tried forcing a scale of 0.3984375 -- that is, 204x204 textures, but this didn't solve the problem! The gaps were... if anything, more pronounced. I even tried clamping my tiled x/y coordinates with math.floor because I thought there might be an IEEE float rounding issue, but still no dice.
So... I'm out of ideas. I've searched the forums thoroughly but haven't found any solutions. I'm hoping some kind soul will here point out where my code is broken. The .love file includes a "brony" (lol) background image from DeviantArt which I think is fair use. Most of the code is in "romance.lua" which is also my namespace for extra functions I've written, e.g. romance.newTiledImage, romance.drawTiledImage. Pretty straightforward, and love->romance seems to be a logical progression. Any, and I mean ANY help would be appreciated. Sorry for the long-winded post! I also have a second question about screenshots, but I might save it for another post.
Unfortunately, I'm not even at the point where I have ego moving around the screen. I hit a bit of a snag scaling the background image to make my game resolution independent.
Thinking about games I'd played recently with smooth, beautiful, high-resolution background artwork (like Lost Horizon), I thought I'd use high resolution background images and scale them down (maintaining aspect ratio) to the user's resolution in full screen mode. Before I even got started, I ran into issues that were (thankfully!) well documented and fixed in builds > 0.80.
After sorting out full screen mode, my first attempt at drawing the background was to do things as simply as possible -- load the image and then scale, translate and draw it every frame. This worked fine on my Windows 7 desktop with its 8800 GTX that gobbles up and spits out large textures at lightning speeds. When I fired it up on a test Windows XP machine in Virtual PC, however, I got this:
I promptly checked out a few of the community articles on the power of 2 problem (PO2) and deduced that this might be the culprit. Indeed if I limited the source image size to 1024x1024, my test background magically appeared in Virtual PC. Thinking I'd solved the problem, I went about building a function that took a really high-res background image and split it into 512x512 (1 PO2 smaller for safety) textures.
Note: I call the 512x512 blocks that Love processes 'textures' because that's what I think they are. I'm not sure if that's the correct term, but it makes the most sense to me. As I understand it, they're stored in VRAM and their size is constrained by video card limitations, not Love ones.
Anyway, I built a similar function to piece the background back together from the smaller textures. So now I had a draw function that:
1. Scaled everything down to fit the full screen resolution
2. Translated everything down or right so that the letterboxing/pillarboxing (if any) around the content was equal
3. Drew the background in 512x512 blocks
4. Drew the cursor
Whew! I thought everything was complete. My 3200x2000 (16:10) source image was still being scaled down nicely on my 1600x1200 monitor. But (shock, horror!) on the Virtual PC Windows XP machine at 1280x1024, I noticed this:
Basically I'm seeing little gaps between the 512x512 textures. At different resolutions they can be more / less pronounced in other areas. I thought about the problem a bit.
- My original resolution was 3200x2000
- I was trying to scale to 1280x1024
- This would mean each 512x512 block would actually be (0.4 x 512) x (0.4 x 512) ... or 204.8x204.8
I thought this could be the problem. Love might be drawing the first texture at (0,0) then the second one at 204.8x204.8 and so on, causing the weird gaps between textures. I tried forcing a scale of 0.3984375 -- that is, 204x204 textures, but this didn't solve the problem! The gaps were... if anything, more pronounced. I even tried clamping my tiled x/y coordinates with math.floor because I thought there might be an IEEE float rounding issue, but still no dice.
So... I'm out of ideas. I've searched the forums thoroughly but haven't found any solutions. I'm hoping some kind soul will here point out where my code is broken. The .love file includes a "brony" (lol) background image from DeviantArt which I think is fair use. Most of the code is in "romance.lua" which is also my namespace for extra functions I've written, e.g. romance.newTiledImage, romance.drawTiledImage. Pretty straightforward, and love->romance seems to be a logical progression. Any, and I mean ANY help would be appreciated. Sorry for the long-winded post! I also have a second question about screenshots, but I might save it for another post.