GMS 2 GUI Size is a lie!?

Khao

Member
Currently setting up some proper display options for my game. Everything works and saves as it should but something's... Off about the resolution of the game and it completely stopped making sense to me unless the display_get_gui_width/height functions are straight up lying to me... which I highly doubt.

This is my menu. Everything in this screen is being drawn in the draw_gui event. Resolution is set to 1024x576.




Except... Everything still appears smooth. The resolution absolutely changed. The "1024x576" number in the corner of the screen is absolutely correct, as it's literally being drawn by doing:
Code:
draw_text(20,20,string(display_get_gui_width())+"x"+string(display_get_gui_height()))
If those numbers are correct... It's impossible for the menu to look as smooth as it does. That's still a 1080p image.

Soooo... how do I know resolution is actually being changed? Well, in-game, things look like this.



Game is absolutely running at 1024x576, as everything looks super pixelated. Everything except the gui. But again, display_get_gui_width and display_get_gui_height are still returning 1024 and 576 respectively, so why the heck is the UI so high-res? The even weirder part is that I'm actually scaling my GUI draw stuff so they remain at a consistent size at all resolutions, and if I don't do that, everything displays at the size you'd expect from a smaller gui layer. It genuinely makes no sense whatsoever to me. Absolutely everything is pointing towards the gui layer being resized correctly, from numbers, to coordenates, to the scaling adjustments I have to make... but everything is still displayed at a higher res than the numbers would tell you. If the UI layer is really being scaled correctly, then an UI as smooth as I'm getting would be impossible.

This is my code for changing resolutions:

Code:
var dw=global.resolution_width
var dh=global.resolution_height
room_set_viewport(room,view_camera[0],1,0,0,dw,dh)
surface_resize(application_surface, dw, dh)
display_set_gui_size(dw,dh)
Any ideas? Am I missing a step? And also if I'm missing a step why the heck is are display_get_gui_width and display_get_gui_height returning the wrong values?
 
Last edited:

Joe Ellis

Member
I don't know the exact answer to this,
but I think the problem is because you're not able to set the resolution of the monitor, so it's always at full standard res or whatever resolution the monitor is set to.
When the app or gui surface size doesn't match the resolution the inbuilt drawing gm does internally is scale the surface to fill the screen
So when you change the resolution of the app surface, it's basically changing the amount of detail\pixels it's able to display, if it's less than the screen res it'll scale it up, if more than, it scales down.
I think the view port shouldn't be changed when the app & gui surface resolution changes cus it'll expand or decrease the area of the level you can see on the screen, so it ends up being similar to just zooming in and out, but also the app surface has less\more pixels on it.
So if you make the resolution smaller, there are less pixels on the app surface, while also displaying less "game pixels"\coordinate units across the screen. And if you make the resolution larger, there are more pixels on the app surface, while also displaying more "game pixels"\coordinate units across the screen. So it's kind of like just expanding the view region and making the amount of pixels displayed match, which defeats the point of changing the resolution.
Anyway, I don't know if that is the heart of the problem, it's just a few things I was thinking when I saw this that might help
 
@Joe Ellis That's true, but why would the resolution of the GUI be super crisp (so it still has the "real" number of pixels to draw with), while still saying that it's "scaled down" (i.e. having less pixels to draw with). I myself have run into a problem with GUI scaling recently when resizing the game window. It leads to some odd ways that the GUI resolution changes, and it seems as though I have to be calling display_set_gui_size(intended_width,intended_height) every draw step, otherwise it doesn't scale things properly. Sometimes even calling the gui_size function in one instance doesn't fix it for other instances, which seems really weird as surely once I've set it, it doesn't "revert" back on the next step...
 

Khao

