Hi, I've been banging my head against this for a while now and would appreciate any insight anyone has to offer. I think it will be simplest to describe my requirements and my problem in list form:
- I'm developing a game for desktop.
- I'm using libGDX's Scene2d.
- I'm intending to limit the aspect ratio of my game area to 16:9. If someone has a 4:3 or 16:10 screen I'll solve that by introducing letterboxing, but that is not what I'm concerned with right now and not the reason I'm writing this post.
- My game is 2d, with a top down viewpoint, and tile based.
- I'm not going for a pixel art look. My original textures will be larger than their ultimate display size, at least at 1920x1080 (unless someone can explain why this is a bad idea).
- My main requirement/problem: I want to display the same number of tiles on screen, in both x and y, regardless of resolution.
- The map will only scroll in terms of discrete tile positions. The map will only ever show partial tiles while in the middle of scrolling. When the map is stationary only whole tiles will be visible.
- In the y direction I want the tiles to cover the entire screen height. In the X direction the tiles will extend from the left of the screen rightwards as far as they need to.
- The number of tiles in both x and y is odd, so that there is a well defined center tile at all times.
I determine the onscreen tile size by dividing the screen height by the number of vertical tiles. The problem is that the number of vertical tiles doesn't always divide evenly into the screen height. This results in non integer tile size and consequently non-integer tile positions, resulting in "shimmering" artifacts as the camera pans. I'm also drawing vertical and horizontal grid lines at tile boundaries and the shimmering problems are especially noticeable with these.
The solution I came up with is to calculate the tile size and overall map size as follows:
- Divide the screen height by my vertical tile count.
- Floor this number to the nearest integer. This is my tile size.
- Calculate the size of the viewable map area by multiplying the tile size by me horizontal and vertical tile counts.
This solution works as it gives me integer tile size and integer viewable map area. The problem is that at most vertical resolutions the viewable map area ends up being shorter than the screen height
. Below is an example of what this looks like (I've centered the viewable area so the black space at top and bottom is the same. Also, the right hand side will be a UI area):http://i.imgur.com/HCfrGYZ.png
This isn't the most awful thing in the world but it does look kind of ugly and and it's something I'd like to avoid if at all possible.
I've tried the following to remedy this:
- Render the tiles at their original dimensions to a Frame Buffer. Then set glViewport to the dimensions I want (maintaining the correct aspect ratio) and render.
- As above, except simply set the Scene2d Stage size to accommodate the tiles at original dimensions, then set glViewport to appropriate screen size.
Both these methods result in the same kind of visual artifacts you get when using non integer tile sizes and positions. In fact it often looks worse as the grid lines I'm drawing (see above image) often get completely filtered out when stationary and only appear/disappear in a shifting pattern when panning the camera.
So, can anyone suggest any solutions to this? Would a custom shader be of any use here (I should point out that I only have a basic idea of what a shader is, let alone how to write one)?
Thanks in advance.