SDL_RenderPresent fails SDL_PollEvent


#1

Following is the SDL program that contains the problem:

#include <stdio.h>
#include "SDL.h"
SDL_Window* g_pWindow = 0;
SDL_Renderer* g_pRenderer = 0;
int main(int argc, char* args[]) {
	// initialize SDL
	if (SDL_Init(SDL_INIT_EVERYTHING) >= 0) {
		// if succeeded create our window
		g_pWindow = SDL_CreateWindow("SDL",
			SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
			640, 480,
			SDL_WINDOW_SHOWN);
		// if the window creation succeeded create our renderer
		if (g_pWindow != 0) {
			g_pRenderer = SDL_CreateRenderer(g_pWindow, -1, 0);
		}
	}
	else {
            printf("SDL_Init failed: %s\n", SDL_GetError());
  	    return -1; // sdl could not initialize
	}
	// everything succeeded lets draw the window
	// set to black // This function expects Red, Green, Blue and 
	// Alpha as color values
	SDL_SetRenderDrawColor(g_pRenderer, 0, 0, 0, 255);
	// clear the window to black
	SDL_RenderClear(g_pRenderer);
	// show the window
	SDL_RenderPresent(g_pRenderer);
// event loop
SDL_Event event;
while (1) {
    if (SDL_PollEvent(&event))
        if (event.type==SDL_QUIT)
            break;
    SDL_RenderPresent(g_pRenderer);
}
        printf("quit the event loop\n");
        
	// clean up SDL
	SDL_DestroyWindow(g_pWindow);
	SDL_DestroyRenderer(g_pRenderer);
	SDL_Quit();
	return 0;
}

If I click the “x” icon to close the window, the SDL_PollEvent call cannot catch the SDL_QUIT event and the program just terminates, without breaking while loop and executing statements after printf("quit the event loop\n");. If I comment out SDL_RenderPresent(g_pRenderer); in the while loop, SDL_QUIT event can be caught and responded as expected, and the program breaks out the while loop and destroys window and renderer normally.

So why does the SDL_RenderPresent fail SDL_PollEvent? We have to use SDL_RenderPresent in game loop to update the game display so simply removing this API makes no sense. How to fix it? Thanks.

I am using NoMachine to remotely connect to a Ubuntu. This is what I got when the program terminates abnormally:

[VGL] ERROR: in readback–
[VGL] 254: Window has been deleted by window manager

This is what I got when the program terminates normally:

[VGL] ERROR: in getGLXDrawable–
[VGL] 184: Window has been deleted by window manager


#2

Not sure if this is exactly your problem, but if (SDL_PollEvent(&event)) is a bad pattern. Use while (SDL_PollEvent(&event)) so you aren’t filling up the event queue faster than you process it.


#3

@JonnyD: You bet! You are really a genius! I fixed the event loop like this:

int count;
bool quitNext = false;
SDL_Event event;
while (1) {
    count=1;
    while (SDL_PollEvent(&event)) {
        printf("%d: event.type is %d\n",count++, event.type);
        if (event.type==SDL_QUIT) {
            quitNext = true;
        }
    }
    if (quitNext)
        break;
    SDL_SetRenderDrawColor(g_pRenderer, 255, 0, 0, 255);
    SDL_RenderClear(g_pRenderer);
    SDL_RenderPresent(g_pRenderer);
    SDL_Delay(10);
}
printf("quit the event loop\n");

Now the program can quit the loop correctly. This is the output:

… …
1: event.type is 1024
1: event.type is 1024
1: event.type is 1024
2: event.type is 512
1: event.type is 512
2: event.type is 256 //this is the SDL_QUIT event
3: event.type is 512
quit the event loop

I now have a good understanding of SDL event loop. Thank you very much for the help.