Direct3D デバイスの作成

DXUT を初期化し、ウィンドウを作成したら、次の手順はデバイスの作成です。Direct3D 9 API または Direct3D 10 API 呼び出しを使用して直接デバイスを作成するか、DXUT を使用してデバイス作成プロセスを簡略化できます。

  • アプリケーションによるデバイスの作成
  • DXUT によるデバイスの作成
  • 次の手順

アプリケーションによるデバイスの作成

独自のデバイスの作成を選択する場合は、次のどちらかを呼び出すことによってデバイスを作成できます。

最初の 2 つのメソッドには、アダプター、デバイス タイプ、アプリケーション ウィンドウへのハンドル、動作フラグ (ソフトウェア頂点処理/ハードウェア頂点処理、およびその他のドライバー フラグ)、プレゼンテーション パラメーターなどの複数の引数が必要となります。また、プレゼンテーション パラメーターには、バック バッファー、マルチサンプリング、スワップ エフェクト、深度ステンシル バッファーなどの多数のオプションが含まれます。これらすべてのパラメーターに対して有効な設定を選択するという作業は、代わりに DXUT を使用してデバイスを作成することによって、より簡単になります。

デバイスを作成したら、DXUTSetD3D9Device 関数または DXUTSetD3D10Device 関数を使用してそれを DXUT に渡します。メイン ループの完了後にデバイス インターフェイスを解放することを忘れないでください。

DXUT によるデバイスの作成

DXUTCreateDevice を呼び出すことによって、デバイスの作成を簡略化できます。

    HRESULT WINAPI DXUTCreateDevice( 
            bool bWindowed = true, 
            int nSuggestedWidth = 0, 
            int nSuggestedHeight = 0 );

これは、以下の既定値でデバイスを作成することと同じです。DXUT の選択肢の設定をさらに細かく制御するには、デバイス設定をカスタマイズできます。

DXUT は Direct3D 9 と Direct3D 10 の両方で機能するため、DXUT ベースのアプリケーションでは、これらの API のいずれかまたは両方を利用できます。DXUT によってシステム上の Direct3D 10 デバイスが検出され、アプリケーションで Direct3D 9 と Direct3D 10 の両方がサポートされている場合は、既定は Direct3D 10 になります。アプリケーションで Direct3D 10 のみがサポートされているが、Direct3D 10 デバイスが見つからない場合は、DXUT からエラーが返されます。

IsDeviceAcceptable コールバック内のデバイス設定のカスタマイズ

DXUT による最適なデバイス設定を支援するには、IsDeviceAcceptable コールバック関数 (DXUTSetCallbackD3D9DeviceAcceptable または DXUTSetCallbackD3D10DeviceAcceptable のどちらか) を使用して、アプリケーションに適さないすべての設定を除外します。コールバック関数内で、アプリケーションでサポートされていないか必要のないすべての組み合わせを、コールバックで false を返すことによって拒否できます。たとえば、次の例では、16 ビットのバック バッファー フォーマットと、ピクセル シェーダー モデル 2 以降をサポートしていないデバイスを拒否します。

bool CALLBACK IsD3D9DeviceAcceptable(
    D3DCAPS9*     pCaps,
    D3DFORMAT     AdapterFormat,
    D3DFORMAT     BackBufferFormat,
    bool          bWindowed )
{
    if( BackBufferFormat == D3DFMT_X1R5G5B5 || BackBufferFormat == D3DFMT_R5G6B5 )
        return false;
    if( pCaps->PixelShaderVersion < D3DPS_VERSION(2,0) )
        return false;

    return true;
}

すべての組み合わせをテストしたら、DXUT によって、次の優先順位を使用して最適なデバイス オプションが選択されます。

  1. ハードウェア アクセラレーション (D3DDEVTYPE_HAL) を選択します。
  2. 32 ビット フォーマットの場合は、モード変更 (ウィンドウ表示モードから全画面モードへ) が可能な限り高速になるように、アダプターおよびデスクトップ フォーマットを一致させます。
  3. 32 ビット未満のアダプターおよびデスクトップ フォーマットの場合は、アダプターおよびデスクトップ フォーマットに D3DFMT_X8R8G8B8 を使用します。
  4. バックバッファー フォーマットをアダプターおよびデスクトップ フォーマットと一致させます。

