【问题标题】:Win32 Main Message Loop for OpenGL [closed]OpenGL的Win32主消息循环[关闭]
【发布时间】:2017-06-11 05:19:09
【问题描述】:

我在 Win32 OpenGL 应用程序中的主消息循环如下所示:

// Inside wWinMain
bool bQuit = false;
while( bQuit == false )
{
    DWORD dwReturn = ::MsgWaitForMultipleObjects( 0, NULL, FALSE, 12, QS_ALLINPUT );

    if( dwReturn == WAIT_OBJECT_0 )
    {
        MSG msg;
        BOOL bReturn = ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE );
        if( bReturn != FALSE )
        {
            if( msg.message == WM_QUIT )
                bQuit = true;
            ::TranslateMessage( &msg );
            ::DispatchMessage( &msg );
        }
    }

    if( dwReturn == WAIT_OBJECT_0 || dwReturn == WAIT_TIMEOUT )
    {
        RenderFrame();
        ::SwapBuffers( hDc );
    }
}

它几乎可以正常工作,我只有一个问题:如果我按 Alt+F4 关闭窗口,释放键后它不会立即退出,但是,如果我将鼠标悬停在窗口上,它会立即退出.

A) 为什么会这样?我应该如何修改我的循环?

B) 我发现的原始代码没有使用MsgWaitForMultipleObjects,而是连续调用了RenderFrame。我认为这种方式在重绘屏幕上浪费了太多的 CPU 时间。我对吗?平时的做法是什么,你是不是把多余的产能都花在了画画上?

【问题讨论】:

  • 请出示真实代码。你的 while( bQuit ) 循环永远不会运行。
  • 看起来我们没有足够的代码。而且这段代码不是真实的。循环永远不会执行。
  • @IInspectable - if( msg.message == WM_QUIT ) bQuit = true; 怎么样?这个和中断循环
  • B) 您想要绘制的频率取决于您绘制的内容。如果您绘制动画,则至少需要 30fps 才能使其流畅。如果您编写游戏,那么输入-显示延迟可能是一个重点,您会希望尽可能频繁地更新视图(或至少以显示器的刷新率,但 vsync 的用途是)。跨度>
  • 看起来像调用PeekMessage 只有一次 但不在循环中while(PeekMessage) MsgWaitForMultipleObjects 代码的非常常见的错误 - 我已经不是第一次看到这个错误了

标签: c++ winapi opengl waitformultipleobjects


【解决方案1】:

您在每个WAIT_OBJECT_0 中调用PeekMessage 的错误只有一次,但您需要在循环while (::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE )) 中运行它,因为我们可以在这里收到多条消息。并更好地使用MsgWaitForMultipleObjectsEx - 试试这个代码:

bool bQuit = false;
while( !bQuit )// for (;;)
{
    MSG msg;

    switch(::MsgWaitForMultipleObjectsEx( 0, NULL, 12, QS_ALLINPUT, 0))
    {
    case WAIT_OBJECT_0:
        while (::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ))
        {
            if( msg.message == WM_QUIT )
                bQuit = true;// return;
            ::TranslateMessage( &msg );
            ::DispatchMessage( &msg );
        }
    case WAIT_TIMEOUT:
        RenderFrame();
        ::SwapBuffers( hDc );
    }
}

如果我按 Alt+F4 关闭窗口,它不会在我关闭后立即退出 松开钥匙

当您按下Alt+F4MsgWaitForMultipleObjects 返回时,有几条消息发布到您的线程队列,但您处理不是全部,而只处理一个

但是,如果我将鼠标悬停在窗口上,它会立即退出

新消息 (WM_MOUSEMOVE) 已放置,但主要 MsgWaitForMultipleObjects 再次返回,您最终会处理与关闭过程相关的所有消息

【讨论】:

  • GetMessage 也做同样正确的事吗?
  • @Raindrop7 当然不能——我们不能在这里使用GetMessage,因为这是同步的,可以等待。我们需要 only PeekMessage 和 in loop while true
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-21
  • 1970-01-01
  • 2011-05-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多