Why is my quit function not responding

Hi this is my first attempt at sdl and open gl trying to do graphics demos and add music, I managed to get a quad on the screen and change the colours but now I’ve got a couple of functions in the main while loop and a bit of sdl delay the if(e.type == SDL_QUIT) doesn’t seem to be responding, how should I re-write it to work? thanks.

‘’'c++
#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <stdio.h>
#include

// -lSDL2 -lGLU -lglut -lGL

//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

//Starts up SDL and creates window
bool init();

//Frees media and shuts down SDL
void close();

//The window we’ll be rendering to
SDL_Window* gWindow = NULL;

//The open gl square
float glSquareblk();
float glSquarerd();
float glSquaregrn();
float glSquarebl();

//Opengl context
SDL_GLContext gContext;

bool init()
{
//Initialization flag
bool success = true;

//Initialize SDL
if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
	printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
	success = false;
}
else
{
	//Create window
	gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_OPENGL |  SDL_WINDOW_SHOWN );
	if( gWindow == NULL )
	{
		printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() );
		success = false;
	}
	else
	{
	
	}
}

return success;

}

void close()
{
//Destroy window
SDL_DestroyWindow( gWindow );
gWindow = NULL;

//Quit SDL subsystems
SDL_Quit();

}

float glSquareblk()
{
glClearColor(0.0,0.0,0.0,1.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,1.0,1.0);
glOrtho(-1.0,1.0,-1.0,1.0,-1.0,1.0);
glBegin(GL_QUADS);
glVertex2f(-0.5,-0.5);
glVertex2f(-0.5,0.5);
glVertex2f(0.5,0.5);
glVertex2f(0.5,-0.5);
glEnd();
glFlush();
}

float glSquarerd()
{
glClearColor(1.0,0.0,0.0,1.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,1.0,1.0);
glOrtho(-1.0,1.0,-1.0,1.0,-1.0,1.0);
glBegin(GL_QUADS);
glVertex2f(-0.5,-0.5);
glVertex2f(-0.5,0.5);
glVertex2f(0.5,0.5);
glVertex2f(0.5,-0.5);
glEnd();
glFlush();
}

float glSquaregrn()
{
glClearColor(0.0,1.0,0.0,1.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,1.0,1.0);
glOrtho(-1.0,1.0,-1.0,1.0,-1.0,1.0);
glBegin(GL_QUADS);
glVertex2f(-0.5,-0.5);
glVertex2f(-0.5,0.5);
glVertex2f(0.5,0.5);
glVertex2f(0.5,-0.5);
glEnd();
glFlush();
}

float glSquarebl()
{
glClearColor(0.0,0.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,1.0,1.0);
glOrtho(-1.0,1.0,-1.0,1.0,-1.0,1.0);
glBegin(GL_QUADS);
glVertex2f(-0.5,-0.5);
glVertex2f(-0.5,0.5);
glVertex2f(0.5,0.5);
glVertex2f(0.5,-0.5);
glEnd();
glFlush();
}

int main( int argc, char* args[] )
{
//Start up SDL and create window
if( !init() )
{
printf( “Failed to initialize!\n” );
}
else
{
//Main loop flag
bool quit = false;

		gContext = SDL_GL_CreateContext( gWindow );
		
		//Event handler
		SDL_Event e;

		//While application is running
		while( !quit )
		{
			//Handle events on queue
			while( SDL_PollEvent( &e ) != 0 )
			{
				glSquareblk();
				SDL_Delay(3000);
				SDL_GL_SwapWindow( gWindow );
				
				glSquarerd();
				SDL_Delay(3000);
				SDL_GL_SwapWindow( gWindow );
				
				glSquaregrn();
				SDL_Delay(3000);
				SDL_GL_SwapWindow( gWindow );
				
				glSquarebl();
				SDL_Delay(3000);
				SDL_GL_SwapWindow( gWindow );
				
				//User requests quit
				if( e.type == SDL_QUIT )
				{
					quit = true;
				

//Free resources and close SDL
close();

return 0;

}
}
}
}
}

‘’’

So what this code is doing:

  • each time there’s an event:
    • do four iterations of:
      • draw something, wait 3 seconds
    • See if the event was a quit request.

So if you don’t trigger any other events, like moving the mouse, this will quit the program after about 12 seconds. Also, if you don’t trigger an event, it won’t draw anything new.

Move the draws and swaps and delays outside of the while( SDL_PollEvent( &e ) != 0 ) loop, so it will handle all pending events together. This will still cause the 12 second issue, but at least it won’t be 12 seconds for every event.

Next, you’re going to want to get rid of those SDL_Delay calls. Most games render every frame, even if nothing has changed, so you might try something like this for that primary loop:

// OUTSIDE OF THE LOOP SO IT DOESN'T RESET EVERY TIME:
int frame_number = 0;

while (!quit)
{
    // at 60fps, there would be 180 frames in 3 seconds. Times 4 colors would be 720 frames.
    if (frame_number > 720)
        frame_number = 0;  // reset this.

    if (frame_number < 180)    
        glSquareblk();
    else if (frame_number < 360)
        glSquarerd();
    else if (frame_number < 520)
        glSquaregrn();
    else
        glSquarebl();
        
    SDL_GL_SwapWindow( gWindow );
    frame_number++;

    while( SDL_PollEvent( &e ) != 0 )
    {
        if( e.type == SDL_QUIT )
            quit = true;   // will fall out of the loop.
    }
}

// AT THE END OF MAIN:
close();
return 0;

This cycles through all the colors, changing about every three seconds, and the event queue is responsive because we process it in full every frame, so you can quit at any time.

BUT: we all know that not all hardware runs at 60fps, and any other number of disasters might happen. I showed you that code so you could see the answer to your question in a clear way, but we need to add a little more complexity to do this properly. We’re going to add a timer check so we render the right color for the block of three seconds we’re in instead of assuming it’s every 180 frames at 60fps. Code is almost the same but with the added details of handling timing.

// OUTSIDE OF THE LOOP SO IT DOESN'T RESET EVERY TIME:
Uint32 start_ticks = SDL_GetTicks();

while (!quit)
{
    // There are a thousand milliseconds ("ticks") in a second.
    const Uint32 now = SDL_GetTicks();
    const Uint32 ticks = now - start_ticks;

    if (ticks > 12000)  // 4 times 3 seconds (3000 milliseconds).
        start_ticks = now;  // reset this for next frame.

    if (ticks < 3000)
        glSquareblk();
    else if (ticks < 6000)
        glSquarerd();
    else if (ticks < 9000)
        glSquaregrn();
    else
        glSquarebl();
        
    SDL_GL_SwapWindow( gWindow );

    while( SDL_PollEvent( &e ) != 0 )
    {
        if( e.type == SDL_QUIT )
            quit = true;   // will fall out of the loop.
    }
}

One more benefit of doing it this way: At the end of the loop, you can plug in an SDL_Delay(10) to give up 10 milliseconds of CPU time each frame–a lifetime to the CPU, barely noticeable to humans–so your CPU isn’t cooking at 100% usage, but you still render with the correct timing.

Hope this helps!

Put a log print or breakpoint inside your close function, in the beginning. Maybe there is a recursion if SDL_Quit calls close.

You should probably rename close to something else because it’s a standard C lib function.

Also enable compiler warnings and fix the reported issues. For example, some function signatures indicate that something is returned but there is no return.