Share via


MultiMon10 サンプル

このサンプルでは、Direct3D 10 で複数のモニターを使用する方法を示します。

Bb232914.d3d10_sample_MultiMon10(ja-jp,VS.85).jpg

Path

ソース : SDK ルート\Samples\C++\Direct3D10\MultiMon10
実行可能ファイル : SDK ルート\Samples\C++\Direct3D10\Bin\プラットフォーム\MultiMon10.exe

サンプルが動作するしくみ

このサンプルは、システム上のすべての Direct3D 10 アダプターと出力を列挙することによって動作します。Direct3D 10 でいうアダプターとは、マシンの物理的なディスプレイ ハードウェアのことです。出力とは、その物理的なディスプレイ ハードウェアに接続された出力デバイスです。出力デバイスは、ほとんどの場合モニターになります。ディスプレイ アダプターの多くは、複数の出力が接続されています。たとえば、ビデオ カードの背面に 2 つの DVI コネクタがある場合、Direct3D 10 では通常これを 2 つの出力を持つ 1 つのアダプターとして列挙します。

複数のモニターをレンダリングするために、サンプルでは、アダプターごとに 1 つの Direct3D 10 デバイス、出力ごとに 1 つのスワップチェーンを作成します。たとえば、前述のシステムの場合は、1 つの Direct3D 10 デバイスと、それに接続された 2 つのスワップチェーンを作成します。

アダプターと出力の列挙

EnumerateAdapters 関数を使用して、マシンのディスプレイ アダプターと、それらに接続された出力の両方を列挙します。IDXGIFactory::EnumAdapters は、GDI の列挙関数とほぼ同じように機能します。DXGI_ERROR_NOT_FOUND が返されるまで、この関数にアダプター数をどんどん増やしながら渡していきます。DXGI_ERROR_NOT_FOUND は、これ以上アダプターが存在しないことを暗に示す戻り値です。各アダプターには、接続可能な出力数があります。これらも列挙する必要があります。

MultiMon のセットアップ

アダプターと出力を列挙した後、サンプルは、複数のモニターを使用する一般的なシナリオをセットアップします。まず、各モニター上にウィンドウを 1 つずつ作成します。次に、アダプターごとに Direct3D 10 デバイスを 1 つずつ作成します。アダプターに接続された各出力には、スワップチェーンを 1 つずつ作成します。注意が必要なのは、共有を使用しない限り、1 つのデバイス上に作成されたリソースは、他のデバイスからアクセスできないという点です。この点を明示するために、作成されるデバイスは、それぞれ異なる形状で描画されます。

複数のモニターへのレンダリング

スワップチェーンを各ウィンドウ/出力に関連付けたら、レンダリングを開始できます。RenderToAllMonitors は、各ウィンドウ/出力を順次レンダリングします。特定の出力をレンダリングするには、その出力のスワップチェーンにレンダー ターゲットとビューポートを設定する必要があります。

    // set the render target
    pWindowObj->pDeviceObj->pDevice->OMSetRenderTargets( 1, &pWindowObj->pRenderTargetView, pWindowObj->pDepthStencilView );
    // set the viewport
    D3D10_VIEWPORT Viewport;
    Viewport.TopLeftX = 0;
    Viewport.TopLeftY = 0;
    Viewport.Width = pWindowObj->Width;
    Viewport.Height = pWindowObj->Height;
    Viewport.MinDepth = 0.0f;
    Viewport.MaxDepth = 1.0f;
    pWindowObj->pDeviceObj->pDevice->RSSetViewports( 1, &Viewport );

これが終了したら、ウィンドウ固有のレンダリング関数を呼び出すことができます。PresentToAllMonitors は、ウィンドウに関連付けられた各スワップチェーンでスクリーン上の最終イメージを表示できるようにします。

全画面表示の切り替え

次のサンプルは、DXGI の Alt + Enter ハンドルを使用して、全画面表示とウィンドウ表示を切り替えます。DXGI で Alt + Enter キー操作が制御されている場合、アプリケーションで唯一必要なことは、WM_SIZE メッセージを処理してウィンドウ サイズが変更されたことを認識し、それに従ってバックバッファーのサイズを変更することです。サンプルは、WM_SIZE メッセージを受け取ると、まず、そのメッセージを受け取ったウィンドウ ハンドルに対応する WINDOW_OBJECT を検索します。これが見つかると、レンダー ターゲット ビュー、深度ステンシル ビュー、および深度ステンシル サーフェスを解放します。次に、ウィンドウのクライアント RECT のサイズに基づいて、スワップチェーンのサイズを変更します。最後に、新しいスワップチェーンに合わせて、レンダー ターゲット ビュー、深度ステンシル サーフェス、および深度ステンシル ビューを再作成します。

    DXGI_SWAP_CHAIN_DESC Desc;
    pObj->pSwapChain->GetDesc( &Desc );

    pObj->pSwapChain->ResizeBuffers( Desc.BufferCount,
                                     (UINT)rcCurrentClient.right,
                                     (UINT)rcCurrentClient.bottom,
                                     Desc.BufferDesc.Format,
                                     0 );

    pObj->Width = (UINT)rcCurrentClient.right;
    pObj->Height = (UINT)rcCurrentClient.bottom;

    // recreate the views
    CreateViewsForWindowObject( pObj );