Member
I don't know the exact answer to this,
but I think the problem is because you're not able to set the resolution of the monitor, so it's always at full standard res or whatever resolution the monitor is set to.
When the app or gui surface size doesn't match the resolution the inbuilt drawing gm does internally is scale the surface to fill the screen
So when you change the resolution of the app surface, it's basically changing the amount of detail\pixels it's able to display, if it's less than the screen res it'll scale it up, if more than, it scales down.
I think the view port shouldn't be changed when the app & gui surface resolution changes cus it'll expand or decrease the area of the level you can see on the screen, so it ends up being similar to just zooming in and out, but also the app surface has less\more pixels on it.
So if you make the resolution smaller, there are less pixels on the app surface, while also displaying less "game pixels"\coordinate units across the screen. And if you make the resolution larger, there are more pixels on the app surface, while also displaying more "game pixels"\coordinate units across the screen. So it's kind of like just expanding the view region and making the amount of pixels displayed match, which defeats the point of changing the resolution.
Anyway, I don't know if that is the heart of the problem, it's just a few things I was thinking when I saw this that might help
The weird thing is that even when changing the amount of pixels of the app, the amount of pixels in the GUI is not changing. After compensating for the scaling of every GUI element with the smaller GUI size, the resolution of all the GUI appears to be exactly the same. It's as if the only thing that changes when adjusting gui_size is the proportion of the X and Y values, and there's no actual way of changing its resolution.

I can literally set my UI size to (10,10) and still get full HD graphics on the GUI layer. Just what's going on here? Have I been misenterpreting the purpose of display_set_gui_size this whole time? Do I need to do something different to actually change UI resolution?
 

Roldy

Member
The weird thing is that even when changing the amount of pixels of the app, the amount of pixels in the GUI is not changing. After compensating for the scaling of every GUI element with the smaller GUI size, the resolution of all the GUI appears to be exactly the same. It's as if the only thing that changes when adjusting gui_size is the proportion of the X and Y values, and there's no actual way of changing its resolution.

I can literally set my UI size to (10,10) and still get full HD graphics on the GUI layer. Just what's going on here? Have I been misenterpreting the purpose of display_set_gui_size this whole time? Do I need to do something different to actually change UI resolution?
Documentation will help you here: https://docs2.yoyogames.com/source/_build/3_scripting/4_gml_reference/cameras and display/display/display_set_gui_size.html

It tells you that this is just a scaling of coordinates. You could essentially set Gui size to (1,1) and use normalized coordinates.

Read the section on the GUI Draw events. The GUI layer draws to the application surface and that will be its resolution. https://docs2.yoyogames.com/source/_build/2_interface/1_editors/events/draw_events.html
 

Joe Ellis

Member
I think this guy just solved it

Darn brain! Why can't you work stuff out as fast as people can read the manual?

I was thinking something along the same lines, I thought resizing the gui layer mainly affects the viewport of it:

AHH! I think I just realized what the functions for resizing the gui surface actually do. They change the view port, the internal directx view port that scales and fits the gui surface onto the window. So we've got no way of really changing the resolution of the gui surface, the resolution is by default always the same as the monitor or window, and changing the size to something different to the window size basically affects how zoomed in or out it is from 1:1 game pixels. So probably it's always best to set gui size to the display_get_width & height(if fullscreen) or window_get_width_height, cus otherwise you'd have to factor in the size, or ratio the gui size is compared to the window size
 
Documentation will help you here: https://docs2.yoyogames.com/source/_build/3_scripting/4_gml_reference/cameras and display/display/display_set_gui_size.html

It tells you that this is just a scaling of coordinates. You could essentially set Gui size to (1,1) and use normalized coordinates.

Read the section on the GUI Draw events. The GUI layer draws to the application surface and that will be its resolution. https://docs2.yoyogames.com/source/_build/2_interface/1_editors/events/draw_events.html
Lol, I should've taken my own oft-given advice of RTFM as well. I was using the Window Resize event to check for the user manually resizing the game window, and it turns out (upon actually reading the manual entry for it) that is not the purpose of window resize. It seems to be related to the "snapping" function that windows has where you can lock the game window to specific areas of the screen. Running a check in the Begin Step Event and comparing a saved value for window_get_width() and window_get_height() to the actual values and then triggering display_set_gui_size() when the check fails fixed up my GUI scaling problems.
 

Khao

