Image Scaling and Aspect Ratios

Handling High DPI Displays in SDL2

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

Abstract art representing computer programming

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.

This Question is from the Lesson:

Image Scaling and Aspect Ratios

Learn techniques for scaling images and working with aspect ratios

Answers to questions are automatically generated and may not have been reviewed.

This Question is from the Lesson:

Image Scaling and Aspect Ratios

Learn techniques for scaling images and working with aspect ratios

sdl2-promo.jpg
Part of the course:

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Free, unlimited access

This course includes:

  • 53 Lessons
  • 100+ Code Samples
  • 91% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved