0

(レンダリングには Ogre3D を使用しますが、質問は一般的なものにする必要があります。)

問題: ほとんどの 3D アプリケーションは、フレームのレンダリングとメッセージのチェックと処理を繰り返すサイクルを使用します。ただし、ダイアログ (MessageBox など) が開かれると、スレッドの実行がブロックされ、独自のメッセージ サイクルが実行されますが、明らかに 3D レンダリング関数は呼び出されません。

ダイアログが開いているときでも 3D シーンのレンダリングを維持するための推奨される、または「最良の」方法は何ですか? 通常のアプリケーションでは、再レンダリングは WM_PAINT メッセージなどによって処理され、モーダル ダイアログには内部メッセージ ループがあるため、必要に応じてウィンドウ プロシージャが呼び出され、すべてが正常に見えるため、この問題に悩まされることはありません。ただし、私の 3D プロジェクトでは、WM_PAINT メッセージがなくてもウィンドウを更新する必要があるため、「必要な場合」は常にです。

頭に浮かぶ簡単な解決策は、ダイアログが開いている時間のタイマーを登録し、WindowProc から 3D シーンをレンダリングすることですが、本当に最善でしょうか? とても汚れているようです...

4

2 に答える 2

3

これが最善の方法かどうかはわかりませんが、うまくいくと思います。

PeekMessageを使用して次のような処理を行うWM_ENTERIDLEのハンドラーを追加します。

case WM_ENTERIDLE:
    while (!PeekMessage())
    {
        DoYourRendering();
    }
    return 0;
于 2012-08-08T21:09:23.260 に答える
1

モーダル操作を開始するときに、コードにカスタムメッセージを送信させることをお勧めします。次に、モーダルループがメッセージをディスパッチするときに現在のフレームをレンダリングし、別のメッセージを投稿してレンダリングループを実行し続けることができます。モーダル操作が終了したら、自分へのメッセージの投稿を停止して、通常のレンダリングロジックに戻ることができます。メニューの場合、モーダルメニューメッセージループがいつ開始および終了するかを検出するために、WM_ENTERMENULOOPおよびメッセージをキャッチできます。WM_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;
于 2012-08-08T21:36:32.483 に答える