Search code examples
csdlsdl-2

SDL2: Why a figure "blinks"?


I'm trying to move a square in a rectangle in SDL, but when i launch it, the rectangle and the square "blinks" until I move the square with up, left, right or down. When the square moves, the rectangle stop blinking and only the square keeps blinking. How can i move it without the blink?

Edit: The problem was that i put SDL_RenderPresent twice after the main loop. Thanks for your help.

#include <SDL2/SDL.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <SDL2/SDL_image.h>

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 500;


int main() {
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window* window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_OPENGL);
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

    bool out = false;
    SDL_Event event;

    SDL_Rect grid;
    grid.x = 25;
    grid.y = 25;
    grid.w = 300;
    grid.h = 450;

    SDL_Rect square;
    square.x = 175;
    square.y = 25;
    square.w = 25;
    square.h = 25;

    //Main loop
   
    while (out==false){
        while (SDL_PollEvent(&event)){
            if (event.type==SDL_QUIT){out=true;}
            else if (event.type==SDL_KEYDOWN){
              // Keys
                switch (event.key.keysym.sym){
                    case SDLK_m:
                        out=true;
                        break;
                    case SDLK_LEFT:
                        square.x-=25;
                        SDL_RenderPresent(renderer);
                        break;
                    case SDLK_RIGHT:
                        square.x+=25;
                        SDL_RenderPresent(renderer);
                        break;
                    default:
                        break;
                        }
                    }
                }

        SDL_SetRenderDrawColor(renderer,0,255,0,0);
        SDL_RenderFillRect(renderer, &grid);
        SDL_RenderPresent(renderer);

        SDL_SetRenderDrawColor(renderer,255,0,0,255);
        SDL_RenderFillRect(renderer,&square);
        SDL_RenderPresent(renderer); 
        }
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}

Solution

  • As @HolyBlackCat pointed out, you should only call SDL_RenderPresent() once per frame, not once per shape or keypress:

    #include <SDL.h>
    #include <SDL_image.h>
    #include <stdbool.h>
    
    int main()
    {
        SDL_Init( SDL_INIT_VIDEO );
        SDL_Window* window = SDL_CreateWindow(
            "",
            SDL_WINDOWPOS_UNDEFINED,
            SDL_WINDOWPOS_UNDEFINED,
            640,
            500,
            SDL_WINDOW_OPENGL );
        SDL_Renderer* renderer = SDL_CreateRenderer(
            window,
            -1,
            SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC );
    
        bool out = false;
        SDL_Event event;
    
        SDL_Rect grid;
        grid.x = 25;
        grid.y = 25;
        grid.w = 300;
        grid.h = 450;
    
        SDL_Rect square;
        square.x = 175;
        square.y = 25;
        square.w = 25;
        square.h = 25;
    
        //Main loop
        while( out == false )
        {
            while( SDL_PollEvent( &event ) )
            {
                if( event.type == SDL_QUIT )
                {
                    out = true;
                }
                else if( event.type == SDL_KEYDOWN )
                {
                    // Keys
                    switch( event.key.keysym.sym )
                    {
                    case SDLK_m:
                        out = true;
                        break;
                    case SDLK_LEFT:
                        square.x -= 25;
                        break;
                    case SDLK_RIGHT:
                        square.x += 25;
                        break;
                    default:
                        break;
                    }
                }
            }
    
            SDL_SetRenderDrawColor( renderer, 0, 255, 0, 0 );
            SDL_RenderFillRect( renderer, &grid );
    
            SDL_SetRenderDrawColor( renderer, 255, 0, 0, 255 );
            SDL_RenderFillRect( renderer, &square );
            
            SDL_RenderPresent( renderer );
        }
    
        SDL_DestroyRenderer( renderer );
        SDL_DestroyWindow( window );
        SDL_Quit();
        return 0;
    }