Direct3D デバイスの作成
DXUT を初期化し、ウィンドウを作成したら、次の手順はデバイスの作成です。Direct3D 9 API または Direct3D 10 API 呼び出しを使用して直接デバイスを作成するか、DXUT を使用してデバイス作成プロセスを簡略化できます。
- アプリケーションによるデバイスの作成
- DXUT によるデバイスの作成
- 次の手順
アプリケーションによるデバイスの作成
独自のデバイスの作成を選択する場合は、次のどちらかを呼び出すことによってデバイスを作成できます。
- IDirect3D9::CreateDevice を使用して、Direct3D 9 でデバイスを作成します。
- D3D10CreateDevice を使用して、Direct3D 10 でデバイスを作成します。
最初の 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 によって、次の優先順位を使用して最適なデバイス オプションが選択されます。
- ハードウェア アクセラレーション (D3DDEVTYPE_HAL) を選択します。
- 32 ビット フォーマットの場合は、モード変更 (ウィンドウ表示モードから全画面モードへ) が可能な限り高速になるように、アダプターおよびデスクトップ フォーマットを一致させます。
- 32 ビット未満のアダプターおよびデスクトップ フォーマットの場合は、アダプターおよびデスクトップ フォーマットに D3DFMT_X8R8G8B8 を使用します。
- バックバッファー フォーマットをアダプターおよびデスクトップ フォーマットと一致させます。
デバイスの作成には、選択されたこれらの設定の最上位の組み合わせと共に、まだ動作フラグとプレゼンテーション パラメーターが必要となります。Direct3D では、これらの設定のために以下の表で示すような既定値が使用されます。
ModifyDeviceSettings コールバック内のデバイス設定の変更
最適な設定を選択した後に DXUT によって使用されるコールバックがもう 1 つあり、それは設定の変更に使用できます。これは、ModifyDeviceSettings コールバック関数です。このコールバック関数は、DXUTDeviceSettings 構造体を受け取ります。この構造体は、DXUTD3D10DeviceSettings と DXUTD3D9DeviceSettings の共用体です。これには、デバイスの作成に必要なすべてのものが含まれています。構造体の 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 パラメーター |
次の手順
次の手順は、メイン ループの作成です。