What is an SDL renderer?

C++SdlTerminologySdl 2

C++ Problem Overview


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.

C++ Solutions


Solution 1 - C++

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.

Solution 2 - C++

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionprcastroView Question on Stackoverflow
Solution 1 - C++olevegardView Answer on Stackoverflow
Solution 2 - C++woolstarView Answer on Stackoverflow