GMS 2 help with pixel perfect scaling

MeltingCat

Member
Hi! I've come across a problem in my game which I have not been able to solve after countless tries and research. I'm trying to scale my pixel art based game to fit multiple screen sizes, without seeing black bars and hopefully a display with the least amount of pixel deformations as possible.

I've been reading as much as I could about this and my main reference points I found in this post:
https://www.yoyogames.com/blog/66/the-basics-of-scaling-the-game-view
and this thread:
https://forum.yoyogames.com/index.php?threads/how-to-properly-scale-your-game.995/
which are both great explanations.


Here is the problem: it works perfectly fine on my 1080p monitor. But as I run the game on a mac book with different resolution and aspect ratio, I find my graphics not quite displayed as I would wish.



Here every game pixel is displayed by 4 monitor pixels. A line which is one game pixel wide is 2 monitor pixels wide. Perfect.


The pixels are much harder to see on this screen, but it is clearly visible that the lines don't have the same thickness anymore. According to all my calculations one pixel in game should just be made out of 9 pixels of this screen. But I can't figure out where my mistake lies.

Here are the numbers:

Comparing monitor with 1920x1080, aspect ratio of 16:9
and a mac book, which has an aspect ratio of 16:10 and a resolution of 2880x1800.

My view port of the game is 960x540 with a same view in most rooms, apart from some rooms where the view is 480x270 or 640x360.

Here is the code I use at the start of the game:

Code:
window_set_fullscreen(true)

Width = camera_get_view_width(view_camera[0]) //960
Height = camera_get_view_height(view_camera[0]) //540
var _CamAspect = Width/Height

var _DispW = display_get_width();
var _DispH = display_get_height();
var _DispAspect = _DispW / _DispH;

var _Wport = view_wport[0]
var _Hport = view_hport[0]

if _CamAspect != _DispAspect {
    
    Height = Width / _DispAspect
    _Wport = view_wport[0]
    _Hport = _Wport / _DispAspect
    view_set_hport(0, round(_Hport)) 
}

camera_set_view_size(view_camera[0], round(Width), round(Height))

surface_resize(application_surface, Width, Height)
application_surface_draw_enable(false)

Scale = view_wport[0] / Width

display_set_gui_size(_Wport, _Hport)
This code runs also at every room start apart from not resizing the gui layer every time, but also the view port stays the same across every room.

Then the surfaces will be drawn like this on the gui layer.
Code:
    gpu_set_blendenable(false)   
    draw_surface_ext(application_surface, 0, 0, Scale, Scale, 0, c_white, 1)
    gpu_set_blendenable(true)


Sorry for the long post, thanks for bearing with me, I hope all the info was clear. If there is any information missing please let me know.

All help is greatly appreciated!
 
Top