Handling High DPI Displays in SDL2

What's the best approach for handling high DPI displays with SDL2?

Handling high DPI (HiDPI) displays in SDL2 is crucial for ensuring your game looks crisp on modern screens. SDL2 provides built-in support for HiDPI, but you need to set it up correctly. Here's a comprehensive approach:

Enable HiDPI Support

First, enable HiDPI support when creating your window:

#include <SDL.h>

#include <iostream>

int main() {
  SDL_Init(SDL_INIT_VIDEO);

  // Enable HiDPI support
  SDL_SetHint(
    SDL_HINT_VIDEO_HIGHDPI_DISABLED, "0");

  SDL_Window* window = SDL_CreateWindow(
    "HiDPI Game", SDL_WINDOWPOS_UNDEFINED,
    SDL_WINDOWPOS_UNDEFINED, 800, 600,
    SDL_WINDOW_ALLOW_HIGHDPI |
    SDL_WINDOW_RESIZABLE);

  if (!window) {
    std::cout << "Failed to create window: " <<
      SDL_GetError() << "\n";
    return 1;
  }

  SDL_Renderer* renderer = SDL_CreateRenderer(
    window, -1,
    SDL_RENDERER_ACCELERATED |
    SDL_RENDERER_PRESENTVSYNC);

  if (!renderer) {
    std::cout << "Failed to create renderer: "
      << SDL_GetError() << "\n";
    return 1;
  }

  // Rest of the code...

  SDL_DestroyRenderer(renderer);
  SDL_DestroyWindow(window);
  SDL_Quit();
  return 0;
}

Get the Correct Window Size

The window size reported by SDL might not match the actual pixel size on HiDPI displays. Use SDL_GetRendererOutputSize() to get the true pixel size:

int windowWidth, windowHeight,
  renderWidth, renderHeight;
SDL_GetWindowSize(
  window, &windowWidth, &windowHeight);
SDL_GetRendererOutputSize(
  renderer, &renderWidth, &renderHeight);

float scaleX = renderWidth
  / static_cast<float>(windowWidth);
float scaleY = renderHeight
  / static_cast<float>(windowHeight);

std::cout << "Window size: " << windowWidth
  << "x" << windowHeight << "\n";
std::cout << "Render size: " << renderWidth
  << "x" << renderHeight << "\n";
std::cout << "Scale factor: " << scaleX
  << "x" << scaleY << "\n";

Scale Your Rendering

Use the scale factor when rendering:

SDL_Rect GetScaledRect(int x, int y, int w,
                       int h, float scaleX,
                       float scaleY) {
  return SDL_Rect{
    static_cast<int>(x * scaleX),
    static_cast<int>(y * scaleY),
    static_cast<int>(w * scaleX),
    static_cast<int>(h * scaleY)};
}

// In your render loop:
SDL_Rect rect = GetScaledRect(
  100, 100, 200, 200, scaleX, scaleY);
SDL_RenderFillRect(renderer, &rect);

Handle Input

Mouse input coordinates are already adjusted by SDL2, but you might need to scale other input values:

int mouseX, mouseY;
SDL_GetMouseState(&mouseX, &mouseY);
float gameX = mouseX / scaleX;
float gameY = mouseY / scaleY;

Load HiDPI Assets

For the best visual quality, provide high-resolution versions of your assets and scale them down as needed:

SDL_Surface* LoadScaledSurface(
  const char* path, float scale) {
  SDL_Surface* original = SDL_LoadBMP(path);
  if (!original) return nullptr;

  int newWidth = static_cast<int>(original->w *
    scale);
  int newHeight = static_cast<int>(original->h *
    scale);

  SDL_Surface* scaled =
    SDL_CreateRGBSurface(0, newWidth, newHeight,
                         32, 0, 0, 0, 0);

  SDL_BlitScaled(original, nullptr, scaled,
                 nullptr);
  SDL_FreeSurface(original);

  return scaled;
}

By following these steps, your SDL2 game will look great on both standard and HiDPI displays, providing a consistent experience across different screen resolutions.

Image Scaling and Aspect Ratios

Learn techniques for scaling images and working with aspect ratios

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Handling Different Screen Resolutions in SDL2
What's the best way to handle different screen resolutions in my SDL2 game?
Efficiently Rendering Multiple Scaled Images
What's the most efficient way to render multiple scaled images in a single frame?
Implementing a Zoom Feature in SDL2
How can I implement a zoom feature using these scaling techniques?
Optimizing Performance with Scaled Images
How can I optimize performance when working with many scaled images simultaneously?
Preserving Aspect Ratio in Fullscreen Mode
What's the best way to handle aspect ratio preservation for fullscreen modes?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant