0

I my trying to learn SDL in C++ . I have simple program which will display a image . but When I try to close window by clicking close button on the window nothing happens.

here is my code:-

#include <SDL2/SDL.h> int main(int argc,char **argv) { static int k =0; SDL_Init(SDL_INIT_VIDEO); SDL_Window *w; w = SDL_CreateWindow("SDL VS Works",300,300,400,500,SDL_WINDOW_OPENGL); SDL_Renderer *render = SDL_CreateRenderer(w,-1,SDL_RENDERER_ACCELERATED); SDL_Surface *tux = SDL_LoadBMP("res/tux.bmp"); SDL_Texture *texture = SDL_CreateTextureFromSurface(render,tux); SDL_FreeSurface(tux); SDL_ShowWindow(w); SDL_Event event; while(1) { k++; printf("Running and loop %d\'th\n",k); SDL_PollEvent(&event); if(event.type == SDL_QUIT) { printf("closing \n"); goto sos; } SDL_RenderCopy(render,texture,0,0); SDL_RenderPresent(render); SDL_Delay(1000); } sos: SDL_DestroyWindow(w); SDL_DestroyRenderer(render); SDL_DestroyTexture(texture); SDL_Quit(); } 

I am using g++ 7.3 on Arch Linux.

5
  • Unrelated to your problem, but don't use goto to break out of a loop. Commented Feb 16, 2018 at 11:56
  • Also note that you need to check what SDL_PollEvent returns. Usually by having it as a condition in a loop. Commented Feb 16, 2018 at 11:57
  • @Someprogrammerdude When code will grow bigger then I will just use goto to sos: when I want to exit. Commented Feb 16, 2018 at 12:00
  • @Someprogrammerdude thanks :) Commented Feb 16, 2018 at 12:01
  • It works fine for me. Clicking the close button ends the loop. Maybe it's not receiving the quit message because you're making the thread sleep for 1000 milliseconds and it's not responsive or something, or you've moved the mouse before releasing the button. Try removing the SDL_Delay() line and try and see. Commented Feb 16, 2018 at 12:15

2 Answers 2

1

The SDL uses an event queue internally. When any event occurs, like the mouse moving a few pixels, it gets added to the queue. When you poll for events (using SDL_PollEvent), you only get the oldest event. Everything else stays in the queue.

Since your code only polls once per second, the queue probably gets flooded by mouse movements, and the SDL_QUIT event is just waiting in line, deep into the queue.

What you usually want to do is poll for events in a loop. Note that SDL_PollEvent returns 0 when there is no pending event.

while (SDL_PollEvent(&event)) { if(event.type == SDL_QUIT) { //... } } 
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks removing SDL_pollevent solved the problem but now CPU use is too high
Removing SDL_PollEvent? I'm going to assume you meant SDL_Delay, since that would indeed cause full CPU usage. You don't have to remove the delay. If you loop through every event in the queue using what I wrote, the SDL_QUIT will be caught as soon as SDL_Delay returns.
@noone Keep the SDL_Delay, put the SDL_PollEvent in a nested loop, and reduce the sleep to 100 or so.
1

By the way, the loop should look something like this:

SDL_Event SDLEvent; while (SDL_PollEvent(&SDLEvent)) { switch (SDLEvent.type) { case SDL_QUIT: break; case SDL_WINDOWEVENT: break; case SDL_MOUSEMOTION: break; case SDL_MOUSEWHEEL: break; } } 

Whether it's a switch statement like this or an if statement like you have isn't important. SDL_PollEvents will return 1 if there are still events in the queue, or zero otherwise. By calling the SDL_PollEvents(&SDLEvent) inside the while condition it will handle all the events in the queue before entering the while block next.

Interestingly your problem that your window won't close seems to be related to something else because it works for me. I've already mentioned maybe get rid of the SDL_Delay line and see if that does anything;

Comments