What's the right way to support hidpi?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By bigzaphod

I can’t seem to wrap my head around how to handle high DPI. I mostly live in the Apple ecosystem and everything is high DPI there. My instinct was that if I wanted to make what would be a typical 64x64 sprite, for example, that I should make the actual image for the sprite be 128x128 pixels so everything is effectively designed at 2x - this is what I’d do if I was making a native iOS app, anyway.

I found the “Allow Hidpi” display option which caused the game’s window to become smaller on my macOS screen, so that seemed good. I then figured the right thing to do would be to double my target width and height in the display settings to counter the hidpi setting and then instead of thinking of things in points (like I’m used to for iOS), I’d just think about it directly in the pixels.

That seemed fine until I exported my project for Windows and ran it there. My Windows machine doesn’t have what’d be considered a high DPI display in the Apple world and the window the game opened was way huge and everything was too big and spilled off screen. This isn’t too surprising since the doubled design resolution I specified in Godot is obviously larger than the resolution of the PC’s monitor, but I kind of expected that if you had “Allow Hidpi” turned on that when you were NOT on a Hidpi display, things would be scaled down to compensate for it!

In any case, I’m very confused how I’d make retina assets for the Apple world while having the game scale down on non-retina devices as needed. On iOS and macOS this is handled automatically because you design everything in “points” and on non-retina displays one point is just one pixel, but on higher resolution displays the point-pixel mapping gets multiplied accordingly (usually 2x, but some devices are at 3x now).

My guess is that this is simply not a built in concept in Godot but perhaps I could somehow counteract it with a script that adjusted the scale of… something… based on… something else? Since I’m a super Godot beginner, I don’t know what such a script would look like or if that’s a reasonable way to go or not. Outside of the Apple ecosystem, I have no idea how hidpi is typically handled or even what is considered hidpi so I worry about making stupid assumptions.

I should also note that I’m not working in a pixel art style and have disabled the stretch mode because I wanted bigger screens and windows to reveal more of the game world when possible while keeping the UI consistently sized with controls anchored to the top and bottom of the window. I feel like I’m fighting Godot with all of this which makes me question if I’ve got some stupid notions in my head that are making me miss something obvious.

:bust_in_silhouette: Reply From: Calinou

I should also note that I’m not working in a pixel art style and have disabled the stretch mode because I wanted bigger screens and windows to reveal more of the game world when possible while keeping the UI consistently sized with controls anchored to the top and bottom of the window. I feel like I’m fighting Godot with all of this which makes me question if I’ve got some stupid notions in my head that are making me miss something obvious.

Right now, you absolutely need to use a stretch mode other than disabled to properly support multiple resolutions and hiDPI.

To increase the in-game visible area when the user resizes the window, you can change the camera zoom automatically when the window is resized. There’s a signal you can connect from the root viewport like this: https://github.com/godotengine/godot-demo-projects/blob/3147c6c5bdafce192d5a51e4911bfc7f0043c6d7/viewport/3d_in_2d/3d_in_2d.gd#L18

Add a 2D scale factor property by Calinou · Pull Request #21446 · godotengine/godot · GitHub will make it possible to support hiDPI for non-game applications (where disabled is a better choice than 2d or viewport), but it most likely won’t be merged until 4.0 at least.