Search code examples
c++windowssdl-2dpirenderer

Why is SDL2 rectangle and line drawing not pixel perfect?


When using SDL2 (2.0.8), drawing a 2D rectangle or a line with SDL_RenderDrawRect or SDL_RenderDrawLine is not pixel perfect. There are some artifacts. Why is that? And is there a way to prevent that?

SDL2 rectangle and line drawing

Code example:

#ifdef WIN32
#include "SDL.h"
#else
#include "SDL2/SDL.h"
#endif

int main(int argc, char* args[])
{
    SDL_Init(SDL_INIT_EVERYTHING);
    SDL_Window*   window = SDL_CreateWindow("test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1000, 800, SDL_WINDOW_RESIZABLE | SDL_WINDOW_SHOWN);
    SDL_Renderer* renderer = SDL_CreateRenderer(window, 0,SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
    SDL_Event event;
    bool quit = false;
    while (!quit)
    {
        SDL_WaitEvent(&event);
        switch (event.type)
        {
            case SDL_QUIT:
            {
                quit = true;
                break;
            }
        }
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        SDL_RenderClear(renderer);
        SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
        SDL_RenderDrawLine(renderer, 40, 10, 60, 10);
        SDL_Rect rect{10, 10, 20, 20};
        SDL_RenderDrawRect(renderer, &rect);
        SDL_RenderPresent(renderer);
    }
    return 0;
}

Environment: Acer Laptop, Intel HD Graphics, NVIDIA GEFORCE 940m, Windows 10


Solution

  • In my Windows 10 display settings "Scale and Layout" was set to "125%". After Setting it to "100%" the rendering was pixel perfect.

    Windows 10 display settings

    Though this is just a workaraound. The real solution is to call the Windows API function "SetProcessDpiAwareness". I found the answer and code to do that on different Windows versions in this link:

    SetProcessDpiAwareness

    There are different methods to set the DPI awareness depending on the Windows OS version. It can be set programmatically or by Application Manifest. See the

    Microsoft docs.

    Setting "Scale and Layout" back to "125%" and calling that function at the begin of my application gives the expected result.