Member
I think I get it. What was confusing me about the manual is that it talks about the sizes in "pixels" when you're not changing the amount of pixels in any way, it's literally just to control GUI scaling.

It's just so surprising to me. There really is no way to change GUI resolution? Like actual resolution, not scaling? Is it impossible for your GUI to be a lower resolution than your monitor?

Read the section on the GUI Draw events. The GUI layer draws to the application surface and that will be its resolution. https://docs2.yoyogames.com/source/_build/2_interface/1_editors/events/draw_events.html
That's not what it says though, there's absolutely no mention of resolution in the whole section. The GUI clearly doesn't draw to the application surface, or the result in my screenshot above wouldn't be possible. GUI is drawn after the application surface is already on the screen.

display_gui_set_maximise(1,1,0,0)
Tried this already and the result doesn't change in the slightest. I still get a high-res GUI. To clarify, I have no problems with scaling. I just want the resolution of my GUI to change with the rest of the game, but I guess that's not possible.
 

Roldy

Member
That's not what it says though, there's absolutely no mention of resolution in the whole section. The GUI clearly doesn't draw to the application surface, or the result in my screenshot above wouldn't be possible. GUI is drawn after the application surface is already on the screen.
You just need to think about it more. Maybe re read the section on cameras and views and application surface.

display_set_gui_size is essentially the camera for Draw GUI calls. Understand the relationship between camera and view and you will understand the relationship between display_set_gui_size and application surface.

Here is an example:

If I have a room size of 64 x64, and a camera size at 64x64 and a view at 128x320. How big is the application surface? The answer is 128x320.


  • During the Draw event I draw an 8x8 sprite at (8,8). The application surface will get 16x40 pixels drawn at (16,40).
  • Without changing display_set_gui_size I draw the same 8x8 sprite at (8,8) during Draw GUI. Now the application surface get 8x8 pixels drawn at (8, 8).

We will see two sprites: one at (8,8) that is 8x8 in size and another at (16, 40) that is 16x40 in size. The first small one is the one drawn during Draw GUI. The second large one is the one drawn during Draw.

  • Now we change the display_set_gui_size to (128, 320), and do the same as we did above and draw the same sprite at the same coordinates in the Draw and Draw GUI event.

We will see the exact same thing as the first time. Because the default gui size is the same as the application surface, and we just manually set gui size to the application surface size. So nothing changed.

  • Now we change the display_set_gui_size to (64, 64), and do the same as we did above and draw the same sprite at the same coordinates in the Draw and Draw GUI event.

But now we only see a single sprite drawn (both calls drawn on top each other). It will be 16x40 pixels big and drawn at 16, 16 on the application surface. The Draw and Draw GUI rendered the same thing to the application surface.

  • Now we change the display_set_gui_size to (32, 32), and do the same as we did above and draw the same sprite at the same coordinates in the Draw and Draw GUI event.

We will now again see two sprites: one small and one big. But this time the small one is from Draw event and the big one from Draw GUI.

Read the manual until the above makes sense.


Tried this already and the result doesn't change in the slightest. I still get a high-res GUI. To clarify, I have no problems with scaling. I just want the resolution of my GUI to change with the rest of the game, but I guess that's not possible.
The 'results' will not change resolution. Only coordinates and scaling. Your source art will not change the number of pixels it uses. The application surface will not change size. display_set_gui_size will only change where and how big on the application surface things get drawn during the Draw GUI.

display_set_gui_size is there so you don't have to do the positioning and scaling yourself when drawing to different resolutions and ratios. You can set display_set_gui_size to a fixed size and all GUI draws will be put in the same position and size relative to the application surface resolution.

display_set_gui_size is essentially the camera for Draw GUI calls. Understand the relationship between camera and view and you will understand the relationship between display_set_gui_size and application surface.
 
Last edited:

Khao

Member
I'm genuinely not sure how any of that contradicts what I said. I understand what you're saying and I agree with it. Like I said, I have no problems with scaling. I wanted to change the GUI's actual resolution but now I understand it's not possible.
 
Top