Fullscreen Windows

Learn how to create and manage fullscreen windows in SDL, including desktop and exclusive fullscreen modes.
This lesson is 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
Abstract art representing computer programming
Ryan McCombe
Ryan McCombe
Posted

In this lesson, we'll explore SDL's window management features, learning how to implement both desktop and exclusive fullscreen modes. We’ll cover:

  • Creating borderless fullscreen windows that cover the entire screen using SDL_WINDOW_FULLSCREEN_DESKTOP
  • Using exclusive fullscreen mode, which changes display settings for optimal performance using SDL_WINDOW_FULLSCREEN
  • Using SDL_SetWindowFullscreen() lets you change modes at runtime
  • Best practices and error handling

Desktop Fullscreen

The easiest way of creating a fullscreen experience is to simply render our game in a borderless window that has the same position and dimensions as the monitor’s display bounds.

SDL provides us with a quick way to set this up, which we’ll cover later in this lesson. However, we could achieve something similar by passing the display index to SDL_GetDisplayBounds(), and then creating a borderless window with the same position and size:

// Get size and position of display with index 0
SDL_Rect Bounds;
SDL_GetDisplayBounds(0, &Bounds);

SDL_Window* Window{SDL_CreateWindow(
  "Window",
  Bounds.x, Bounds.y, // Position 
  Bounds.w, Bounds.h, // Size 
  SDL_WINDOW_BORDERLESS 
)};

This technique is sometimes referred to as windowed fullscreen, desktop fullscreen, or borderless fullscreen. With this technique, our game is just another window, which makes multi-tasking easier. It provides a solid user experience when the player is switching between our game and other windows.

However, there are two problems:

  • We may want to render our game at a different resolution than what the monitor is currently using
  • The way our game represents colors may be different to what the monitor is currently using

SDL automatically handles both of these problems by rescaling each frame to match the display resolution and reformatting it to match the monitor's color requirements.

However, this additional rescaling and reformatting step means each frame takes slightly longer to complete. So, whilst windows fullscreen provides a smooth experience when multitasking, we pay for it by our game possibly running slightly slower.

Exclusive Fullscreen

Instead of having our frames rescaled and reformatted to meet the monitor’s requirements, we could instead update the monitor’s settings to match what our game is outputting.

This allows each frame to be displayed directly on the display. This technique is often called exclusive fullscreen or simply fullscreen, and it eliminates the performance overhead of windowed fullscreen.

However, changing the display mode of a typical monitor takes a few seconds, during which time the monitor is typically unusable. This makes switching to other windows more frustrating for users, as it takes a few seconds to update their display settings. We cover these display modes in detail in the next lesson.

Most games allow players to configure whether they’d prefer the game run in a window, windowed fullscreen or exclusive fullscreen:

Screenshot of the Dishonored 2 options menu
Screenshot of the Dishonored 2 options menu

When we know which mode they want to use, we can create or update our window to use that preference.

Creating Fullscreen Windows

We can create an exclusive or fullscreen window by passing the appropriate flag to the SDL_CreateWindow() function.

SDL_WINDOW_FULLSCREEN_DESKTOP

SDL uses the SDL_WINDOW_FULLSCREEN_DESKTOP flag to configure desktop fullscreen windows:

SDL_Window* Window{SDL_CreateWindow(
  "Window",
  SDL_WINDOWPOS_UNDEFINED,
  SDL_WINDOWPOS_UNDEFINED,
  1920, 1080,
  SDL_WINDOW_FULLSCREEN_DESKTOP
)};

int x, y;
SDL_GetWindowSize(Window, &x, &y);
std::cout << "Size: " << x << 'x' << y;
Size: 2560x1440

The window size we specify for a fullscreen desktop window can still be relevant. For example, if we update our window to no longer be fullscreen, it will adopt the size we specified - 1920x1080 in this example. We cover how to change the fullscreen status of a window later in this lesson.

SDL_WINDOW_FULLSCREEN

Exclusive fullscreen windows are configured using the SDL_WINDOW_FULLSCREEN flag:

SDL_Window* Window{SDL_CreateWindow(
  "Window",
  SDL_WINDOWPOS_UNDEFINED,
  SDL_WINDOWPOS_UNDEFINED,
  1920, 1080,
  SDL_WINDOW_FULLSCREEN
)};

int x, y;
SDL_GetWindowSize(Window, &x, &y);
std::cout << "Size: " << x << 'x' << y;
Size: 1920x1080

With an exclusive fullscreen window, the display the window is created on will be updated to adopt the resolution that matches our window size - 1920x1080 in this example.

