SDL 2 Tutorials: Lesson 5 - Textures

    Hello everyone and welcome to the fifth lesson on SDL 2, in which we will analyze the textures, simplifying the work of the computer. You can find all the lessons in English here .

    In the second version SDL, there is a very good opportunity to create textures and render them. Hardware rendering is much faster than drawing surfaces in a window.

    Textures have their own data type - SDL_Texture . When working with textures, we need a render for rendering. Now we will announce all this.

    #include<SDL2/SDL.h>#include<SDL2/SDL_image.h>#include<iostream>usingnamespacestd;
    int SCREEN_WIDTH = 640;
    int SCREEN_HEIGHT = 480;
    SDL_Window *win = NULL;
    SDL_Renderer *ren = NULL;
    SDL_Texture *flower = NULL;
    

    Here we announced a window, a render and this flower.
    We also connected libraries and set window sizes.

    The Init function will also have to be changed.

    bool ok = true;
        if (SDL_Init(SDL_INIT_VIDEO) != 0) {
            cout << "Can't init: " << SDL_GetError() << endl;
            ok = false;
        }
        win = SDL_CreateWindow("Текстуры", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
        if (win == NULL) {
            cout << "Can't create window: " << SDL_GetError() << endl;
            ok = false;
        }
    

    First, create the variable ok , so as not to end the function immediately, but to find all errors during initialization. Next, initialize the SDL and create a window in a known manner.

    It's time to declare a render.

        ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
        if (ren == NULL) {
            cout << "Can't create renderer: " << SDL_GetError() << endl;
            ok = false;
        }
        SDL_SetRenderDrawColor(ren, 0xFF, 0xFF, 0xFF, 0xFF);
    

    The render is declared by the SDL_CreateRenderer function . It takes 3 values: the window for which this render will be used, the driver index (or -1 if we want to find the first one suitable) and flags. I used the flags SDL_RENDERER_ACCELERATED and SDL_RENDERER_PRESENTVSYNC . Here is a list of all the flags:

    Flags
    SDL_RENDERER_SOFTWARE - fallback for;
    SDL_RENDERER_ACCELERATED - use of hardware acceleration;
    SDL_RENDERER_PRESENTVSYNC - vertical synchronization;
    SDL_RENDERER_TARGETTEXTURE - support for rendering to texture.

    Next, we use the SDL_SetRenderDrawColor function , which sets the color for drawing primitives.

    After that, initialize the IMG and return ok .

    int flags = IMG_INIT_PNG;
        if (!(IMG_Init(flags) & flags)) {
            cout << "Can't init image: " << IMG_GetError() << endl;
            ok = false;
        }
        return ok;
    }
    

    Now let's write the Load function .

    boolload(){
        bool ok = true;
        SDL_Surface * temp_surf = NULL;
        temp_surf = IMG_Load("flower.png");
        if (temp_surf == NULL) {
            cout << "Can't load image: " << IMG_GetError() << endl;
            ok = false;
        }
    

    Here we also created the ok variable , for the same needs. They created a temporary surface and loaded flower images into it.

    Next we need to make a texture from the surface.

        flower = SDL_CreateTextureFromSurface(ren, temp_surf);
        if (flower == NULL) {
            cout << "Can't create texture from surface: " << SDL_GetError() << endl;
            ok = false;
        }
    

    The function SDL_CreateTextureFromSurface will help us in creating the texture . It takes on render and surface values. It returns an instance of the SDL_Texture class .

    In order not to clog the memory, we need to clean the temporary surface. After that, return ok and the function is ready.

    The Quit function has taken a few more actions.

    voidquit(){
        SDL_DestroyWindow(win);
        win = NULL;
        SDL_DestroyRenderer(ren);
        ren = NULL;
        SDL_DestroyTexture(flower);
        flower = NULL;
        SDL_Quit();
        IMG_Quit();
    }
    

    Here we removed the window, render, texture and left SDL and IMG . I also set all deleted objects to NULL for even better memory cleanup.

    We begin to write the Main function.

    intmain(int argc, char ** argv){
        if (!init()) {
            quit();
            return1;
        }
        if (!load()) {
            quit();
            return1;
        }
    

    We wrote initialization and loading, we do not stop here.

    The next step is to create 2 variables.

    bool run = true;
        SDL_Event e;
    

    This program will have a main cycle to refresh memory, so let's start unwriting it.

    while (run) {
            while(SDL_PollEvent(&e) != 0) {
                if (e.type == SDL_QUIT) {
                    run = false;
                }
            }
    

    Processed the event of pressing the cross and that's it.

    It's time to draw. When using textures and rendering, different functions are used for rendering from what we know. In order to clear the screen of drawn textures, the SDL_RenderClear function is used . It paints the screen with the color that we specified with the SDL_SetRenderDrawColor function . To draw texture isrolzuetsya function SDL_RenderCopy , and to update the screen - SDL_RenderPresent . We’ll write them now.

            SDL_RenderClear(ren);
            SDL_RenderCopy(ren, flower, NULL, NULL);
            SDL_RenderPresent(ren);
        }
    

    We will analyze only the SDL_RenderCopy function . It takes 4 meanings. The first is a render, the second is a texture, the third is a rectangle whose area we want to cut out for drawing, the fourth is a rectangle whose coordinates are used for rendering, and the width and height are for resizing the texture.

    Next, call the Quit function and return 0 .

        quit();
        return0;
    }
    

    On this I will finish the lesson, if something was not clear - write, but I say goodbye to all for now!

    By the way, here is the full code:

    #include<SDL2/SDL.h>#include<SDL2/SDL_image.h>#include<iostream>usingnamespacestd;
    int SCREEN_WIDTH = 640;
    int SCREEN_HEIGHT = 480;
    SDL_Window *win = NULL;
    SDL_Renderer *ren = NULL;
    SDL_Texture *flower = NULL;
    boolinit(){
        bool ok = true;
        if (SDL_Init(SDL_INIT_VIDEO) != 0) {
            cout << "Can't init: " << SDL_GetError() << endl;
            ok = false;
        }
        win = SDL_CreateWindow("Текстуры", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
        if (win == NULL) {
            cout << "Can't create window: " << SDL_GetError() << endl;
            ok = false;
        }
        ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
        if (ren == NULL) {
            cout << "Can't create renderer: " << SDL_GetError() << endl;
            ok = false;
        }
        SDL_SetRenderDrawColor(ren, 0xFF, 0xFF, 0xFF, 0xFF);
        int flags = IMG_INIT_PNG;
        if (!(IMG_Init(flags) & flags)) {
            cout << "Can't init image: " << IMG_GetError() << endl;
            ok = false;
        }
        return ok;
    }
    boolload(){
        bool ok = true;
        SDL_Surface * temp_surf = NULL;
        temp_surf = IMG_Load("flower.png");
        if (temp_surf == NULL) {
            cout << "Can't load image: " << IMG_GetError() << endl;
            ok = false;
        }
        flower = SDL_CreateTextureFromSurface(ren, temp_surf);
        if (flower == NULL) {
            cout << "Can't create texture from surface: " << SDL_GetError() << endl;
            ok = false;
        }
        SDL_FreeSurface(temp_surf);
        return ok;
    }
    voidquit(){
        SDL_DestroyWindow(win);
        win = NULL;
        SDL_DestroyRenderer(ren);
        ren = NULL;
        SDL_DestroyTexture(flower);
        flower = NULL;
        SDL_Quit();
        IMG_Quit();
    }
    intmain(int argc, char ** argv){
        if (!init()) {
            quit();
            return1;
        }
        if (!load()) {
            quit();
            return1;
        }
        bool run = true;
        SDL_Event e;
        while (run) {
            while(SDL_PollEvent(&e) != 0) {
                if (e.type == SDL_QUIT) {
                    run = false;
                }
            }
            SDL_RenderClear(ren);
            SDL_RenderCopy(ren, flower, NULL, NULL);
            SDL_RenderPresent(ren);
        }
        quit();
        return0;
    }
    

    Previous lesson | Next lesson

    Also popular now: