[ SDL2 – Part 6 ] Using SDL_Textures

Loading textures


In this tutorial you will learn how to load images ( just .bmp for now, the next part will cover .png ). First of all, a little info about the two new structs we’ll be using

SDL_Surface


This is part of the old SDL ( before 2.0. ) It was used for just about everything related to rendering.

SDL_Surface is used for holding the raw texture data. Basically it says what the color for every pixels is. Sort of like this :

  • pixel[ 0, 0 ] = 128, 64, 255, 255 ( 128 red, 64 green, 255 blue, 255 alpha )
  • pixel[ 1, 0 ] = 255, 32, 128, 128 ( 255 red, 32 green, 128 blue, 128 alpha )
  • ..etc

( This might not be 100% true for all cases, but it’s generally how SDL_Surface stores the pixels. )

The SDL_Surface structure also holds other data about the texture :

  • width/height ( these are read-only )
  • the pixel format, stores as an SDL_PixelFormat
  • clip_rec, a SDL_Rect used for bliting ( similar to rendering )

These values are useful to know about if you want to create your own SDL_Surfaces using code or want to use the old form of rendering ( bliting ). I do, however, not recommend learning about it. Bliting is less intuitive and it uses only software rendering. This basically means that the CPU will be doing the rendering, something CPUs are really bad at. We want optimized hardware rendering on the GPU. And that’s where the second struct comes in.

SDL_Texture


Like SDL_Surface, SDL_Texture holds texture data. But unlike SDL_Surface, SDL_Texture holds an optimized, driver specific representation of the pixel data. This means rendering will be executed on the GPU, where it belongs. And THAT means it is really, really fast!

So what’s the point of SDL_Surfaces?

Well, as I said, the pixel data in SDL_Texture is optimized. And what’s more, it can be very different depending on your driver ( nVidia vs ATI. ) Basically this means that you can’t use the pixel data for anything other than rendering. A second reason will come up when we dive into another new part of SDL, namely image loading.

Loading images


Loading a BMP image in SDL is very easy. It can be done using the following function

Parameters

  • file – the file we want to load

Return value

The loaded image as a SDL_Surface. null if failed

Converting SDL_Surface to SDL_Texture


We’re not gonna use the SDL_Surface*, we want a SDL_Texture* instead. To get it, we need to use a second function :

Parameters

  • renderer – our SDL_Renderer
  • surface – the surface we want to make a SDL_Texture from

Return value

The resulting SDL_Texture. null if failed. 

Since we won’t be using the SDL_Surface, we can delete it and free the memory :

Parameters

  • surface – the SDL_Surface to delete

Now that all of this is in place, we can wrap it all up in a nice little function :

Getting the images on screen


Now that we have loaded the textures, we need to render then on screen. That means no more SDL_RenderFillRect() and THAT means no more rectangles and squares. Finally! To render them, we just need a simple function :

Parameters

  • renderer – the SDL_Renderer we always use for rendering
  • texture – the SDL_Texture we want to render
  • srcrect – which part of the SDL_Texture to render. null for everything.
  • dstrect – where to render it. Used exactly like in SDL_RenderFillRect)

Return value

0 on success

Even though this function has a few parameters, it’s really quite simple. We can use nullptr for srcrect and the SDL_Rects we used for SDL_RenderFillRect() as dstrect. And then we can remove the SDL_SetRenderDrawColor and end up with a shorter Render() function.

Putting it all together


I’m not gonna put the entire code on the blog anymore since this creates a whole wall of text to scroll through. And now there are images you’ll need too. But you can download the images and the source code here.


Feel free to comment if you have anything to say or ask questions if anything is unclear. I always appreciate getting comments.

You can also email me : olevegard@headerphile.com
Share

4 thoughts on “[ SDL2 – Part 6 ] Using SDL_Textures”

  1. As i understand SDL_Surface and SDL_Texture are just 2d images and structs what contain information about images(correct me if i am wrong).What is diffrence between them and why to use function to convert from surface to texture if they are the same thing? Maybe its faster and something with memory?

    Thanks

    1. Hello 🙂

      Yes, SDL_Surface is more or less just struct containing pixel data in a raw format. See https://wiki.libsdl.org/SDL_Surface

      While SDL_Texture is a more efficient representation of the data. It is driver-specific so we need to let SDL handle the conversion using the conversion function. See https://wiki.libsdl.org/SDL_Texture

      In general you want to use SDL_Texture for rendering. But you can’t get access to the pixel data with SDL_Texture. At least not in a platform-independent way. With SDL_Surface you can’t get access to the raw pixel data, along with some metadata like width and height

      1. I have read your post about png files.Now i dont understand why to ever use SDL_Surface if you never will use bmp files if you can load png files(and other) with texture directly?Is SDL_Surface used somethere else?

        1. SDL_Surface was used before SDL 2, there is no SDL_Texture in the old SDL.

          There really isn’t much use for SDL_Surface anymore, unless you need access to the raw pixel data. I’ll probably write more about this when I get into using textures with OpenGL

Leave a Reply

Your email address will not be published. Required fields are marked *