Platform SDK: DirectX

列挙されたデバイスの選択

[C++]

C++ の場合、Direct3D は、アプリケーションに用意されている D3DEnumDevicesCallback7 関数を、システムにインストールされている各 Direct3D デバイスに対して呼び出す。この関数の呼び出しでは、第 1 パラメータはデバイスを説明する文字列で、第 2 パラメータは分かりやすいデバイス名を示す文字列である。

第 3 パラメータは、デバイスのハードウェア機能についての情報を格納する D3DDEVICEDESC7 構造体へのポインタである。列挙されるデバイスが HAL デバイスであっても、Direct3D で使用可能な機能を特定のハードウェアがすべてサポートするとは限らない。最後のパラメータは、プログラマが定義する値である。アプリケーションでは、この値を IDirect3D7::EnumDevices メソッドに渡す。次に、この値を D3DEnumDevicesCallback7 関数に渡す。

次のコードは、D3DEnumDevicesCallback7 関数の作成方法を示す。この例では、アプリケーションに用意されているコールバック関数の名前を EnumDeviceCallback とする。EnumDeviceCallback 関数では、以下のアルゴリズムを使用して、適切な Direct3D デバイスを選択する。

  1. 現在のディスプレイ深度に一致しないデバイスをすべて廃棄する。
  2. 三角形をグーロー シェーディング処理できないデバイスをすべて廃棄する。
  3. 上の 1 と 2 に当てはまらないハードウェア デバイスがあれば、それを使用する。ただし、アプリケーションをデバッグ モードで実行している場合は、ハードウェア デバイスは使用しない。

EnumDeviceCallback 関数のコード例を以下に示す。

// この関数では、次のグローバル変数が
// プログラムで宣言されているとする。
// DWORD                   g_dwDeviceBitDepth          = 0; 
// GUID                    g_guidDevice; 
// char                    g_szDeviceName[MAX_PATH]; 
// char                    g_szDeviceDesc[MAX_PATH]; 
// D3DDEVICEDESC7          g_d3dDeviceDesc; 
 
static HRESULT WINAPI 
EnumDeviceCallback(LPSTR            lpszDeviceDesc, 
                   LPSTR            lpszDeviceName, 
                   LPD3DDEVICEDESC7 lpd3dEnumDeviceDesc, 
                   LPVOID           lpUserArg) 
{ 
    BOOL fIsHardware = FALSE;

    fIsHardware = (lpd3dEnumDeviceDesc->dwDevCaps & D3DDEVCAPS_HWRASTERIZATION); 

// デバイスのレンダリングが希望の深度で行われるかどうか。
    if ((lpd3dEnumDeviceDesc->dwDeviceRenderBitDepth & g_dwDeviceBitDepth) == 0) 
    { 
// そうでなければ、このデバイスはスキップする。
 
        return D3DENUMRET_OK; 
    } 
 
// デバイスは、グーロー シェーディング処理した三角形をサポートする必要がある。
    if (!(lpd3dEnumDeviceDesc->dpcTriCaps.dwShadeCaps & 
          D3DPSHADECAPS_COLORGOURAUDRGB)) 
    { 
// グーロー シェーディングをサポートしていない。このデバイスはスキップする。
 
        return D3DENUMRET_OK; 
    } 
  
    //
// このデバイスは必要な機能を備えている。詳細を保存する。
    //
    *(BOOL*)lpUserArg = TRUE; 
    CopyMemory(&g_guidDevice, &lpd3dEnumDeviceDesc->deviceGUID, sizeof(GUID)); 
    strcpy(g_szDeviceDesc, lpszDeviceDesc); 
    strcpy(g_szDeviceName, lpszDeviceName); 
    CopyMemory(&g_d3dDeviceDesc, lpd3dEnumDeviceDesc, 
               sizeof(D3DDEVICEDESC7)); 
 
// これがハードウェア デバイスの場合、
// 必要な機能を備えている。
    if (fIsHardware) 
        return D3DENUMRET_CANCEL; 
 
// そうでなければ、検索を続ける。
 
    return D3DENUMRET_OK; 
} 
[Visual Basic]

