SDL 2.0 Lesson Cycle: Lesson 1

Original author: Twinklebear

From a translator: inspired by a series of articles , I decided to try my hand at SDL. Yes, that's bad luck, I could not find any sensible lessons on SDL version 2.0 in Russian. This prompted me to translate the wonderful series of Twinklebear tutorials in the original available here .

Welcome!

The purpose of these lessons is to introduce you to the basics of SDL 2.0 and the C ++ game maiden. It is understood that the reader has some C ++ programming experience and minimal knowledge of arrays, vectors, control structures, functions, and pointers.

If you are having difficulty parsing the code in the examples, use one of the books on this wonderful list on StackOverflow .

If you want to see the full source or download resources for lessons, then all this can be obtained on GitHub . But do not copy!

SDL 2.0 documentation is also available for reading on this wiki .

Lesson 1: Hello World!


In this tutorial, we will learn how to open a window, create a rendering context, and draw a loaded image on the screen. Below you can pick up a BMP picture that we will draw. Save it somewhere in your project. So let's get started!

image

SDL launch

The first step is usually to include the SDL header file.

#include 

In order to start working with SDL, we need to initialize the various SDL subsystems that we want to use. This can be done using the SDL_Init function , which accepts a set of flags indicating which subsystem we want to initialize. Now we just say that we want to initialize everything, but if you want, you can change this. The minimum that is needed for our lesson is SDL_INIT_VIDEO. If everything goes well, SDL_Init will return 0, otherwise we will print an error and exit.

Note for Visual Studio users: if you set the system value as Windows in the linker settings, then you will not get standard output to the console. To prevent this from happening, you need to change the system value to Console.

if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
	std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
	return 1;
}

Window opening

We need a window so that we can display it on a render. We can create it using the SDL_CreateWindow function , which takes the name of the window, its coordinates, height, width and some flags to set window parameters. This function returns SDL_Window *. This pointer will be NULL if something goes wrong when creating the window.

SDL_Window *win = SDL_CreateWindow("Hello World!", 100, 100, 640, 480, SDL_WINDOW_SHOWN);
if (win == nullptr){
	std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
	return 1;
}

Renderer Creation

Now we can create a renderer using SDL_CreateRenderer . This is necessary in order to be able to draw in the window. This function accepts a pointer to the window with which the renderer must be associated, the driver index that will be used for rendering (or -1 to select the first one that suits our requirements) and various flags used to indicate the type of renderer that we need. In this case, we request a renderer with hardware acceleration and enabled vertical synchronization. We will get SDL_Renderer *, which will be NULL if something went wrong.

SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (ren == nullptr){
	std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
	return 1;
}

BMP image upload

In order to render a BMP image, we first need to load it into memory, and then into the rendering device that we use (in this case, the GPU). We can load the image using SDL_LoadBMP . This function returns SDL_Surface * , which we can load into SDL_Texture so that it can be used by the renderer.

SDL_LoadBMP takes the path to our image, which you must change to fit your project structure, and returns SDL_Surface * or NULL if there is an error.

SDL_Surface *bmp = SDL_LoadBMP("../res/Lesson1/hello.bmp");
if (bmp == nullptr){
	std::cout << "SDL_LoadBMP Error: " << SDL_GetError() << std::endl;
	return 1;
}

Now we can load the image into the renderer using SDL_CreateTextureFromSurface . We pass the rendering context and the image in memory (SDL_Surface), and we get the loaded texture. In case something went wrong, we get NULL. Also, we will no longer need SDL_Surface, so we will free up the memory it occupies.

SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, bmp);
SDL_FreeSurface(bmp);
if (tex == nullptr){
	std::cout << "SDL_CreateTextureFromSurface Error: " << SDL_GetError() << std::endl;
	return 1;
}

Texture rendering

All that is left to do is get our texture on the screen! First we clean the renderer, after we render the texture , and then we show the updated screen to see the result. Since we want to render the whole image and make it stretch to fit the screen, we will pass NULL as the source and target rectangles for SDL_RenderCopy. We also want to keep the window open for a while to see the result until the program ends, so we will add the SDL_Delay call .

SDL_RenderClear(ren);
SDL_RenderCopy(ren, tex, NULL, NULL);
SDL_RenderPresent(ren);
SDL_Delay(2000);

Garbage collection

Before we exit, we must destroy all the objects we created with the various SDL_DestroyX functions and complete the SDL.

SDL_DestroyTexture(tex);
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
SDL_Quit();

End of the lesson

If successful, at startup you should see the image in the entire window, and after two seconds the program will end. In case of problems, make sure the SDL is installed and configured correctly. Detailed instructions for installing and configuring SDL for various platforms are available here .

See you soon in lesson 2: don't push everything into main .

Also popular now: