8
votes

Nettoyage lorsque vous quittez une application OpenGL

J'ai une application OSX OpenGL, j'essaie de modifier. Quand je crée l'application un tout Les fonctions d'initialisation sont appelées - y compris les méthodes où je peux spécifier mes propres manutes de souris et de clavier, etc. Par exemple:

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);


1 commentaires

Si vous souhaitez que votre application de glueuse nettoie: N'utilisez pas de glueuse.


5 Réponses :



0
votes

Généralement, vous n'avez pas besoin de le faire; La sortie de l'application démolira toutes les ressources que vous avez allouées. Même si vous avez capturé l'écran, il devrait revenir à la normale.


9 commentaires

Je ne comprends pas; Comment la glueuse voudrait-elle savoir ce que j'ai Malloc'd?


Ce n'est pas une glouteuse qui fait cela, son système d'exploitation. Votre application se ferme et le système d'exploitation se nettoie après vous-même.


-1. C'est vraiment une mauvaise pratique. Il encourage les pratiques de programmation bâclée, telles que ne pas suivre correctement votre mémoire. Si vous avez écrit votre application correctement, vous devriez pouvoir vous détendre facilement des allocations de mémoire sans vous appeler sur le système d'exploitation pour effacer après vous.


+1 pour équilibrer. Peu importe que sa mauvaise pratique. C'est comment fonctionne de glutte. La fonction GLUTMODUNOPOOP ne retourne pas, alors NSApplication :: Run ne retourne pas. Dans les conditions où le cadre est déjà prometteur de ne pas faire de nettoyage, essayer de forcer les objets d'application au nettoyage est un effort gaspillé.


@Goz - Aiee. Si ce type de nettoyage était réellement nécessaire, ce serait un bug dans le système d'exploitation. En fait, dans le système d'exploitation X 10.6, Apple encourage explicitement explicitement les applications à se laisser tuer plutôt que gracieusement fermées lorsque cela est possible, afin d'accélérer la déconnexion: elle s'appelle une terminaison soudaine ( développeur.apple.com / Mac / Bibliothèque / Documentation / Cocoa / Référencez CE / ... ).


@Nicholas: Hélas C'est ce genre d'approche qui mène à un jeu comme Battlefield qui devait créer un nouveau processus et mettre fin à l'ancienne à chaque changement de niveau. C'est une mauvaise pratique. J'admets de regarder dans ce que c'est ce que c'est ce que glut vous encourage à faire, mais c'est mauvais. Surtout avec tous les insectes de pilotes OpenGL sur j'ai des doutes que le nettoyage GL sera complètement ...


Le questionneur demande quoi faire quand quitter ; Si vous fuiez dans votre application, c'est votre problème. Les fuites de ressources dans les conducteurs OpenGL sont des insectes dans les pilotes; Bien sûr, vous devrez peut-être travailler autour d'eux, mais il n'est pas nécessaire d'écrire toujours comme si elles existent.


Hé, si vous avez bownvotez cette réponse, veuillez vous expliquer vous-même. Je pense que j'ai toujours défendu ma réponse dans les commentaires, mais j'aimerais savoir pourquoi les gens sont en désaccord. (Sérieusement.)


@Nicholasriley - Je n'ai pas suscité ou non avancé votre réponse. Non Downvote - Tous les systèmes d'exploitation modernes que je connaisse (ne peuvent pas dire pour chaque) effectuent un nettoyage de ressources pour vous - si vous utilisez espace utilisateur . Et il n'y a rien de mal à laisser le système d'exploitation pour vous, surtout si le vendeur du système d'exploitation vous encourage à le faire (votre exemple Apple). Problème surviennent lorsque ce code est censé travailler sur un tel système dans l'espace utilisateur est, disons, a porté un autre système, ou effectué pour courir dans l'espace du noyau, ou simplement réutilisé par un autre codeur qui s'attend à objet de libération de ses ressources sur la résiliation. Ou autre chose..



4
votes

Je suis tombé pour cela de temps en temps, essayant de jouer avec une coupable. J'ai essayé tout ce que je pouvais, y compris la sortie IIRC sortant gluttmainloop à travers une exception captée dans la fonction principale mais ...

Lorsque vous utilisez glutmainloop

Ma solution était la suivante: Créez un objet global objet , qui sera propriétaire de toutes vos ressources et libérera ces ressources dans le destructeur.

Ce contexte global le destructeur d'objet sera appelé immédiatement après la sortie de la principale.

Il est important contexte est une variable globale, et non une variable déclarée dans la fonction principale, car pour une raison qui m'échappe encore (je ne sais toujours pas l'intérêt de ce choix de mise en œuvre) , Glutmainloop ne reviendra pas.

Dans ma boîte Linux (Ubuntu), le destructeur est appelé correctement. Je suppose que cela devrait également fonctionner de la même manière sur Windows et MacOS.

Notez qu'il s'agit de la version C ++ de la solution ATEXIT () FRANCISCO SOTO, sans limitations possibles.

Utilisation de GlutmainlopEvent

Apparemment, certaines implémentations ont un glauloopEvent qui peut être utilisé au lieu d'appeler Glutmainloop.

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

GlutmainloopEvent ne résoudra que les événements en attente, puis retourner. Ainsi, vous devez fournir la boucle d'événement (le pour (;;;) construire) autour de l'appel à GlutmainlopEvent , mais de cette façon, vous pouvez travailler avec une goutte et avoir toujours Contrôle sur la boucle d'événement et libérez vos ressources en cas de besoin.


0 commentaires

10
votes

dans Freeglut Si vous appelez ceci:

glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION)


1 commentaires

Il est en fait à noter que le contexte est détruit! C'est ce qui m'a conduit ici, 18 mois après avoir écrit ça. Une autre bonne option est le raclage de GlutClosefunc (), qui fonctionne juste après avoir fermé la fenêtre de votre programme. Le contexte existe toujours dans cette fonction, vous pouvez donc détruire correctement les choses là aussi.



0
votes

J'ai fini par utiliser la réponse de Paercebal ci-dessus, avec sa précédente tentative d'utilisation d'un bloc d'essai / attraper autour de GluttMainloop (). Pourquoi? Parce que je voulais nettoyer correctement, peu importe la façon dont il a été arrêté. L'objet contexteur global sera détruit correctement si l'application quitte proprement, ce qui se passe si vous fermez l'application en fermant la fenêtre (ou en quittant l'application sur OS X). Mais si vous frappez CTRL-C dans le terminal où il a été lancé (ou envoyez-le un SIGINT), le nettoyage ne se produit pas. Pour gérer cela, j'ai ajouté ce qui suit à mon code:

signal(SIGINT, sighandler);
glutIdleFunc(idleFunc);

try {
  glutMainLoop();
} catch(...) {}


0 commentaires