I have a little confusion around this old topic.
So, this recent fix says that
screen coordinates are
virtual ones that are gotten by scaling pixels by some factor. Where can I find this factor and how do I take it into account?
For example, when I do a call to
SDL_CreateWindow, I supply it with
screen coordinates. I can, say, first query the display’s width and height with
SDL_GetDisplayMode and then get a window for a half of the screen.
But when I get a
SDL_Renderer, does it bare its dimensions in pixels or
screen coordinates? Docs for
SDL_GetRendererOutputSize does not specify it, but
SDL_GetWindowSize references a renderer’s size in pixels. So to be sure I’m on a safe side I need to get
wherewhere-im-rendering-into’s size in pixels, even if I’m rendering into a window? For example, vertices’ coordinates for
SDL_RenderGeometry are in pixels?
Renderer coordinates was renamed to points due to confusion with pixels, as said in the patch message.
SDL_GetWindowSize will query the window size, not the renderer surface size. In most cases this size will match your renderer surface (but if
SDL_WINDOW_ALLOW_HIGHDPI was passed as window flag, your window size will be recalculated with the display scale rate in mind).
SDL_GetRendererOutputSize will always query the renderer surface size in pixels.
SDL_GetWindowSizeInPixels is the same as
SDL_GetRendererOutputSize but for legacy reasons (when you render without
In fullscreen mode everything is more simple, your output size is always the size you requested (unless you use
The virtual thing is simple. You can set arbitrary resolution with
SDL_RenderSetLogicalSize and the coordinates you pass to render functions will be recalculated. For example, you have a
512x512px window, and in the most cases you will end up with
512x512px renderer surface. In this case coordinates will match with the pixel positions for your window, but if you used
SDL_RenderSetLogicalSize on your renderer with new size
256x256 (for example), the renderer now will recalculate all coordinates with scale factor
2 for both
y, but the output size (which you see on the screen) will be same as before. The point
32x32 will become
64x64, and all rendering functions will draw on
256x256 area, but you will see it as scaled to
You don’t need to do such thing, SDL handle it behind the scenes.
They are coordinates, that can match pixels. Or not. Read previous part carefully .
Simple rules of thumb that I use at my own (use one or more):
SDL_RenderSetLogicalSize (fix the sizes for different display ratio), good for the pixel games or static resolution rendering.
If your game has static ratio/resolution add fullscreen mode with centered playzone (so it will not look stretched on wide displays), and allow user to resize window in windowed mode.
Do not use
SDL_WINDOW_ALLOW_HIGHDPI unless it’s a UI program.
Calculate all offsets, sizes, positions based on current resolution (probably the best way, but can be hard to implement).
Implement GUI/HUD scaling for your game, everyone will like it.
Long story short: you will get what you requested from SDL.
If you not requesting anything but the simple window with static size, you will get it. All consequences you might face you will get from your requests, like a scaled rendering, resizable windows and dpi-awareness.
One more thing about the virtual coordinates: In SDL you can use points with negative coordinates and points that are located out of render area bounds.
That’s completely safe and very handy, for example having renderer area
512x512 and calling
SDL_RenderCopy with some
512x512 texture, with
0, will end up with only a right half of the texture rendered at position
0x0, no need to calculate src/dst rects by yourself.
Hello-hello again, thank you for the detailed answer!
renderer coordinates and
screen coordinates are all the same?
But what about this then? Pixels are not render coordinates?
Yeah, that is pretty neat! Alleviates lots of headache for sure)
They can match, but they are the different things.
It’s about the size, not about positions. If you use scaling, then coordinates will not match the real pixels.
Like i said before, things can act same but it does not make them the same thing.