Visual Basic では、Direct3DEnumDevices クラスによって、システムにインストールされている Direct3D デバイスを列挙する。このクラスに問い合わせを行い、クラス内の列挙されるデバイスをそのインデックスで識別することで、各デバイスの情報を取得する。デバイスのインデックスは、最初のデバイスには 1、2 つ目のデバイスには 2、という順序で付く。Direct3DEnumDevices.GetCount メソッドは、列挙されるデバイスの数、つまり最大許容インデックス値を返す。

列挙されるデバイスの GUID をテキスト文字列として取得するには、Direct3DEnumDevices.GetGuid メソッドを呼び出す。文字列はデバイスごとに異なる。

デバイスの名前と分かりやすい説明を含むテキスト文字列を取得するには、Direct3DEnumDevices.GetName および Direct3DEnumDevices.GetDescription メソッドを呼び出す。

D3DDEVICEDESC7 型の形式でデバイスの機能についての説明を取得するには、Direct3DEnumDevices.GetDesc メソッドを呼び出す。列挙されるデバイスがハードウェア デバイスであっても、Direct3D API で使用可能な機能を特定のハードウェアがすべてサポートするとは限らない。

次のコードは、デバイス機能を決定するために Direct3DEnumDevices クラスのメソッドを呼び出す関数の作成方法を示す。この例のアプリケーション定義関数では、以下のアルゴリズムを使用して、適切な Direct3D デバイスを選択する。

  1. 現在のディスプレイ深度に一致しないデバイスをすべて廃棄する。
  2. 三角形をグーロー シェーディング処理できないデバイスをすべて廃棄する。
  3. 上の 1 と 2 に当てはまらないハードウェア デバイスがあれば、それを使用する。
Private Sub EnumerateDevices(d3denum As Direct3DEnumDevices)
' この例では、以下のグローバル変数が宣言されているとする。
'   g_lDeviceBitDepth は希望のビット深度を表す (CONST_DDBITDEPTHFLAGS の定数の組み合わせ)。
'   g_DeviceDesc にはデバイス機能を表す D3DDEVICEDESC7 が格納される。
'   g_strDeviceGUID にはデバイスの GUID 文字列が格納される。
'   g_strDeviceDescription にはデバイスを説明するテキスト文字列が格納される。
'   g_strDeviceName にはデバイス名を表す文字列が格納される。
    
' デバイスの列挙に使用するローカル変数。
Dim iDevice As Integer
Dim DevDesc As D3DDEVICEDESC7
Dim bIsHardware As Boolean
    
' デバイスの列挙を開始する。
For iDevice = 1 To d3denum.GetCount
Dim checkDesc As D3DDEVICEDESC7
Call d3denum.GetDesc(iDevice, DevDesc)
        
' このデバイスで使用する機能がハードウェアでサポートされていない場合
bIsHardware = (DevDesc.lDevCaps Or D3DDEVCAPS_HWRASTERIZATION)
        
' デバイスのレンダリングが希望の深度で行われるかどうか。行われない場合は中止する。
' チェックを行い、次のデバイスを取得する。
If checkDesc.lDeviceRenderBitDepth And Not g_lDeviceBitDepth Then
GoTo NEXT_DEVICE
End If
        
' デバイスは、グーロー シェーディング処理した三角形をサポートする必要がある。
If (Not checkDesc.dpcTriCaps.lShadeCaps And D3DPSHADECAPS_COLORGOURAUDRGB) Then
' RGB モードのグーロー シェーディングをサポートしていない。このデバイスはスキップする。
GoTo NEXT_DEVICE
End If
        
        '
' ここに処理が達するまでに適切なデバイスが検出される。
' その結果をグローバル変数に格納する。
        '
g_strDeviceGUID = d3denum.GetGuid(iDevice)
g_strDeviceDescription = d3denum.GetDescription(iDevice)
g_strDeviceName = d3denum.GetName(iDevice)
g_DeviceDesc = DevDesc
                
' この現在のデバイスがハードウェア アクセラレーションを備えている場合、
' これは適切なデバイスである。
If bIsHardware = True Then Exit For
        
' ハードウェア アクセラレーションを備えていない場合は処理を次に移す。
NEXT_DEVICE:
Next iDevice
End Sub ' EnumerateDevices