在模态对话框/打开主菜单期间保持渲染3D窗口?

时间:2012-08-08 17:40:18

标签: windows winapi 3d modal-dialog windows-messages

(我使用Ogre3D进行渲染,但问题应该是通用的。)

问题:大多数3D应用程序使用循环来迭代渲染帧并检查消息并处理它们。但是,如果打开一个对话框(MessageBox或类似的对象),它会阻止线程的执行并运行它自己的消息周期,但它显然不会调用其中的3D渲染函数。

即使对话框打开,保持渲染3D场景的首选或“最佳”方式是什么?普通的应用程序不会遇到这个问题,因为它们的重新渲染是由WM_PAINT消息等处理的,并且由于模态对话框确实有内部消息循环,所以在需要时调用窗口proc并且一切看起来都很好。然而,在我的3D项目中,“需要时”始终是,因为即使没有WM_PAINT消息,窗口也必须更新。

想到的简单解决方案是在对话框打开时注册计时器,并从WindowProc渲染3D场景,但它真的是最好的吗?看起来很脏......

2 个答案:

答案 0 :(得分:2)

我不知道这是最好的方式,但我认为它会起作用。

WM_ENTERIDLE添加一个处理程序,使用PeekMessage执行以下操作:

case WM_ENTERIDLE:
    while (!PeekMessage())
    {
        DoYourRendering();
    }
    return 0;

答案 1 :(得分:1)

我建议让代码在进入模态操作时向自己发布自定义消息。然后,您可以在模态循环调度消息时呈现当前帧,然后发布另一条消息以保持渲染循环运行。模态操作完成后,您可以停止向自己发布消息并返回到正常的渲染逻辑。对于菜单,您可以捕获WM_ENTERMENULOOPWM_EXITMENULOOP消息,以检测模式菜单消息循环何时开始和结束。

例如:

const UINT WM_RENDER_FRAME = WM_USER+100:

BOOL m_InModalOp = FALSE;

case WM_ENTERMENULOOP:
    m_InModalOp = TRUE;
    PostMessage(hwnd, WM_RENDER_FRAME, 0, 0);
    break;

case WM_EXITMENULOOP:
    m_InModalOp = FALSE;
    break;

case WM_RENDER_FRAME:
    if (m_InModalOp)
    {
        // render a frame...
        PostMessage(hwnd, WM_RENDER_FRAME, 0, 0);
    }
    break;

m_InModalOp = TRUE;
PostMessage(hwnd, WM_RENDER_FRAME, 0, 0);
MessageBox(...);
m_InModalOp = FALSE;