grimfang4 / sdl-gpu

A library for high-performance, modern 2D graphics with SDL written in C.
MIT License
1.18k stars 123 forks source link

Resolution issues in SDL_WINDOW_FULLSCREEN with HIDPI and touch handling #67

Open ephemer opened 7 years ago

ephemer commented 7 years ago

Hi, I'm trying to get some code working with SDL_gpu and SDL2 on both Retina Macs and high DPI Android devices (e.g. Galaxy S7) in SDL_WINDOW_FULLSCREEN.

The Android device seems to report its screen dimensions from SDL_GetDisplayMode (but also the GPU_Target returned by GPU_Init's .base_w / .base_h) in actual pixels, whereas the Mac reports it in (retina-scaled) points. This means dimensions I provide to GPU_Init end up being wrong on one device or the other. I've been going around in circles for days: either my touch handling is wrong (all hits are boxed into one corner) or the display scale is wrong (display boxed into the corner but touch handling correct etc.) on one of the platforms.

I've all sorts of things to get around this, like manually changing .w and .h of the GPU_Target provided by GPU_Init, getting the SDL_DisplayMode dimensions after init and calling GPU_SetVirtualResolution to them, trying various manual mathematical acrobatics. GPU_GetVirtualCoords doesn't seem to do anything on the Android device and seems to give me the wrong coordinates on the Mac (which doesn't seem to need any adjustments to pixel coordinates in HIDPI by default). In any case, if I fix it on one, it's broken again on the other.

It seems like SDL_GL_GetDrawableSize and comparing it to the SDL_DisplayMode dimensions would be the way of finding out the real scale factor of the pixels, at which point I could adjust the scale of things manually. That function only seems to work with an SDL_Window though, which isn't available after starting SDL with GPU_Init (or is it?).

I couldn't see any clear way of doing this in the docs, can you recommend a way forward? I was considering doing an OS check for Android and implementing different logic there, but it seems risky, because I couldn't be sure that all devices behave in the same way. I'd much rather get a real content scale factor if it's possible!

grimfang4 commented 7 years ago

SDL_gpu does use SDL_GL_GetDrawableSize to try to avoid the HIDPI issue, so it sounds like it's just not doing it right. If I get some time, I'll try to look into it on a retina device.

You can get the windowID from the screen target: screen->context->windowID and use SDL_GetWindowFromID() to get the SDL_Window. Maybe you can get further with that for now?

ephemer commented 7 years ago

@grimfang4 thanks for the tip about context->windowID, I have just hacked this for now with OS-dependent conditions but will probably have another look at it soon