Scaling, resolution and pixel art

Hi everyone,

I’m working on a PC-only game (Windows, Mac and Linux), but I’m running in to a few snags with choosing the correct resolution, and handling the scaling. I’m using SDL_Texture’s etc. and not OpenGL directly.

Most art in my game is pure pixel art, and the game is centered around a statically sized level/tilemap. Each tile is 16x16, with the tilemap’s size currently at 40x26 tiles.

I’m using a logical resolution of 640x480, then allowing SDL to scale and add the black bars, using the SDL_WINDOW_FULLSCREEN_DESKTOP flag. I’m also using nearest pixel sampling, by the way.

Now, in theory this all seems perfect, and should (afaik) support the majority of users out there, with the minimal resolution of 640x480.

The problem comes from when the native/actual resolution is not 2x the logical resolution, for example with the logical resolution of 640x480, and an actual resolution of 1920x1080.

What ends up happening is that tiles/sprites aren’t scaled equally, and even text (SDL_ttf with the infamous Nokia font) ends up looking skewed.

I’d first like to know if my current way of doing it is correct/feasible for a “pure” pixel-based game. If it is, I’d like to know what my options would be regarding the skewing/scaling issues and choosing the correct resolutions.

Any help would be greatly appreciated!

As I haven’t gotten any replies, I’ll try to elaborate or simplify the issue.

When using SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, 0) and SDL_RenderSetLogicalSize(_renderer, 640, 480) with my 16x16 pixel art tiles and a pixel art font, SDL incorrectly scales the game to an aspect ratio/scale that’s not 1:1 with the original/logical resolution (640x480).

This is a real issue for me, and I originally thought that setting the logical size would also add black bars to the top/bottom if the resolution height wasn’t an exact match.

Would I be better off implementing the black bars by myself (both horizontally and vertically), or am I missing something here?

I made a quick image that shows the stretching at different resolutions.
[Image: https://dl.dropboxusercontent.com/u/480/SDL_Scaling_Issue.png ]

When using SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, 0) and
SDL_RenderSetLogicalSize(_renderer, 640, 480) with my 16x16 pixel art
tiles and a pixel art font, SDL incorrectly scales the game to an
aspect ratio/scale that’s not 1:1 with the original/logical resolution
(640x480).

The easy way to fix this problem is to lock the size of window and could
only changed by some in-game setting you create, then you can prevent
none 1:1 physical window size.

The hard way is to change sampling algorithm in SDL. But still, you
would never place three dots into five screen pixels averagely so this
won’t fix anything.

This is a real issue for me, and I originally thought that setting the
logical size would also add black bars to the top/bottom if the
resolution height wasn’t an exact match.

Would I be better off implementing the black bars by myself (both
horizontally and vertically), or am I missing something here?

SDL won’t create black bar for you but to achieve it, just need a simple
trick: clear entire screen with black before drawing your stuffs.On Sat, Apr 25, 2015 at 08:44 AM, Dids <pauli.jokela at didstopia.com> wrote:


< Work hard, also play hard and have fun >

    \   ^__^
     \  (oo)\_______
        (__)\       )\/\
            ||----w |
            ||     ||

-------------- next part --------------
A non-text attachment was scrubbed…
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20150427/618e8e91/attachment.pgp

Hello,

[…]

I’m using a logical resolution of 640x480,

This isn’t theoretically a showstopper, but considering that virtually
all screens are 16:9 these days, I’d suggest using 640x360 as the
"native" resolution instead. It greatly improves the chances of nice
integer scaling factors to fullscreen modes on most current platforms.

then allowing SDL to scale and
add the black bars, using the SDL_WINDOW_FULLSCREEN_DESKTOP flag. I’m also
using nearest pixel sampling, by the way.

Scaling is what it is, and the only way that really works without
blurring or distorting the graphics is to stick with integer scaling
factors. Calculate display/original for width and height, grab the
smallest quotient, and round it down to an integer value, to get your
scaling factor. (Assume pixels are square unless you’re targeting some
really odd displays. Different scaling factors for width and height is
almost always wrong!) Then set up your own scaling and offset, so you
get a centered view with borders if needed.On Tue, Apr 21, 2015 at 7:38 PM, Dids <pauli.jokela at didstopia.com> wrote:


//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.— Games, examples, libraries, scripting, sound, music, graphics —.
| http://consulting.olofson.net http://olofsonarcade.com |
’---------------------------------------------------------------------’

Thank you very much!

For some reason I wasn’t even thinking that most displays are 16:9 anyway, so why not target that.

I tried using various different resolutions from here:
https://pacoup.com/2011/06/12/list-of-true-169-resolutions/

The only resolution that displayed no scaling issues was the 640x360 that you mentioned, although that does make the level size in my game smaller.

I’ll have to see if this resolution is enough for the game so it doesn’t impact gameplay, but if it does, I’ll try my best to roll my own scaling solution.

Thanks again, always helps to have a second set of eyes look at a problem. :slight_smile:

If you want smart scaling, you really have to do it yourself. Use whatever
screen resolution makes the most sense for the device (e.g. fullscreen
window resolution). Choose an aspect ratio for your main playing viewport
independently from that. When you calculate scaling factors, scale your
playing field so it’s scaled to the size of the minimum screen dimension.
The screen’s aspect ratio then doesn’t matter at all except that it shows
more or less of the area beyond your main play area (which you can treat
either like letterboxing, show unimportant decoration, or show more of the
action around the main view focus).

The trouble is that it’s kinda a lot of work and mess unless you design
your code to hide the scaling factors. I’m also not sure how well it would
work for getting precise pixels rendered.

Jonny DOn Saturday, May 2, 2015, Dids <pauli.jokela at didstopia.com> wrote:

Thank you very much!

For some reason I wasn’t even thinking that most displays are 16:9 anyway,
so why not target that.

I tried using various different resolutions from here:
https://pacoup.com/2011/06/12/list-of-true-169-resolutions/

The only resolution that displayed no scaling issues was the 640x360 that
you mentioned, although that does make the level size in my game smaller.

I’ll have to see if this resolution is enough for the game so it doesn’t
impact gameplay, but if it does, I’ll try my best to roll my own scaling
solution.

Thanks again, always helps to have a second set of eyes look at a problem. [image:
Smile]