129

I'm starting with SDL2 and having some trouble trying to understand what an SDL_Renderer is.

What is it? What does it do? What's the difference between SDL_Renderer, SDL_Window, SDL_Surface and SDL_Texture and how they are related?

I had issues with this when trying to understand this introductory code:

#include <iostream>
#include <SDL2/SDL.h>

int main()
{
    /* Starting SDL */
    if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
        std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
        return 1;
    }

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

    /* Create a Render */
    SDL_Renderer *render = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (render == nullptr) {
        std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
        return 1;
    }

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

    /* Upload surface to render, and then, free the surface */
    SDL_Texture *texture = SDL_CreateTextureFromSurface(render, bmp);
    SDL_FreeSurface(bmp);
    if (texture == nullptr){
        std::cout << "SDL_CreateTextureFromSurface Error: " << SDL_GetError() << std::endl;
        return 1;
    }

    /* Draw the render on window */
    SDL_RenderClear(render); // Fill render with color
    SDL_RenderCopy(render, texture, NULL, NULL); // Copy the texture into render
    SDL_RenderPresent(render); // Show render on window

    /* Wait 2 seconds */
    SDL_Delay(5000);

    /* Free all objects*/
    SDL_DestroyTexture(texture);
    SDL_DestroyRenderer(render);
    SDL_DestroyWindow(window);

    /* Quit program */
    SDL_Quit();
    return 0;
}

I was using Twinklebear tutorial (suggested on SDL Wiki) and looked also on SDL Wiki Documentation and some books. But all of them assume that I know these definitions.

Stevoisiak
  • 23,794
  • 27
  • 122
  • 225
prcastro
  • 2,178
  • 3
  • 19
  • 21

2 Answers2

244

SDL_Window

SDL_Window is the struct that holds all info about the Window itself: size, position, full screen, borders etc.


SDL_Renderer

SDL_Renderer is a struct that handles all rendering. It is tied to a SDL_Window so it can only render within that SDL_Window. It also keeps track the settings related to the rendering. There are several important functions tied to the SDL_Renderer

  • SDL_SetRenderDrawColor(renderer, r, g, b, a);
    This sets the color you clear the screen to ( see below )

  • SDL_RenderClear(renderer);
    This clears the rendering target with the draw color set above

  • SDL_RenderCopy(
    This is probably the function you'll be using the most, it's used for rendering a SDL_Texture and has the following parameters :

    • SDL_Renderer* renderer,
      The renderer you want to use for rendering.
    • SDL_Texture* texture,
      The texture you want to render.
    • const SDL_Rect* srcrect, The part of the texture you want to render, NULL if you want to render the entire texture
    • const SDL_Rect* dstrect)
      Where you want to render the texture in the window. If the width and height of this SDL_Rect is smaller or larger than the dimensions of the texture itself, the texture will be stretched according to this SDL_Rect
  • SDL_RenderPresent(renderer);
    The other SDL_Render* functions draws to a hidden target. This function will take all of that and draw it in the window tied to the renderer.

SDL_Textures and SDL_Surface

The SDL_Renderer renders SDL_Texture, which stores the pixel information of one element. It's the new version of SDL_Surface which is much the same. The difference is mostly that SDL_Surface is just a struct containing pixel information, while SDL_Texture is an efficient, driver-specific representation of pixel data.

You can convert an SDL_Surface* to SDL_Texture using

SDL_Texture* SDL_CreateTextureFromSurface(SDL_Renderer* renderer,
                                          SDL_Surface*  surface)

After this, the SDL_Surface should be freed using

SDL_FreeSurface( SDL_Surface* surface )

Another important difference is that SDL_Surface uses software rendering (via CPU) while SDL_Texture uses hardware rendering (via GPU).


SDL_Rect

The simplest struct in SDL. It contains only four shorts. x, y which holds the position and w, h which holds width and height.

It's important to note that 0, 0 is the upper-left corner in SDL. So a higher y-value means lower, and the bottom-right corner will have the coordinate x + w, y + h


You can read more about SDL2 on my blog.

Stevoisiak
  • 23,794
  • 27
  • 122
  • 225
olevegard
  • 5,294
  • 1
  • 25
  • 29
  • 1
    So what you when you call SDL_RenderPresent is take that renderer with all it's setting and textures that were uploaded to it and make it render this informations on the Window that it's tied to? – prcastro Jan 08 '14 at 22:15
  • 5
    @olevegard, great answer. Just to clarify the difference between SDL_Texture and SDL_Surface, I would emphasize that SDL_Texture renders using the GPU and SDL_Surface uses software redering, which is less efficient but lets you manipulate freely the pixel information. Also, great blog, I will surely read it :) – Fabio Picchi Sep 12 '15 at 23:44
  • The statement *"This clears the rendering target with the draw color set above"*, I believe, is correct but I'm unable to understand the phrase "clears" in the statement. The [doc](https://wiki.libsdl.org/SDL_RenderClear?highlight=%28%5CbCategoryAPI%5Cb%29%7C%28SDLFunctionTemplate%29) always uses this phrase. Could you please explain what exactly *"clear"* means here? Does it mean "paint" (sort-of) with the current draw color of the renderer? – Nawaz Dec 30 '16 at 17:47
  • Is there any reason to use `SDL_Surface` over `SDL_Renderer`? – Stevoisiak Aug 17 '18 at 18:34
  • 2
    The top answer has some inaccuracy, SDL_Renderer can tied to surface too, not only to window, please check the link: https://wiki.libsdl.org/SDL_CreateSoftwareRenderer – dmitro Nov 27 '18 at 11:26
  • 1
    Many articles are not available now at your blog =( – Eugen Konkov Dec 26 '20 at 10:36
  • the render context is unique? or you can have several renderers. For example: in game class have *renderer and in player class have *playerRenderer. Or i have to pass game class *render to others clases for make diferents textures from surfaces? – Hernán Garcia Nov 23 '21 at 03:09
11

Think of SDL_Window as physical pixels, and SDL_Renderer and a place to store settings/context.

So you create a bunch of resources, and hang them off of the renderer; and then when its ready, you tell renderer to put it all together and send the results to the window.

woolstar
  • 5,063
  • 20
  • 31