Creating a Window

Learn how to get started with SDL2 in C++ by creating a window. Includes an explanation of all the SDL2 functions we use, and the options we have to modify the window.
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
aSDL5.jpg
Ryan McCombe
Ryan McCombe
Posted

With SDL2 successfully installed and added to our project, lets start our journey.

The first step is being able to create and manipulate a window. This lesson goes over the steps in how we can do this. We break down and explain every function in the process, as well as describing the most common options.

Let's start by creating a class to manage our window..

Creating the Window Class

Note, this article assumes we've completed the SDL2 setup for our environment. Guides for doing this on most common environments are provided below:

Below, we've created a Window class to manage the window. We'll break down every line of code we're using here, once we see it working:

// Window.h
#pragma once
#include <SDL.h>

class Window {
public:
  Window() {
    SDL_Init(SDL_INIT_VIDEO);

    SDLWindow = SDL_CreateWindow(
      "Hello Window", 0, 0, 500, 300, 0
    );

    SDLWindowSurface = SDL_GetWindowSurface(SDLWindow);

    SDL_FillRect(
      SDLWindowSurface,
      nullptr,
      SDL_MapRGB(SDLWindowSurface->format, 40, 40, 40)
    );
  }

  void RenderFrame() {
    SDL_UpdateWindowSurface(SDLWindow);
  }

private:
  SDL_Window* SDLWindow { nullptr };
  SDL_Surface* SDLWindowSurface { nullptr };
};

Then, from our main.cpp we can include the header file and create our window:

#include <SDL.h>
#include "Window.h"

int main() {
  Window GameWindow;
  SDL_Event event;
  while(true) {
    SDL_PollEvent(&event);
    GameWindow.RenderFrame();
  }
}

Compiling and running this code, we should see our application opens a window which we can move around:

Screenshot of a window on MacOS

Let's break this code down, line by line.

SDL_Init

Our first action is to initialise the SDL subsystems we need, using the SDL_Init command.

SDL_Init(SDL_INIT_VIDEO);

Here, we’re just initializing the video subsystem. Checking the SDL2 documentation, we see that this will also initialize the events subsystem.

The documentation claims we can initialize multiple subsystems by “OR-ing them together”. This refers to the bitwise OR operator, |

An explanation of the | operator, and how this code works more generally, is available here:

So, for example, we could initialize 3 subsystems like this:

SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER);

SDL_Window

Next, we need to create the window, which will have a type provided by SDL: SDL_Window. We store a pointer to it in a private member we’re calling SDLWindow:

SDLWindow = SDL_CreateWindow(
  "Hello Window", 0, 0, 500, 300, 0
);

The SDL_CreateWindow function helps us do this. It accepts 6 arguments:

  • The window title - “Hello Window”
  • The horizontal position of the window - 0, indicating the left-most edge of our screen
  • The vertical position of the window - 0, indicating the top-most edge of our screen
  • The width of the window - 500 pixels
  • The height of the window - 300 pixels
  • “Flags” to modify the behavior of the window

Reviewing the CreateWindow documentation, we see there are some helpers for the position:

  • SDL_WINDOWPOS_CENTERED will automatically center the window along its axis
  • SDL_WINDOWPOS_UNDEFINED will let the operating system choose the best place to open the window. This is a good default, as operating systems have put a lot of thought into what gives the best user experience
SDLWindow = SDL_CreateWindow(
  "Hello Window",
  SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
  500, 300, 0
);

The final argument to SDL_CreateWindow gives us more control over how the window behaves. The documentation provides a list of “flags” that can be used with this argument.

Similarly to before, these flags can be combined using the | operator. For example, we could make our window borderless and resizable like this:

SDLWindow = SDL_CreateWindow(
  "Hello Window",
  SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
  500, 300,
  SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE
);

SDL_Surface

An SDL_Surface is where we draw our content. Later in this chapter, we will create our own surfaces.

However, the window we created come with a surface by default. We can access that surface using the SDL_GetWindowSurface function.

In our class, we’re storing a pointer to it in a private member called SDLWindowSurface so we can draw on it later:

SDLWindowSurface = SDL_GetWindowSurface(Window);

SDL_FillRect

This function fills a rectangle with a solid color. It needs three arguments:

  • A pointer to the surface the rectangle is on
  • A pointer to the rectangle to fill. We’ll create our own. rectangles later - for now, passing a nullptr indicates we want the entire surface to be filled
  • The colour to fill the rectangle with
SDL_FillRect(
  SDLWindowSurface,
  nullptr,
  SDL_MapRGB(SDLWindowSurface->format, 40, 40, 40)
);

Surfaces can have different ways to represent color. The SDL_MapRGB function standardizes this. We can provide the format of the surface, accessible through the surface pointer, and then our three color components: red, green, and blue.

These components are in the 0-255 range. So, for example, if we wanted to make our window background red, we would change our code to this:

SDL_FillRect(
  SDLWindowSurface,
  nullptr,
  SDL_MapRGB(WindowSurface->format, 255, 0, 0)
);
Screenshot of a window with a red background

SDL_UpdateWindowSurface

Once we’ve made all the changes we need to our surface, we are ready to render our next frame. Our class has a public RenderFrame method to do just that.

Within that function, for now, all we need to do is ask SDL to update the window surface with our changes. We aren’t making any changes yet, but we will soon.

To update the window surface, we call SDL_UpdateWindowSurface function, passing in a pointer to our window:

void RenderFrame() {
  SDL_UpdateWindowSurface(SDLWindow);
}

The Render Loop

Finally, our last block of code is over in our main function. It looks like this:

Window GameWindow;
SDL_Event event;
while(true) {
  SDL_PollEvent(&event);
  GameWindow.RenderFrame();
}

Here, we first create our window, calling all the code in our Window constructor.

Then, we have an infinite loop, causing our window to constantly render new frames.

The two new things here are lines 2 and 4, which are dealing with events. We’ll introduce events in the next lesson.

Closing an SDL2 Window

You may have noticed the window doesn’t respond to being closed from the title bar - it remains open.

We’ll fix that in the next lesson, too. For now, if you’re running the code through your IDE, hitting the stop button within your editor will terminate the process and close the window.

Otherwise, you can force your operating system to close it. That can be done using the Ctrl + Alt + Del menu in Windows, or the Opt + Cmd + Esc menu on Mac

Was this lesson useful?

Next Lesson

Implementing an SDL2 Application Loop in C++

Setting solid foundations for our application, by implementing the main loop and the event loop
aSDL6.jpg
Ryan McCombe
Ryan McCombe
Posted
Lesson Contents

Creating a Window

Learn how to get started with SDL2 in C++ by creating a window. Includes an explanation of all the SDL2 functions we use, and the options we have to modify the window.

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
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:

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

Implementing an SDL2 Application Loop in C++

Setting solid foundations for our application, by implementing the main loop and the event loop
aSDL6.jpg
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved