Search code examples
c++sdl-2lagrenderer

SDL2 renderer is giving me problems


I'm following this tutorial that teaches how to use SDL2 with the final goal of learning C++ in a more fun and interactive way.

For this, I only need to be able to draw lines, polygons and circles.

So, after reading part 1 that explains how to create a window on the screen and part 3 that introduces event handling, I headed torward part 7 and 8 that explain, respectively, how to create a renderer and how to draw a rectangle on the screen. This is the code I've got so far (it isn't exactly the same as the code on the tutorial: I've introduced a struct to pass SDL objects around and removed all the error handling which was confusing):

#include <SDL2/SDL.h>

//screen dimensions costants
#define SCREEN_WIDTH 540
#define SCREEN_HEIGHT 960

//data structure holding the objects needed to create a window and draw on it
struct interface {
    SDL_Window * window = NULL;
    SDL_Surface * surface = NULL;
    SDL_Renderer * renderer = NULL;
};

//function which inits the sdl and creates an interface object
interface init() {
    interface screen;
    SDL_Init(SDL_INIT_VIDEO);
    screen.window = SDL_CreateWindow("", 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
    screen.surface = SDL_GetWindowSurface(screen.window);
    screen.renderer = SDL_CreateRenderer(screen.window, -1, SDL_RENDERER_ACCELERATED);
    return screen;
}

//function to free the memory and close the sdl application
void close(interface screen) {
    SDL_DestroyRenderer(screen.renderer);
    SDL_DestroyWindow(screen.window);
    screen.renderer = NULL;
    screen.window = NULL;
    SDL_Quit();
}

int main(int argc, char* args[]) {

    //start the application
    interface screen = init();

    //setup for event handling
    bool quit = false;
    SDL_Event event;

    //the shape to render
    SDL_Rect fillRect = { SCREEN_WIDTH / 4, SCREEN_HEIGHT / 4, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2 };

    //main loop which first handles events
    while (!quit) {
        while (SDL_PollEvent(&event) != 0) {
            if (event.type == SDL_QUIT)
                quit = true;
        }
        //should draw a red rectangle on the screen
        SDL_SetRenderDrawColor(screen.renderer, 0xFF, 0xFF, 0xFF, 0xFF);
        SDL_RenderClear(screen.renderer);
        SDL_SetRenderDrawColor(screen.renderer, 0xFF, 0x00, 0x00, 0xFF);
        SDL_RenderFillRect(screen.renderer, &fillRect);
    }

    //End the application
    close(screen);
    return 0;
}

The problem is that, as it is, the program draws nothing to the screen (which remains black), and if I remove the line screen.surface = SDL_GetWindowSurface(screen.window); it also begins lagging a lot in a manner I even find difficult to exit the application.

Note that I'm programming on Android using C4droid and the SDL Plugin for C4droid.

Why is that happening? What am I doing wrong?

EDIT Problem solved by renaming close to end and by including a call to SDL_RenderPresent(screen.renderer); at the end of the main loop. With this setup the screen surface has to be deleted or the program won't draw anything.

Thanks to @keltar and @Wutipong Wongsakuldej for answering the question in the comments


Solution

  • Screenshot

    First of all I tested the code in Windows (MSYS2) rather than on Android as I don't have AIDE installed at the moment.

    Basically I added 2 lines of code into the main loop :

    //main loop which first handles events
    while (!quit) {
        while (SDL_PollEvent(&event) != 0) {
            if (event.type == SDL_QUIT)
                quit = true;
        }
        //should draw a red rectangle on the screen
        SDL_SetRenderDrawColor(screen.renderer, 0xFF, 0xFF, 0xFF, 0xFF);
        SDL_RenderClear(screen.renderer);
        SDL_SetRenderDrawColor(screen.renderer, 0xFF, 0x00, 0x00, 0xFF);
        SDL_RenderFillRect(screen.renderer, &fillRect);
        /** below lines are added **/
        SDL_RenderPresent(screen.renderer);
        SDL_Delay(0);
    }
    
    • SDL_RenderPresent draw whatever you've renderred so far to the screen. This make the output shows up.

    • SDL_Delay() this is added to give the cpu time back to the os. Without this your app might become unresponsive and the cpu utilization will be 100% (at one core) in some operating system (especially the very old one). I don't know if this is needed in Android or not anyway. Give it a try.