デバイスの作成には、選択されたこれらの設定の最上位の組み合わせと共に、まだ動作フラグとプレゼンテーション パラメーターが必要となります。Direct3D では、これらの設定のために以下の表で示すような既定値が使用されます。

ModifyDeviceSettings コールバック内のデバイス設定の変更

最適な設定を選択した後に DXUT によって使用されるコールバックがもう 1 つあり、それは設定の変更に使用できます。これは、ModifyDeviceSettings コールバック関数です。このコールバック関数は、DXUTDeviceSettings 構造体を受け取ります。この構造体は、DXUTD3D10DeviceSettingsDXUTD3D9DeviceSettings の共用体です。これには、デバイスの作成に必要なすべてのものが含まれています。構造体の ver フィールドは、設定の構造体が Direct3D 9 デバイス用か Direct3D 10 デバイス用かを示します。

DXUT によってこの構造体に有効な値が格納され、その後、その構造体が、それをアプリケーションで変更できるコールバック関数に渡されます。このコールバック関数でアプリケーションによって加えられたすべての変更を、必ず検証するようにしてください。次に、深度ステンシル フォーマットを変更する例を示します。

bool CALLBACK ModifyDeviceSettings( 
    DXUTDeviceSettings* pDeviceSettings, 
    void* pUserContext )
{
    if( pDeviceSettings->ver == DXUT_D3D9_DEVICE )
    {
        IDirect3D9* pD3D = DXUTGetD3DObject();
        if( SUCCEEDED( pD3D->CheckDeviceFormat(
                           pDeviceSettings->d3d9.AdapterOrdinal, pDeviceSettings->d3d9.DeviceType,
                           pDeviceSettings->d3d9.AdapterFormat, D3DUSAGE_DEPTHSTENCIL,
                           D3DRTYPE_SURFACE, D3DFMT_D24S8 ) ) )
        {
            if( SUCCEEDED( pD3D->CheckDepthStencilMatch(
                               pDeviceSettings->d3d9.AdapterOrdinal, pDeviceSettings->d3d9.DeviceType,
                               pDeviceSettings->d3d9.AdapterFormat, pDeviceSettings->d3d9.pp.BackBufferFormat,
                               D3DFMT_D24S8 ) ) )
            {
                pDeviceSettings->d3d9.pp.AutoDepthStencilFormat = D3DFMT_D24S8;
            }
        }
    }
    
    return true;
}

次に、フォーマットがサポートされているかどうかを確認するための、CD3D9Enumeration オブジェクトを使用した別の例を示します。

bool CALLBACK ModifyDeviceSettings( 
    DXUTDeviceSettings* pDeviceSettings, 
    void* pUserContext )
{
    if( pDeviceSettings->ver == DXUT_D3D9_DEVICE )
    {
        CD3D9Enumeration *pEnum = DXUTGetD3D9Enumeration();
        CD3D9EnumDeviceSettingsCombo *pCombo;
        
        pCombo = pEnum->GetDeviceSettingsCombo( pDeviceSettings );
        
        if( pCombo->depthStencilFormatList.Contains( D3DFMT_D24S8 ) )
            pDeviceSettings->d3d9.pp.AutoDepthStencilFormat = D3DFMT_D24S8;
    }
        
    return true;
}

これらの両方の例では、アプリケーションによってデバイス設定が変更されてから、DXUT によってデバイスが同じ設定で作成されます。

アプリケーションで true が返されると、DXUT によって通常どおりにデバイス作成が実行されます。false が返されると、デバイスは DXUT によって変更されず、存在する場合は現在のデバイスが保持されます。これは、アプリケーションに、DXUT の要求を拒否して、使用できないデバイスを変更できるようにするために実行されます。たとえば、複数のモニターが存在する構成において、既定でモニター間でのウィンドウのドラッグを可能にすると、DXUT によるデバイスの変更が引き起こされます。しかし、アプリケーションでその他のデバイスを使用できない場合は、この変更を拒否して現在のデバイスを引き続き使用できなければなりません。

ソフトウェア頂点処理へのフォールバック

