Image Scaling and Aspect Ratios

Preserving Aspect Ratio in Fullscreen Mode

What's the best way to handle aspect ratio preservation for fullscreen modes?

Abstract art representing computer programming

Preserving aspect ratio in fullscreen mode is crucial for maintaining the visual integrity of your game across different screen sizes. Here's a comprehensive approach to handle this in SDL2:

Calculate the Aspect Ratio

First, determine the aspect ratio of your game's native resolution:

const int GAME_WIDTH = 1280;
const int GAME_HEIGHT = 720;
const float GAME_ASPECT_RATIO = GAME_WIDTH /
  static_cast<float>(GAME_HEIGHT);

Create a Fullscreen Window

Create a borderless fullscreen window that covers the entire screen:

SDL_Window* window = SDL_CreateWindow(
  "Fullscreen Game", SDL_WINDOWPOS_UNDEFINED,
  SDL_WINDOWPOS_UNDEFINED, 0, 0,
  SDL_WINDOW_FULLSCREEN_DESKTOP);

Calculate Scaling Factors

Determine the scaling factors to fit the game resolution into the screen while preserving aspect ratio:

int screenWidth, screenHeight;
SDL_GetWindowSize(window, &screenWidth,
                  &screenHeight);

float scaleX = screenWidth / static_cast<float>(
  GAME_WIDTH);
float scaleY = screenHeight / static_cast<float>
  (GAME_HEIGHT);
float scale = std::min(scaleX, scaleY);

int scaledWidth = static_cast<int>(GAME_WIDTH *
  scale);
int scaledHeight = static_cast<int>(GAME_HEIGHT
  * scale);

Calculate Letterbox or Pillarbox Dimensions

Determine the size and position of black bars to maintain aspect ratio:

int xOffset = (screenWidth - scaledWidth) / 2;
int yOffset = (screenHeight - scaledHeight) / 2;

SDL_Rect gameViewport = {
  xOffset, yOffset, scaledWidth, scaledHeight};

Set Up Rendering

Create a renderer and set the viewport:

SDL_Renderer* renderer =
  SDL_CreateRenderer(window, -1,
                     SDL_RENDERER_ACCELERATED);
SDL_RenderSetViewport(renderer, &gameViewport);

// Clear the entire screen (including
// letterbox/pillarbox areas)
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear (renderer);

Render Your Game

Render your game content within the viewport:

void RenderGame(SDL_Renderer* renderer) {
  // Clear only the game area
  SDL_SetRenderDrawColor(renderer, 50, 50, 50,
                         255);
  SDL_Rect fullViewport = {
    0, 0, GAME_WIDTH, GAME_HEIGHT};
  SDL_RenderFillRect(renderer, &fullViewport);

  // Render game content here
  SDL_SetRenderDrawColor(renderer, 255, 0, 0,
                         255);
  SDL_Rect rect = {100, 100, 200, 200};
  SDL_RenderFillRect(renderer, &rect);

  SDL_RenderPresent(renderer);
}

Handle Window Resize Events

Recalculate the viewport when the window is resized:

void HandleWindowResize(SDL_Window* window,
                        SDL_Renderer*
                        renderer) {
  int screenWidth, screenHeight;
  SDL_GetWindowSize(window, &screenWidth,
                    &screenHeight);

  float scaleX = screenWidth / static_cast<
    float>(GAME_WIDTH);
  float scaleY = screenHeight / static_cast<
    float>(GAME_HEIGHT);
  float scale = std::min(scaleX, scaleY);

  int scaledWidth = static_cast<int>(GAME_WIDTH
    * scale);
  int scaledHeight = static_cast<int>(
    GAME_HEIGHT * scale);
  int xOffset = (screenWidth - scaledWidth) / 2;
  int yOffset = (screenHeight - scaledHeight) /
    2;

  SDL_Rect gameViewport = {
    xOffset, yOffset, scaledWidth,
    scaledHeight};

  SDL_RenderSetViewport(renderer,
                        &gameViewport);
}
// In your event loop:
SDL_Event event;
while (SDL_PollEvent(&event)) {
  if (event.type == SDL_WINDOWEVENT &&
      event.window.event ==
        SDL_WINDOWEVENT_RESIZED) {
    HandleWindowResize(window, renderer);
  }
  // Handle other events...
}

By implementing this approach, your game will maintain its aspect ratio in fullscreen mode across different screen sizes. The game content will be scaled to fit the screen as large as possible while preserving its original proportions, and black bars (letterboxing or pillarboxing) will be added as needed to fill the remaining space.

This method ensures that your game looks consistent and visually appealing regardless of the display's aspect ratio, providing a professional fullscreen experience for your players.

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:

  • 62 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