If we disable fullscreen mode for this window, our display will revert to its original mode, and we will have a regular 1920x1080 window on that display. We cover display modes in detail in the next lesson.

Changing Fullscreen Mode

We can update the fullscreen mode of an existing window using the SDL_SetWindowFullscreen() function. We pass the SDL_Window pointer as the first argument, and the desired window flag as the second argument. Our options are:

  • SDL_WINDOW_FULLSCREEN_DESKTOP: Set the window to be desktop fullscreen
  • SDL_WINDOW_FULLSCREEN: Set the window to be exclusive fullscreen
  • 0: Disable fullscreen mode for this window

Here’s an example:

SDL_Window* Window{SDL_CreateWindow(
  "Window",
  SDL_WINDOWPOS_UNDEFINED,
  SDL_WINDOWPOS_UNDEFINED,
  1920, 1080,
  0 // Not fullscreen
)};

// Set window to be desktop fullscreen
SDL_SetWindowFullscreen(Window,
  SDL_WINDOW_FULLSCREEN_DESKTOP);
  
// Set window to be exclusive fullscreen
SDL_SetWindowFullscreen(Window,
  SDL_WINDOW_FULLSCREEN);

// Disable fullscreen
SDL_SetWindowFullscreen(Window, 0);

Error Handling

The SDL_SetWindowFullscreen() function returns 0 if it was successful, or a negative error code otherwise. We can call SDL_GetError() to retrieve the error message:

if (SDL_SetWindowFullscreen(nullptr, 0) < 0) {
  std::cout << "Error changing fullscreen "
               "mode: " << SDL_GetError();
}
Error changing fullscreen mode: Invalid window

Getting Fullscreen Mode

We can check a window's current fullscreen state using SDL_GetWindowFlags(). This function returns a bit field containing all the window's current flags. To check for fullscreen modes, we examine specific bits using bitwise operations. The bitwise AND operator (&) lets us check if specific flags are set:

SDL_Window* Window{SDL_CreateWindow(
  "Window",
  SDL_WINDOWPOS_UNDEFINED,
  SDL_WINDOWPOS_UNDEFINED,
  1920, 1080,
  SDL_WINDOW_FULLSCREEN_DESKTOP
)};

Uint32 Flags{SDL_GetWindowFlags(Window)};

if (Flags & SDL_WINDOW_FULLSCREEN_DESKTOP) {
  std::cout << "Desktop fullscreen";
} else if (Flags & SDL_WINDOW_FULLSCREEN) {
  std::cout << "Exclusive fullscreen";
} else {
  std::cout << "Not fullscreen";
}
Desktop fullscreen

Note that the SDL_WINDOW_FULLSCREEN is set if our window is running in either exclusive or desktop fullscreen. As such, the order of our if statements in the previous example is important - specifically the decision to check SDL_WINDOW_FULLSCREEN_DESKTOP before SDL_WINDOW_FULLSCREEN. In other words:

  • in desktop fullscreen mode, both SDL_WINDOW_FULLSCREEN and SDL_WINDOW_FULLSCREEN_DESKTOP are set.
  • in exclusive fullscreen mode, SDL_WINDOW_FULLSCREEN is set but SDL_WINDOW_FULLSCREEN_DESKTOP is not set.

Summary

In this lesson, we've learned how to implement fullscreen functionality using SDL. We covered both desktop and exclusive fullscreen modes, understanding their benefits and tradeoffs. Key takeaways:

  • Use SDL_GetDisplayBounds() to match monitor dimensions
  • Use desktop fullscreen - SDL_WINDOW_FULLSCREEN_DESKTOP - for easier multitasking
  • Exclusive fullscreen - SDL_WINDOW_FULLSCREEN - may provide better performance
  • SDL_SetWindowFullscreen() enables runtime mode changes
  • Check window flags to determine current mode
  • We can test and validate window operations with error checking

Was this lesson useful?

Next Lesson

Display Modes

Learn how to manage screen resolutions and refresh rates in SDL games using display modes.
Abstract art representing computer programming
Ryan McCombe
Ryan McCombe
Posted
Lesson Contents

Fullscreen Windows

Learn how to create and manage fullscreen windows in SDL, including desktop and exclusive fullscreen modes.

sdl2-promo.jpg
This lesson is 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
Monitors and Display Modes
sdl2-promo.jpg
This lesson is 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:

  • 71 Lessons
  • 100+ Code Samples
  • 91% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Next Lesson

Display Modes

Learn how to manage screen resolutions and refresh rates in SDL games using display modes.
Abstract art representing computer programming
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved