[SDL2] How screen coordinates are computed exactly?

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 SDL_Renderer).

In fullscreen mode everything is more simple, your output size is always the size you requested (unless you use SDL_WINDOW_FULLSCREEN_DESKTOP with SDL_WINDOW_ALLOW_HIGHDPI).

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 x and 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 512x512.


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 :grin:.

Simple rules of thumb that I use at my own (use one or more):

  • Use 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.

1 Like

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.

1 Like

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 dstrect x=-256 y=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.

1 Like

Hello-hello again, thank you for the detailed answer!

Wait, so 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.