Search code examples
c++sdldrawrect

Dissapearing SDL Rects. How to update window with new additional shapes


I'm trying to update the window with a new additional rect upon key pressing, but it keeps disappearing due to SDL_RenderClear. Is it recommended to remove SDL_RenderClear?

while (!quit) {
  while (SDL_PollEvent( & e) != 0) {
    if (e.type == SDL_QUIT)
      quit = true;
  }
  SDL_SetRenderDrawColor(gRenderer, 0xFF, 0xFF, 0xFF, 0xFF);
  SDL_RenderClear(gRenderer); //if i remove this line, the new rectangle will remain there

  SDL_Rect fillRect = {
    0,
    0,
    SCREEN_WIDTH / 5 - 5,
    SCREEN_HEIGHT / 5 - 5
  };
  SDL_SetRenderDrawColor(gRenderer, 255, 205, 51, 0xFF);
  SDL_RenderFillRect(gRenderer, & fillRect);

  switch (e.type) {
  case SDL_KEYDOWN:
    if (e.key.keysym.sym == SDLK_RIGHT) {
      SDL_Rect fillRect = {
        0,
        200,
        SCREEN_WIDTH / 5 - 5,
        SCREEN_HEIGHT / 5 - 5
      };
      SDL_SetRenderDrawColor(gRenderer, 255, 205, 51, 0xFF);
      SDL_RenderFillRect(gRenderer, & fillRect);
    }
    break;
  }
  SDL_RenderPresent(gRenderer);
}

Solution

  • SDL_RenderClear() is perfectly fine and in fact you should be using it. Your problem (aka the rect disappearing) is caused by the way you handle input. SDL_KEYDOWN is an event that only occurs on the frame that you press a key for, and while you're holding it down after a short delay. What you are doing is drawing the rect if the key has been pressed on that exact frame, not if it's been pressed on any previous frames. A solution via a bool could look like this:

    bool keyPressed = false;
    while( !quit ) {
        while( SDL_PollEvent( &e ) != 0 ) {
            if( e.type == SDL_QUIT )
                quit = true; 
    }
        SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );
        SDL_RenderClear( gRenderer ); //if i remove this line, the new rectangle will remain there
    
        SDL_Rect fillRect = { 0, 0, SCREEN_WIDTH / 5-5, SCREEN_HEIGHT / 5-5 };
        SDL_SetRenderDrawColor( gRenderer, 255, 205, 51, 0xFF );        
        SDL_RenderFillRect( gRenderer, &fillRect );
        
        if(keyPressed){
            SDL_Rect fillRect = { 0, 200, SCREEN_WIDTH / 5-5, SCREEN_HEIGHT / 5-5 };
            SDL_SetRenderDrawColor( gRenderer, 255, 205, 51, 0xFF );        
            SDL_RenderFillRect( gRenderer, &fillRect );
    }
        switch(e.type){
        case SDL_KEYDOWN:
            if(e.key.keysym.sym==SDLK_RIGHT){
                keyPressed = true;
            }
      break;
     }
       SDL_RenderPresent( gRenderer );
    }
    

    Screen clearing is something that should absolutely be done in graphics, because otherwise the shapes you've drawn on previous frames will just remain there.