Open KingofBeast opened 6 years ago
Please!
Can't you use this? http://wiki.garrysmod.com/page/Global/ScreenScale
No
That only scales based on resolution, not pixel density
Ah, you're right.
Any news on this? Would be great.
Bump
Wrote this proof-of-concept function that correctly retrieves DPI in Windows with the help of SDL. GMod already uses SDL, so it shouldn't be a huge problem to implement it. The function is also cross-compatible.
The issue of using SDL_GetDisplayDPI
by itself is that it returns logical DPI on Windows, which is defined by Windows and not the monitor hardware.
Instead of using the function, you can also modify the SDL library itself and change MDT_EFFECTIVE_DPI
to MDT_RAW_DPI
, which would make the SDL_GetDisplayDPI
work properly on Windows.
I have tested SDL_GetDisplayDPI
on Linux and it seemed to work properly. I haven't tested this on Mac though.
float GetWindowDisplayDPI(SDL_Window* window) {
#ifdef _WIN32
typedef enum MONITOR_DPI_TYPE {
MDT_EFFECTIVE_DPI = 0,
MDT_ANGULAR_DPI = 1,
MDT_RAW_DPI = 2,
MDT_DEFAULT = MDT_EFFECTIVE_DPI
} MONITOR_DPI_TYPE;
static HRESULT(WINAPI * GetDpiForMonitor)(HMONITOR hmonitor,
MONITOR_DPI_TYPE dpiType,
UINT * dpiX,
UINT * dpiY) = 0;
static int initialized = 0;
if (!initialized) {
void* shcoreDLL = SDL_LoadObject("SHCORE.DLL");
if (shcoreDLL) {
GetDpiForMonitor = (HRESULT(WINAPI*)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*)) SDL_LoadFunction(shcoreDLL, "GetDpiForMonitor");
}
else {
SDL_ClearError();
}
initialized = 1;
}
float dpi = 0;
if (GetDpiForMonitor != NULL) {
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
SDL_GetWindowWMInfo(window, &info);
HMONITOR hmonitor = MonitorFromWindow(info.info.win.window, MONITOR_DEFAULTTONEAREST);
UINT dpiX, dpiY;
GetDpiForMonitor(hmonitor, MDT_RAW_DPI, &dpiX, &dpiY);
dpi = (float)dpiX;
} else {
SDL_GetDisplayDPI(SDL_GetWindowDisplayIndex(window), NULL, &dpi, NULL);
}
return dpi;
#else
float dpi = 0;
SDL_GetDisplayDPI(SDL_GetWindowDisplayIndex(window), NULL, &dpi, NULL);
return dpi;
#endif
}
Wrote this proof-of-concept function that correctly retrieves DPI in Windows with the help of SDL. GMod already uses SDL, so it shouldn't be a huge problem to implement it. The function is also cross-compatible. ...
That's effective, and quality code. Make sure you "unload" the pointer shcoreDLL
though. Use SDL_UnloadObject
Could definitely be of use. Great work @h3xcat !
Implementing it should be simple.
Make sure you "unload" the pointer shcoreDLL though. Use SDL_UnloadObject
I'm not sure how I would achieve that within the function without reloading the library during each call, probably it's better to handle library loading and unloading outside the function in that case.
Make sure you "unload" the pointer shcoreDLL though. Use SDL_UnloadObject
I'm not sure how I would achieve that within the function without reloading the library during each call, probably it's better to handle library loading and unloading outside the function in that case.
That could work. Or make it a const static void
pointer then unload it at the end. So it retains its value each time its called.
As the number of users with high DPI monitors rises, more and more players will be met with HUDs and UIs that don't fit their screens well. Being able to determine logical pixel density for players will allow developers to intelligently scale menus, fonts, and the like to appropriately present them.