Psst! Do you want to know a way to get your SDL2 applications running faster?
Sweet! Sounds awesome. Lead me the way.
The release of SDL2 added the ability to use the GPU. All this time, we've been doing software rendering which is where the CPU is doing all the graphics calculations. The CPU is fast but is not optimized for the doing the necessary calculations to output graphics onto the screen.
How do we use the GPU with SDL2?
We have to use an SDL_Renderer
for that. To create one, we use the SDL_CreateRenderer()
function and it takes the following arguments:
- A pointer to an
SDL_Window
- The index for what rendering driver we want to use
- And 0 or more
SDL_RendererFlags
OR'd together.
I get the first and third, but I don't know the indices of my rendering drivers.
If you don't want to set it manually, just supply -1 and let SDL2 do the work for you.
We'll be the using SDL_RENDERER_ACCERELATED
renderer flag to get 2DS accelerated graphics.
SDL_Window *window = ...;
SDL_Renderer *window_renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
A quick note: don't try to get the window's surface if you also want to use the window's renderer. Bad things will happen if you do.
We got our renderer. Now what?
The SDL_Renderer
works by having pixels copied into it and then SDL_RenderPresent()
is called.
Like blitting?
Similar in spirit, yes.
Okay, I've got this. First, I'll load an image into an SDL_Surface
and then copy it over.
One problem with that.
What is it?
The function used to copy the pixel data is SDL_RenderCopy()
and it takes an SDL_Texture
.
I know what a texture is.
The ones in SDL2 are not exactly the same as of what you're probably thinking of right now.
Okay, then what's different between SDL_Surface
and SDL_Texture
?
SDL_Surface
is a collection of pixels and some extra information like the format being used while SDL_Texture
is also a collection of pixels but is stored in an efficient and driver specific representation.
Okay, is there a function that loads an image into an SDL_Texture
?
No.
Then how do we use an SDL_Texture
?
We have to convert it from an SDL_Surface
to an SDL_Texture
.
And we do that by?
By using SDL_CreateTextureFromSurface()
which takes two arguments:
- A pointer to an
SDL_Renderer
- And a pointer to an
SDL_Surface
.
SDL_Surface *surface = ...;
SDL_Texture *texture = SDL_CreateTextureFromSurface(window_renderer, surface);
if(!texture)
{
std::cout << "Failed to convert surface into a texture\n";
std::cout << "SDL2 Error: " << SDL_GetError() << "\n";
}
SDL_FreeSurface(surface);
Remember to free the surface when you're done converting it into a texture. When you're done using the texture, make sure to call SDL_DestroyTexture()
on it.
Let's render the texture onto the screen.
Aren't you missing something?
No. I think we have everything we need to render onto the screen.
We need to clear the screen first, silly!
Ah, my bad.
We need to clear the screen as you suggested. We can do this by using SDL_RenderClear()
and it takes one argument which is a pointer to an SDL_Renderer
. If we want to change the color that SDL_RenderClear()
uses to clear the window with, we can call SDL_SetRenderDrawColor()
which takes a pointer to an SDL_Renderer
and red, green, blue and alpha values for each argument.
By default it uses black.
SDL_RenderClear(window_renderer);
SDL_RenderCopy(window_renderer, texture, nullptr, nullptr);
SDL_RenderPresent(window_renderer);
SDL_RenderCopy()
takes the following arguments:
- A pointer to an SDL_Renderer
- A pointer to an SDL_Texture
- The source
SDL_Rect
- And the destination
SDL_Rect
And there you have it! 2D accelerated graphics in SDL2. More about 2D acceleration can be found in this section of the documentation:
https://wiki.libsdl.org/CategoryRender
What's next
We have enough knowledge of SDL2 to finally create our own small-scale game. The game we will be making is the classic arcade game, Pong. It will probably be a multi-part article and the first one may not be released for a few days. So, hang tight!
Top comments (2)
Oh my ! Hey I want to give a shoutout to this since it has been a while since I have used SDL2. I loved it when I did though!
I love SDL2 and its ease to handle input from user!