ハードウェアでピクセル処理 (トランスフォームとライティング) がサポートされているが頂点処理はサポートされていない場合は注意が必要です。よくある誤りの 1 つとして、コールバック関数 (LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE または LPDXUTCALLBACKISD3D10DEVICEACCEPTABLE) で頂点シェーダー バージョンに基づいてデバイスを拒否してしまうことが挙げられます。正しい解決策としては、次のように ModifyDeviceSettings コールバック関数でチェックを実装します。

bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, 
                                    void* pUserContext )
{
    if( pDeviceSettings->ver == DXUT_D3D9_DEVICE )
    {
        D3DCAPS9 caps;
        DXUTGetD3D9DeviceCaps( pDeviceSettings, &caps );
    
        // If device doesn't support HW T&L or doesn't support 1.1 vertex 
        // shaders in HW, then switch to SWVP.
        if( (pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 ||
             pCaps->VertexShaderVersion < D3DVS_VERSION(1,1) )
        {
            pDeviceSettings->d3d9.BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
        }
    
        else
        {
            pDeviceSettings->d3d9.BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
        }
    }
    
    return true; 
}

DXUT での既定のデバイス設定

DXUT では、Direct3D 9 に対して次のような既定の設定が使用されます。

Direct3D 9 プレゼンテーション パラメーター (D3DPRESENT から) 説明 DXUTCreateDevice の 既定値
BackBufferCount バック バッファーの数 2 (トリプル バッファリング)
BackBufferFormat バック バッファー フォーマット デスクトップ ディスプレイ モード、またはデスクトップ ディスプレイ モードが 32 ビット未満の場合は D3DFMT_X8R8G8B8 (D3DFORMAT の 1 つ)
AutoDepthStencilFormat デバイスが作成する自動深度ステンシル サーフェスの深度フォーマット バック バッファー フォーマットが 16 ビット以下の場合は D3DFMT_D16、それ以外の場合は D3DFMT_D32 (D3DFORMAT の 1 つ)
MultiSampleQuality 品質レベル マルチサンプリングが無効の場合は、MultiSampleQuality = 0
Flags プレゼンテーション フラグ D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL (D3DPRESENTFLAG の 1 つ)
PresentationInterval 表示間隔 ウィンドウ表示モードの場合は D3DPRESENT_INTERVAL_IMMEDIATE、全画面モードの場合は D3DPRESENT_INTERVAL_DEFAULT
FullScreen_RefreshRateInHz 画面のリフレッシュ レート ウィンドウ表示モードの場合は 0
BackBufferWidth、BackBufferHeight 表示モードの解像度 ウィンドウ表示モードの場合は 640 x 480 ピクセル、全画面モードの場合はデスクトップの解像度
AutoDepthStencilFormat デバイスが作成する自動深度ステンシル サーフェスのステンシル フォーマット バック バッファー フォーマットが 16 ビット以下の場合は D3DFMT_D16、それ以外の場合は D3DFMT_D32 (D3DFORMAT の 1 つ)
SwapEffect スワップ エフェクト D3DSWAPEFFECT_DISCARD (D3DSWAPEFFECT の 1 つ)
その他の Direct3D パラメーター この API で使用される名前 説明 DXUTCreateDevice の 既定値
AdapterFormat IDirect3D9::CheckDeviceFormat アダプター表面フォーマット デスクトップ ディスプレイ モード、またはデスクトップ ディスプレイ モードが 32 ビット未満の場合は D3DFMT_X8R8G8B8 (D3DFORMAT の 1 つ)
Adapter IDirect3D9::CreateDevice アダプターの序数 D3DADAPTER_DEFAULT
DeviceType IDirect3D9::CreateDevice デバイスの列挙型 利用可能な場合は D3DDEVTYPE_HAL、それ以外の場合は D3DDEVTYPE_REF、どちらも利用できない場合は失敗コード
BehaviorFlags IDirect3D9::CreateDevice 頂点処理フラグ サポートされている場合は D3DCREATE_HARDWARE_VERTEXPROCESSING、それ以外の場合は D3DCREATE_SOFTWARE_VERTEXPROCESSING (D3DCREATE を参照)
hFocusWindow IDirect3D9::CreateDevice ウィンドウ ハンドル DXUTSetWindow の hWndFocus パラメーター

次の手順

次の手順は、メイン ループの作成です。

関連項目

DXUT プログラミング ガイド