c++openglglutfreeglutglutcreatewindow

glutCloseFunc without terminating application


I have created a window with glutCreateWindow and started a loop using glutMainLoop. I want to end that loop and close the window so I use glutLeaveMainLoop and glutCloseFunc to destroy it. Automatically, my application terminates.

I would like the application to persist after the window is destroyed. Is it possible?

According to this link I can do it, however I don't know how. I'm using freeglut.


Solution

  • In the doc for glutCloseFunc():

    Users looking to prevent FreeGLUT from exiting when a window is closed, should look into using glutSetOption to set GLUT_ACTION_ON_WINDOW_CLOSE.

    which leads to the glutSetOption() docs:

    GLUT_ACTION_ON_WINDOW_CLOSE - Controls what happens when a window is closed by the user or system:

    • GLUT_ACTION_EXIT will immediately exit the application (default, GLUT's behavior).
    • GLUT_ACTION_GLUTMAINLOOP_RETURNS will immediately return from the main loop.
    • GLUT_ACTION_CONTINUE_EXECUTION will continue execution of remaining windows.

    And from glutLeaveMainLoop():

    The glutLeaveMainLoop function causes freeglut to stop the event loop. If the GLUT_ACTION_ON_WINDOW_CLOSE option has been set to GLUT_ACTION_GLUTMAINLOOP_RETURNS or GLUT_ACTION_CONTINUE_EXECUTION, control will return to the function which called glutMainLoop; otherwise the application will exit.

    Putting the pieces together:

    #include <GL/freeglut.h>
    #include <iostream>
    
    void display()
    {
        glClear( GL_COLOR_BUFFER_BIT );
        glutSwapBuffers();
    }
    
    int main( int argc, char** argv )
    {
        glutInit( &argc, argv );
        glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
        glutCreateWindow( "GLUT" );
        glutDisplayFunc( display );
        glutSetOption( GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS ); 
        std::cout << "Before glutMainLoop()!" << std::endl;
        glutMainLoop();
        std::cout << "Back in main()!" << std::endl;
        return 0;
    }