Using SDL2: 2D Accelerated Renderering
Tags: cpp, sdl
Published: 2018-11-05 04:56:13

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:

1. A pointer to an `SDL_Window`
2. The index for what rendering driver we want to use
3. 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.

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

1. A pointer to an `SDL_Renderer`
2. And a pointer to an `SDL_Surface`.

```cpp
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.

```cpp
SDL_RenderClear(window_renderer);

SDL_RenderCopy(window_renderer, texture, nullptr, nullptr);

SDL_RenderPresent(window_renderer);
```

`SDL_RenderCopy()` takes the following arguments:

1. A pointer to an SDL_Renderer
2. A pointer to an SDL_Texture
3. The source `SDL_Rect`
4. 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!