Search code examples
c++macossdlhidpi

game displayed in the bottom-left quarter of my screen in SDL2


I recently updated my mac and the code that was normally running stopped functioning. When I now run my program (a game) the window still has the right dimensions but the elements are displayed in the bottom-left quarter of my screen.

what I see

I don't understand where it comes from.

here is the .cpp that I used in the exemple:

#include "../../include/game.h"

int     main(int argc, char **argv)
{
    SDL_Window      *window;
    SDL_Renderer    *render;
    int             w;
    int             h;

    (void)argc;
    (void)argv;

    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
    window = SDL_CreateWindow("lul", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_W, WINDOW_H, 0);
    render = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    SDL_GetWindowSize(window, &w, &h);

    SDL_Surface     *surface;
    SDL_Texture     *texture;

    surface = IMG_Load("FondHome2.jpg");
    texture = SDL_CreateTextureFromSurface(render, surface);

    SDL_Event   event;
    bool        close_requested = false;

    while (!close_requested)
    {
        while (SDL_PollEvent(&event))
        {
            if (event.type == SDL_QUIT)
            {
                close_requested = true;
            }
        }
        SDL_RenderCopy(render, texture, NULL, NULL);
        SDL_RenderPresent(render);
    }

    return(0);
}

and here is the .h used:

#ifndef GAME_H
# define GAME_H

# include <SDL2/SDL.h>
# include <SDL2/SDL_timer.h>
# include <SDL2/SDL_image.h>
# include <SDL2/SDL_ttf.h>

# include <fstream>
# include <iostream>
# include <string>
# include <vector>
# include <stdarg.h>
# include <math.h>

# define WINDOW_W 400
# define WINDOW_H 300

#endif

Solution

  • See content related to High-DPI differences when working with Retina displays on Mac: SDL_GL_GetDrawableSize. Pass the SDL_WINDOW_ALLOW_HIGHDPI flag to SDL_CreateWindow, and the SDL_Render API should do the right thing.

    The problem is that without high DPI enabled, the actual width and height of your SDL_Window correspond to more pixels than you passed to SDL_CreateWindow (2X width and height, in this case). It seems like SDL_RenderCopy still thinks the target framebuffer is 400x300, which is correct when the DPI scaling factor is 1. When the image is drawn, only 1/4 of the physical space is covered.

    I can't tell you exactly where the scaling issue happens without reading the SDL2 source, since it could be happening with an internal framebuffer or during the final blit, but the issue is the assumption of a DPI scaling factor of 1. Passing the SDL_WINDOW_ALLOW_HIGHDPI flag during window creation tells SDL to query the actual monitor DPI to be used.

    Related issue: SDL 2.0 retina mac