This issue is directly related to #837.
When creating a RenderTexture on a HighDPI application:
// Create a RenderTexture2D to be used for render to texture
RenderTexture2D target = LoadRenderTexture(GetScreenWidth(), GetScreenHeight());
GetScreenWidth() and GetScreenHeight() actually return the original screen size requested by the user, despite that everything drawn is scaled to match HighDPI. So, we end up with a RenderTexture smaller than the actual render size.
One possible solution would be to consider the scaleFactor directly on GetScreenWidth() and GetScreenHeight() but if those calls are used in game logic for some maths it will lend to logic errors, because scaling is done automatically only on drawing.
Another solution would be directly exposing the HighDPI scaleFactor and let the user manage everything.
Feedback is welcome!
I love the idea of exposing the DPI to the user. I ran into this issue, and am working off a fork that exposes this info via
float GetWindowDPI(void).
I found it necessary for recreating the render texture when the window is moved to a new monitor with a different DPI or when the window is resized.
Just for reference, glfwGetMonitorContentScale() is the related function.
@raysan5 Im very interested in this feature. I agree with @jozanza . Exposing the dpi seems like a good solution. Im about to do this locally now.
Hmmm. I was going to try and do this, but I'm getting an error. Here is what I have done to try and expose the dpi.
core.c
Vector2 GetWindowDPI(void)
{
#if defined(PLATFORM_DESKTOP)
float xdpi;
float ydpi;
glfwGetMonitorContentScale(CORE.Window.handle, &xdpi, &ydpi);
return (Vector2){ xdpi, ydpi };
#endif
return (Vector2){ 1.0f, 1.0f };
}
And here is the error I get when calling the function from my code.
WARNING: GLFW: Error: 65544 Description: Cocoa: Failed to find a screen for monitor
Any ideas?
@jozanza would you mind sharing your implementation in your fork?
Success! Sorry I figured it out. I was passing the window handle. The glfwGetMonitorContentScale() actually was expecting a monitor pointer.
Heres my final code which is working:
Vector2 GetWindowDPI(void)
{
#if defined(PLATFORM_DESKTOP)
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
if (!monitor)
{
TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor");
return (Vector2){ 1.0f, 1.0f };
}
float xdpi;
float ydpi;
glfwGetMonitorContentScale(monitor, &xdpi, &ydpi);
return (Vector2){ xdpi, ydpi };
#endif
return (Vector2){ 1.0f, 1.0f };
}
I think it is better:
````
Vector2 GetWindowDPI(void)
{
float xdpi = 1.0;
float ydpi = 1.0;
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
if (!monitor)
{
TRACELOG(LOG_WARNING, "GLFW: Failed to get primary monitor");
return (Vector2){ xdpi, ydpi };
}
glfwGetMonitorContentScale(monitor, &xdpi, &ydpi);
return (Vector2){ xdpi, ydpi };
}
````
@ismyhc @Miha-ha Added GetWindowScaleDPI() on commit https://github.com/raysan5/raylib/commit/8e59ecb50c0bbf2e46c7c6cf8deb09a3c31c42e7.
Still need to think about the issue a bit more... but this is a solution for now...
@raysan5 thanks for this! Ive been toying around with both Raylib and SDL2. What I'm trying to accomplish is actually handled in one line in SDL2.
SDL_RenderSetLogicalSize(SDL_Renderer * renderer, int w, int h)
Im not sure how it would translate to Raylib, but below you can see description of the function which explains what Id like to do.
/**
* \brief Set device independent resolution for rendering
*
* \param renderer The renderer for which resolution should be set.
* \param w The width of the logical resolution
* \param h The height of the logical resolution
*
* This function uses the viewport and scaling functionality to allow a fixed logical
* resolution for rendering, regardless of the actual output resolution. If the actual
* output resolution doesn't have the same aspect ratio the output rendering will be
* centered within the output display.
*
* If the output display is a window, mouse events in the window will be filtered
* and scaled so they seem to arrive within the logical resolution.
*
* \note If this function results in scaling or subpixel drawing by the
* rendering backend, it will be handled using the appropriate
* quality hints.
*
* \sa SDL_RenderGetLogicalSize()
* \sa SDL_RenderSetScale()
* \sa SDL_RenderSetViewport()
*/
extern DECLSPEC int SDLCALL SDL_RenderSetLogicalSize(SDL_Renderer * renderer, int w, int h);
@ismyhc it seems similar to example core_window_letterbox
Hey @raysan5.
I had an issue that may be related.
First I turned off the following in libs/raylib/src/core.c:
//#define SUPPORT_HIGH_DPI // Force HighDPI support on macOS
With this removed, I get the following behaviour:
1) App loads and behaves normally
2) Resizing the app leads to the following:
a) Screen image is 1/2 size and positioned in the bottom left corner:

b) Buttons still work as though the screen is full size.
c) Moving the window sets everything back right again!
I fixed this issue by messing with glfw:
In libs/raylib/src/external/glfw/src/cocoa_window.m
I modified windowDidResize(), adding the following two lines from the windowDidMove() function at the end of windowDidResize():
if (window->context.client != GLFW_NO_API)
[window->context.nsgl.object update];
@TakUnderhand Thanks for reporting! I'm afraid behaviour could be dependant of macOS version as well as retina display... but, in any case, your solution points to GLFW library, maybe that issue could also be asked on their repo to make it available for all the users.
Also, note that current GLFW version used in raylib is about 4 month old, maybe something changed on GLFW side on that time.
Thanks :)
I took GLFW 3.3.2 from their repo, combined it into Raylib, just to see if that latest version would have any fix for this issue. (It didn't).
If I get chance, I'll put a simple test case together, to raise an issue on the GLFW team.
@TakUnderhand Thank you very much for your time an effort! This issue has been open for some time, it would be great to find a proper fix! :)
Not sure how helpful this is, but I wrote a hack to allow me to drag a window between monitors that "mostly" works:
https://gist.github.com/mattj1/606a94527badb6ffa7d22245c9b745b1
(I'm on a Mac, btw)
Note: GLFW is required, and you have to specify your viewport size to rlViewport.
hi @mattj1! Thank you very much for the git! I'm reviewing it!
Most helpful comment
@ismyhc @Miha-ha Added
GetWindowScaleDPI()on commit https://github.com/raysan5/raylib/commit/8e59ecb50c0bbf2e46c7c6cf8deb09a3c31c42e7.Still need to think about the issue a bit more... but this is a solution for now...