XNAでウィンドウのサイズ変更中にストレッチを停止するにはどうすればよいですか?


8

ウィンドウモードのXNAゲームでは、ユーザーがウィンドウのサイズを変更すると、ゲームがウィンドウの更新を停止し、ユーザーがマウスを離してサイズ変更が完了するまで、最後に描画されたフレームが引き伸ばされて変形します。

サイズ変更イベント中にゲームを「通常」に実行し続け、フレームを更新し、画面を再描画する方法はありますか?

ハードウェア管理リソースが継続的に作成および破棄されるため、サイズ変更中にレンダーループを維持することは不可能または推奨されない可能性があることを理解していますが、醜いストレッチを停止する方法はありますか?理想的には、左上に既存のフレームを拡大縮小せずに残すか、それが不可能な場合は黒い画面にします。


ウィンドウサイズ変更のイベントを登録し、GraphicsDevice解像度を更新します。これにより、アスペクト比が更新され、ストレッチが修正される場合があります。
Gustavo Maciel 2012年

C#/ XNAについては知りませんが、C ++ / D3Dでは、メッセージループを持つメインスレッドとは別のスレッドでレンダーループを実行しました。メインスレッドは、サイズ変更イベントが発生すると、ミューテックスを介して同期され、バッファーのサイズ変更を実行します。

1
グスタボ、私はすでにゲームの他の目的でそのイベントを処理しています。残念ながら、サイズ変更が完了してユーザーがマウスを離すまで起動しません。
Bradley Uffner、2012年

この質問と回答のペアが役立つ場合があります。レンダリングを継続する方法を示します(ただし、ストレッチは修正されません)。
Andrew Russell

回答:


3

追跡できるメッセージは少なくとも3つあります。

  • WM_SIZE-ウィンドウのサイズ変更、ミニ/最大化、フルスクリーン/ウィンドウ切り替え。正確に何が起こったかを知るためにwParamを読み、現在のサイズについてはlParamを読みます。
  • WM_ENTERSIZEMOVE -ウィンドウモードでウィンドウのサイズ変更を開始します
  • WM_EXITSIZEMOVE -ウィンドウモードでウィンドウのサイズ変更を終了する

通常、WM_ENTERSIZEMOVEとWM_EXITSIZEMOVEの間のすべてのフレームでアプリのサイズを変更することは望ましくありません。しかし、それを試してみてください、確かにそれはストレッチよりもうまく、おそらくあなたはそれを好きになるでしょう=)

case WM_SIZE:
    // Save the new client area dimensions.
    m_ptViewportSize.x  = LOWORD(lParam);
    m_ptViewportSize.y = HIWORD(lParam);
    if( wParam == SIZE_MINIMIZED )
    {
        m_bAppSuspended = true;
        m_bMinimized = true;
        m_bMaximized = false;
    }
    else if( wParam == SIZE_MAXIMIZED )
    {
        m_bAppSuspended = false;
        m_bMinimized = false;
        m_bMaximized = true;
        OnResize();
    }
    else if( wParam == SIZE_RESTORED )
    {
        // Restoring from minimized state
        if( m_bMinimized )
        {
            m_bAppSuspended = false;
            m_bMinimized = false;
            OnResize();
        }
        // Restoring from maximized state
        else if( m_bMaximized )
        {
            m_bAppSuspended = false;
            m_bMaximized = false;
            OnResize();
        }
        else if( m_bResizing )
        {
            // Resizing in processs
            // You woldn't wanto to handle a massive stream of
            // WM_SIZE here because buffers resizing is very slow
        }
        else
        {
            // Resizing finished and you can handle it. For ex. with 
            // m_SwapChain->SetFullscreenState
            OnResize();
        }

    }
    return 0;

// WM_EXITSIZEMOVE is sent when the user grabs the resize bars.
case WM_ENTERSIZEMOVE:
    m_bAppSuspended = true;
    m_bResizing  = true;
    g_pTimer->Stop();
    return 0;
// WM_EXITSIZEMOVE is sent when the user releases the resize bars.
// Here we reset everything based on the new window dimensions.
case WM_EXITSIZEMOVE:
    m_bAppSuspended = false;
    m_bResizing  = false;
    g_pTimer->Start();
    OnResize();
    return 0;

1
.NETでのWindowsメッセージの処理には、オーバーライドが含まれますSystem.Windows.Forms.Form.WndProc()。XNAで作業しFormている場合、そのメソッドをオーバーライドするためにに直接アクセスすることはできません。可能ですが、それは簡単な作業ではなく、XNAの設計を回避する必要があります。
サイファー、

誰かがこの方法を選択した場合、このwm_ *定数のリストが役立つことが判明するはずです。pinvoke.net
Cypher

他の人が言ったように、私はまだXNA「エンジン」を短絡させて、正しいイベントの間に再度描画させる方法が必要でしょう。サイズ変更手順の実行中にXNAで "スリープ状態に入る"と言えます。
Bradley Uffner、2012年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.