Clearing when exiting an OpenGL application

I have an OSG OpenGL application that I am trying to modify. When I create the application as a whole, a set of initialization functions is called - including methods where I can specify my own mouse and keyboard handlers, etc. For example:

glutInit(&argc, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(100, 100); glutInitWindowSize(700, 700); glutCreateWindow("Map Abstraction"); glutReshapeFunc(resizeWindow); glutDisplayFunc(renderScene); glutIdleFunc(renderScene); glutMouseFunc(mousePressedButton); glutMotionFunc(mouseMovedButton); glutKeyboardFunc(keyPressed); 

At some point, I pass control to glutMainLoop, and my application starts up. In the process, I create a whole bunch of objects. I would like to clean them. Is there a way I can tell GLUT to call the cleanup method before it exits?

+7
c ++ opengl macos glut
source share
5 answers

In freeglut, if you call this:

 glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION) 

Before entering the main loop, when the window closes, the main loop function will return, and you can perform the cleanup.

It is worth noting that at this stage, the GL context has already been destroyed, so you cannot perform any GL operations.

+9
source share

I fell for it from time to time, trying to play with GLUT. I tried everything I could, including IIRC coming out of glutMainLoop through an exception caught in the main function, but ...

When using glutMainLoop

My solution was this: Create a global Context object that will be the owner of all your resources and free those resources in the destructor.

This global destructor of the Context object is called immediately after exiting the main one.

Important Context is a global variable, not a variable declared in the main function, because for the reason that it still eludes me (I still don’t see interest in this implementation option), glutMainLoop will not return.

In my Linux box (Ubuntu), the destructor is called correctly. I think it will also work on Windows and MacOS.

Please note that this is the C ++ version of the Francisco Soto atexit() version without any restrictions.

Using glutMainLoopEvent

Apparently, some implementations have glutMainLoopEvent, which can be used instead of calling glutMainLoop.

http://openglut.sourceforge.net/group__mainloop.html#ga1

glutMainLoopEvent only allow pending events, and then will return. Thus, you should specify the event loop ( for(;;) construct) around the glutMainLoopEvent call, but in this way you can work with GLUT and still have control over the event loop and free up your resources when necessary.

+4
source share

If you are using C / C ++, maybe you can use the atexit () call?

+3
source share

Usually you do not need to do this; only exiting the application will disrupt all the resources that you have allocated. Even if you capture the screen, it should return to normal operation.

0
source share

I ended up using paercebal's answer above, as well as his previous attempt to use the try / catch block around glutMainLoop (). What for? Because I wanted to clean it correctly, no matter how it was turned off. The global Context object will be destroyed correctly if the application terminates, and this will happen if you close the application by closing the window (or exit the application on OS X). But if you press ctrl-C in the terminal where it was started (or sent SIGINT), cleaning will not happen. To handle this, I added the following to my code:

 static bool exitFlag = false; static void sighandler(int sig) { exitFlag = true; } static void idleFunc() { if(exitFlag) { throw NULL; } } 

And then in main ():

 signal(SIGINT, sighandler); glutIdleFunc(idleFunc); try { glutMainLoop(); } catch(...) {} 

This is not the most beautiful bit of code, but it handles both cases of exit from the program correctly.

One catch (not a pun intended) is any code that you place after the catch () block will not be called if you close the window / usually close the application. You must put your cleanup code in a global Context object, as shown in paercebal's answer. All of this code makes the SIGINT signal be used to exit glutMainLoop ().

I think the real lesson here is that for something really complicated, GLUT is simply not going to cut it.

0
source share

All Articles