In this lesson we’ll learn how to open a window, create a rendering context and draw an image we’ve loaded to the screen. Grab the BMP we’ll be drawing below and save it somewhere in your project and let’s get started!
To use SDL we first need to initialize the various SDL subsystems we want to use. This is done through
SDL_Init which takes a set of
flags or’d together specifying the subsystems we’d like to initialize.
For now we just need the video subsystem but we’ll add more flags as we require more features. Note that the event
handling system is initialized automatically when the video system is if not explicitly requested by itself while
the file I/O and threading systems are initialized by default.
If everything goes ok
SDL_Init will return 0, if not we’ll want to print out the error and quit.
We’ll need a window to display our render in, we can create one with
SDL_CreateWindow which takes a title for the window,
the x and y position to create it at, the window width and height and some flags to set properties of the window and returns an
SDL_Window*. This pointer will be
NULL if anything went
wrong when creating the window. If an error does occur we need to clean up SDL before exiting the program.
Now we can create a renderer to draw to the window using
SDL_CreateRenderer. This function takes the window to associate the renderer with, the index of the rendering driver
to be used (or -1 to select the first that meets our requirements) and various
flags used to specify what sort of renderer we want.
Here we’re requesting a hardware accelerated renderer with vsync enabled. We’ll get back an
SDL_Renderer* which will be
NULL if something went wrong. If an error does occur we need to clean up anything we’ve previously created and quit
SDL before exiting the program.
To render a BMP image we’ll need to load it into memory and then onto the rendering platform we’re
using (in this case the GPU). We can load the image with
which gives us back a
SDL_Surface* that we can then take and upload to a
SDL_Texture that the renderer is able to use.
SDL_LoadBMP takes the filepath of our image, which you should change to match your project structure, and gives us back
NULL if something went wrong.
With the image loaded we can now upload it to the renderer using
SDL_CreateTextureFromSurface. We pass in the rendering context to upload to and the image in memory (the
and get back the loaded texture, if something went wrong we’ll get back
NULL. We’re also done with the original
surface at this point so we’ll free it now.
All that’s left to do is get our texture on the screen! First we’ll clear
the renderer, then render our texture and then
present the updated screen to show the result. Since
we want to render the whole image and have it stretch to fill the screen we’ll pass
NULL as the source
and destination rectangles for
SDL_RenderCopy. We’ll also
want to keep the window open for a bit so we can see the result before the program exits, so we’ll add in a call
We’ll place all this rendering code within the main loop of our program, which for now will be a simple for loop. Each iteration through our loop we’ll sleep for a second, so we can increase or decrease the counter to make our program run for a longer or shorter period. When we get to event handling we’ll instead track a boolean that indicates if the user wants to quit our program (eg. clicked the X on the window) and exit our loop in that case.
Before we exit we’ve got to destroy all the objects we created through the various
SDL_DestroyX functions and
quit SDL. Error handling note: previously in the program we may have encountered an error and exited early,
in which case we’d have to destroy any SDL objects we had created and quit SDL to properly clean up before exiting.
This part of the error handling is omitted from the lessons since they’re such small examples
and it helps keep the code a bit shorter, but in a real world program
proper error handling and clean up is absolutely required.
If everything went well you should see the image you loaded render over the entire window, wait for 2s and then exit. If you have any problems, make sure you’ve got SDL installed and your project configured properly as discussed in Lesson 0: Setting up SDL, or send an email or tweet. In the postscript I cover an easy way to simplify the cleanup calls behind a variadic template function.
I’ll see you again soon in Lesson 2: Don’t Put Everything in Main.