【问题标题】:What is the nicest way to close FreeGLUT?关闭 FreeGLUT 最好的方法是什么?
【发布时间】:2011-06-29 08:42:31
【问题描述】:

我在使用 FreeGLUT 关闭控制台应用程序时确实遇到了麻烦。

我想知道最好的方法是采取所有可能的关闭方式,因为我不想要任何内存泄漏(我很害怕那些)。

所以我已经尝试了以下方法,这给了我这样的异常:

myProject.exe 中 0x754e6a6f 处的第一次机会异常: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 C++ 中。

更新

我发现抛出了异常,因为我在调试。所以这不会是一个问题。但问题仍然悬而未决:真正关闭过剩的最优雅方法是什么?

atexit() 似乎也可以,所以也许我可以使用它?

【问题讨论】:

  • 当您的程序关闭时,您无需担心释放内存,操作系统会回收所有内容并且不会泄漏任何内容。当然,像文件这样的持久性资源仍然应该被正确清理。
  • atexit() 可能无法解决您的 C++ 对象清理问题。
  • @Ben, @wilhelmtell:但我应该清除我的keyboardManager 对象,因为我的Progam 拥有一个指向它的指针,对吧?
  • 如果它使用了一些在程序终止后仍然存在的资源,是的。但是操作系统将回收内存并且还应该撤销键盘输入捕获,因此键盘管理器可能不需要清理。甚至有一种观点认为也不清理持久性资源,理由是最终你的清理将没有机会运行(可能是灾难性的电源故障),所以你需要逻辑来恢复脏状态。如果你能处理脏状态,那么任何清理都只是浪费时间。
  • 如果您关心 opengl 泄漏(比如说您正在重新创建东西或者您多次启动并拆除 OpenGL),那么您可以使用GDebugger 报告所有泄漏的 OpenGL 对象。它还会报告您可能做错的各种有用的事情,例如冗余状态更改或使用已弃用的功能。

标签: c++ opengl console-application glut freeglut


【解决方案1】:

试试这个方法:

glutDestroyWindow(glutGetWindow());

【讨论】:

    【解决方案2】:

    感谢 Maarten 的帖子,这对我有用:

    glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,GLUT_ACTION_CONTINUE_EXECUTION);
    

    当您想离开主循环而不终止应用程序使用时:

    glutLeaveMainLoop();
    

    不要忘记包含“freeglut.h”

    【讨论】:

      【解决方案3】:

      我用glutDestroyWindow(int handle);

      根据 ID:OpenGL 论坛上的 RigidBody

      void destroy_window() 
      {
       window_valid = -1;
      }
      
      void display_func() 
      {
       if(window_valid == -1)
         return;
       // draw things
      }
      

      【讨论】:

        【解决方案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 是安全的,无需检查。

        【讨论】:

        • 看起来确实很有趣。所以我可以在SetConsoleCtrlHandler 和keychecker 中调用这个函数来检查ESC。那么我可以把我的指针删除器放在主函数中吗?
        • 最好设置 glutCloseFunc 来调用清理函数。 FreeGLUT 会在尝试拆除上下文之前调用它,这与在主循环之后执行它不同。
        • 好吧,根据最新的 GLUT 规范 (3.7),glutLeaveMainLoop() 不再存在。那么现在OP的问题的答案是什么?
        • glutLeaveMainLoop 仍然存在于 FreeGLUT 中(我相信 OpenGLUT,虽然未经验证,但他们的 subwin 示例使用它)。使用最新的稳定版本 3.0.0 进行测试 - 它是常规 GLUT 的扩展。
        • Ubuntu 有它,但有一个技巧。 Ubuntu 上的 GLUT 都是 FreeGLUT,FreeGLUT 分为 _std 和 _ext 头文件。如果您包含GL/glut.h,它只包含freeglut_std.h。您必须改为包含 GL/freeglut.h,这包括 _std 和 freeglut_ext.h 标头,然后您会得到 glutLeaveMainLoop()
        猜你喜欢
        • 1970-01-01
        • 2010-10-10
        • 1970-01-01
        • 1970-01-01
        • 2010-10-04
        • 2014-05-27
        • 2011-10-09
        • 2021-01-13
        • 1970-01-01
        相关资源
        最近更新 更多