Как лучше всего закрыть FreeGLUT?

У меня действительно проблемы с закрытием консольного приложения с помощью FreeGLUT.

Я хотел бы знать, как лучше всего использовать все возможные закрытия, потому что я не хочу никаких утечек памяти (я их очень боюсь).

Итак, я уже пробовал следующее, что дает мне такое исключение:

Исключение первого шанса по адресу 0x754e6a6f в myProject.exe: 0x40010005: Control-C.

int main(int argc, char **argv)
{
    if( SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, true) )
    {
        // more code here as well ....


        glutCloseFunc(close); // set the window closing function of opengl
        glutMainLoop();
        close(); // close function if coming here somehow
    }
    else
    {
        return 1;
    }
    return 0;
}

void close()
{
    // keyboardManager is a pointer to a class
    // which I want to delete, so no memory will leak.
    if(keyboardManager) // do I need this check?
        delete keyboardManager;
}

bool CtrlHandler(DWORD fdwCtrlType)
{
    switch(fdwCtrlType)
    {
        // Handle the CTRL-C signal.
        case CTRL_C_EVENT:
        // and the close button
        case CTRL_CLOSE_EVENT:
          close();
          return true;

        // Pass other signals to the next handler. 
        case CTRL_BREAK_EVENT:
            return false;

    // delete the pointer anyway
        case CTRL_LOGOFF_EVENT:
        case CTRL_SHUTDOWN_EVENT:
        default:
            close();
            return false; 
    } 
}

Итак, что происходит правильно:

  1. Закрытие окна перенасыщения
  2. Закрытие консольного приложения с помощью x
  3. Закрытие моего окна перенасыщения с помощью моего менеджера по клавиатуре if(keyboardManager->isKeyDown[27]) glutExit();

Что идет не так:

  1. Закрытие консольного приложения с помощью CTRL+C дает исключение из приведенного выше.

Это в Visual Studio 2008 С++.

ОБНОВИТЬ

Я обнаружил, что возникает исключение, потому что я в отладке. Так что это не будет проблемой. Но вопрос все еще остается открытым: Какой самый элегантный способ действительно закрыть перенасыщение?

atexit() тоже работает, так что, может быть, я могу использовать это?


person Marnix    schedule 17.02.2011    source источник
comment
Вам не нужно беспокоиться об освобождении памяти, когда ваша программа закрывается, ОС восстанавливает все и ничего не утекает. Конечно, постоянные ресурсы, такие как файлы, все равно должны быть правильно очищены.   -  person Ben Voigt    schedule 18.02.2011
comment
atexit() скорее всего не решит вашу проблему с очисткой объектов C++.   -  person wilhelmtell    schedule 18.02.2011
comment
@Ben, @wilhelmtell: Но я должен, например, очистить свой объект keyboardManager, потому что моя программа содержит указатель на него, верно?   -  person Marnix    schedule 18.02.2011
comment
Если он использует некоторые ресурсы, которые переживут завершение вашей программы, да. Но ОС освободит память, а также должна отменить захват ввода с клавиатуры, поэтому диспетчер клавиатуры, вероятно, не нуждается в очистке. Существует даже школа мысли, которая говорит, что не следует также очищать постоянные ресурсы, обосновывая это тем, что в конечном итоге ваша очистка не получит возможности запуститься (возможно, катастрофический сбой питания), поэтому вам нужна логика для восстановления грязного состояния. И если с грязным состоянием можно справиться, то любая очистка — пустая трата времени.   -  person Ben Voigt    schedule 18.02.2011
comment
Если вас беспокоят утечки opengl (скажем, вы воссоздаете что-то или запускаете и отключаете OpenGL более одного раза), вы можете использовать GDebugger, чтобы сообщать обо всех просочившихся объектах OpenGL. Он также сообщает о всевозможных полезных вещах, которые вы, возможно, делаете неправильно, таких как избыточные изменения состояния или использование устаревших функций.   -  person doug65536    schedule 04.03.2013


Ответы (4)


Я использую эту функцию:

void glutLeaveMainLoop ( void ); 

На их странице sourceforge есть дополнительная информация, но я никогда не использовал эту функцию:

Функция glutLeaveMainLoop заставляет freeglut останавливать цикл обработки событий. Если для параметра GLUT_ACTION_ON_WINDOW_CLOSE установлено значение GLUT_ACTION_CONTINUE_EXECUTION, управление вернется к функции, которая вызвала glutMainLoop; в противном случае приложение будет закрыто.

http://freeglut.sourceforge.net/docs/api.php#EventProcessing

Безопасно использовать delete для нулевого указателя, нет необходимости проверять.

person Maarten    schedule 21.02.2011
comment
Кажется действительно интересным. Так что я мог бы вызвать эту функцию в SetConsoleCtrlHandler и в программе проверки ключей для проверки ESC. Так что, возможно, я мог бы поместить средства удаления указателя в основную функцию? - person Marnix; 21.02.2011
comment
Гораздо лучше настроить glutCloseFunc для вызова очищающей функции. FreeGLUT вызовет его до того, как попытается разорвать контекст, в отличие от выполнения этого после основного цикла. - person doug65536; 04.03.2013
comment
На самом деле не так уж сложно правильно выполнить очистку, но если вы используете такой инструмент, как GDebugger, который жалуется, если вы не выполняете очистку, вы можете использовать glutCloseFunc для получения чистых прогонов. - person doug65536; 04.03.2013
comment
Итак, согласно последней спецификации GLUT (3.7), glutLeaveMainLoop() больше не существует. Итак, каков будет ответ на вопрос ОП? - person Anish Ramaswamy; 20.09.2013
comment
glutLeaveMainLoop все еще существует в FreeGLUT (и я верю, что OpenGLUT, хотя и непроверенный, но их образец subwin использует его). Протестировано с последней стабильной версией 3.0.0 - это расширение для обычного GLUT. - person ZXcvbnM; 18.10.2015
comment
У Ubuntu это есть, но есть хитрость. GLUT в Ubuntu — это полностью FreeGLUT, а FreeGLUT разделен на заголовочные файлы _std и _ext. Если вы включаете GL/glut.h, он просто включает freeglut_std.h. Вместо этого вы должны включить GL/freeglut.h, включая заголовки _std и freeglut_ext.h, и тогда вы получите glutLeaveMainLoop(). - person Blair Houghton; 26.10.2015

Благодаря сообщению Маартена это работает для меня:

glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,GLUT_ACTION_CONTINUE_EXECUTION);

всякий раз, когда вы хотите выйти из основного цикла без прерывания использования приложения:

glutLeaveMainLoop();

не забудьте включить "freeglut.h"

person Amit    schedule 29.09.2016

Я использую glutDestroyWindow(int handle);

or

Согласно ID: RigidBody на форуме OpenGL

void destroy_window() 
{
 window_valid = -1;
}

void display_func() 
{
 if(window_valid == -1)
   return;
 // draw things
}
person Cloud Cho    schedule 06.07.2016

Попробуйте этот метод:

glutDestroyWindow(glutGetWindow());
person malin    schedule 01.10.2018