次の方法で共有


インデックス バッファー (Direct3D 9)

IDirect3DIndexBuffer9 インターフェイスによって表されるインデックス バッファーは、インデックス データを含むメモリ バッファーです。 インデックス データ (インデックス) は頂点バッファーへの整数オフセットであり、 IDirect3DDevice9::D rawIndexedPrimitive メソッドを使用してプリミティブをレンダリングするために使用されます。

頂点バッファーには、頂点が含まれているため、インデックス化されたプリミティブがあってもなくても頂点バッファーを描画できます。 ただし、インデックス バッファーにはインデックスが含まれているため、対応する頂点バッファーがなければインデックス バッファーを使うことができません。 (サイド ノートとして、 IDirect3DDevice9::D rawIndexedPrimitiveUPIDirect3DDevice9::D rawPrimitiveUP は、インデックスまたは頂点バッファーなしで描画する唯一の描画メソッドです)。

インデックス バッファーの記述

インデックス バッファーは、メモリ内のどこに存在するか、読み取りと書き込みをサポートするかどうか、含めることができるインデックスの種類と数など、機能の観点から記述されます。 これらの特徴は 、D3DINDEXBUFFER_DESC 構造に保持されます。

インデックス バッファーの記述は、既存のバッファーがどのように作成されたかをアプリケーションに示します。 以前に作成されたインデックス バッファーを埋めるには、システムに空の記述構造を提供します。

  • Format メンバーは、インデックス バッファー データのサーフェス形式を記述します。
  • Type は、インデックス バッファーのリソースの種類を識別します。
  • Usage 構造体メンバーには、一般的な機能フラグが含まれています。 D3DUSAGE_SOFTWAREPROCESSING フラグは、インデックス バッファーがソフトウェア頂点処理で使用されることを示します。 Usage にD3DUSAGE_WRITEONLY フラグが存在することは、インデックス バッファー メモリが書き込み操作にのみ使用されることを示します。 これにより、ドライバーはインデックス データを最適なメモリ位置に配置して、高速な処理とレンダリングを可能にします。 D3DUSAGE_WRITEONLY フラグを使用しない場合、ドライバーは読み取り操作に非効率的な場所にデータを配置する可能性が低くなります。 これにより、処理とレンダリング速度が低下します。 このフラグを指定しない場合、アプリケーションはインデックス バッファー内のデータに対して読み取り操作と書き込み操作を実行すると見なされます。
  • Pool は、インデックス バッファーに割り当てられるメモリ クラスを指定します。 D3DPOOL_SYSTEMMEM フラグは、システムがシステム メモリにインデックス バッファーを作成したことを示します。
  • Size メンバーは、頂点バッファー データのサイズをバイト単位で格納します。
  • 最後のパラメーター pSharedHandle は使用されません。 これを NULL に設定します。

インデックス処理の要件

インデックス処理操作のパフォーマンスは、インデックス バッファーがメモリ内のどこに存在するかと、使われるレンダリング デバイスの種類に大きく依存します。 アプリケーションは、インデックス バッファーの作成時にそのメモリ割り当てを制御します。 D3DPOOL_SYSTEMMEM メモリ フラグが設定されると、インデックス バッファーがシステム メモリに作成されます。 D3DPOOL_DEFAULT メモリ フラグを使用すると、デバイス ドライバーは、インデックス バッファーのメモリが最適に割り当てられる場所 (ドライバー最適メモリと呼ばれることがよくあります) を決定します。 ドライバーに最適なメモリは、ローカル ビデオ メモリ、ローカル以外のビデオ メモリ、またはシステム メモリです。

IDirect3DDevice9::CreateIndexBuffer メソッドを呼び出すときにD3DUSAGE_SOFTWAREPROCESSING動作フラグを設定すると、インデックス バッファーをソフトウェア頂点処理で使用するように指定します。 このフラグは、ソフトウェア頂点処理を使用する場合に、混合モードの頂点処理 (D3DCREATE_MIXED_VERTEXPROCESSING) に必要です。

アプリケーションは、ドライバー用に最適化されたメモリに割り当てられたインデックス バッファーにインデックスを直接書き込みます。 この手法を使うと、後で冗長コピー操作を実行できなくなります。 アプリケーションがインデックス バッファーからデータを読み戻す場合、この手法は適切に機能しません。ドライバー用に最適化されたメモリからホストにより実行される読み取り操作は非常に遅いためです。 したがって、アプリケーションがデータの処理時に読み取りを行う必要がある場合や、バッファーにデータを不規則に書き込む場合、システム メモリ インデックス バッファーの方が適しています。

注意

ドライバーが頂点バッファーまたはインデックス バッファーを AGP メモリに配置する場合は、ビデオ メモリを使用しない場合や大量のページ ロック RAM を使用する場合を除き、常にD3DPOOL_DEFAULTを使用します。

 

インデックス バッファーを作成する

6 つのパラメーターを受け取る IDirect3DDevice9::CreateIndexBuffer メソッドを呼び出して、インデックス バッファー オブジェクトを作成します。

  • 最初のパラメーターは、インデックス バッファーの長さをバイト単位で指定します。

  • 2 番目のパラメーターは、使用コントロールのセットです。 特に、その値は、インデックスによって参照される頂点がクリッピング情報を格納できるかどうかを決定します。 パフォーマンスを向上させるには、クリッピングが不要な場合にD3DUSAGE_DONOTCLIPを指定します。

    D3DUSAGE_SOFTWAREPROCESSING フラグは、そのデバイスに対して混合モードまたはソフトウェア頂点処理 (D3DCREATE_MIXED_VERTEXPROCESSING/D3DCREATE_SOFTWARE_VERTEXPROCESSING) が有効になっている場合に設定できます。 D3DUSAGE_SOFTWAREPROCESSINGは、混合モードでのソフトウェア頂点処理で使用するバッファーに設定する必要がありますが、混合モード (D3DCREATE_HARDWARE_VERTEXPROCESSING) でハードウェア インデックス処理を使用する場合は、可能な限り最高のパフォーマンスを得るために設定しないでください。 ただし、ハードウェアとソフトウェアの両方の頂点処理で 1 つのバッファーを使用する場合は、D3DUSAGE_SOFTWAREPROCESSINGの設定のみがオプションです。 D3DUSAGE_SOFTWAREPROCESSINGは、混合デバイスとソフトウェア デバイスに対して許可されます。

    ハードウェアでインデックス処理が行われている場合でも、D3DPOOL_SYSTEMMEMを指定することで、頂点バッファーとインデックス バッファーをシステム メモリに強制的に挿入できます。 これは、ドライバーがこれらのバッファーを AGP メモリに配置するときに、過度に大量のページ ロック メモリを回避する方法です。

  • 3 番目のパラメーターは、各インデックスのサイズを指定する D3DFORMAT 列挙型のD3DFMT_INDEX16またはD3DFMT_INDEX32 メンバーです。

  • 4 番目のパラメーターは、新しいインデックス バッファーを配置するメモリ内の場所をシステムに指示する D3DPOOL 列挙型のメンバーです。

  • IDirect3DDevice9::CreateIndexBuffer が受け取る最後のパラメーターは、呼び出しが成功した場合に、頂点バッファー オブジェクトの新しい IDirect3DIndexBuffer9 インターフェイスへのポインターで埋められた変数のアドレスです。

次の C++ コード例は、インデックス バッファーを作成するコードの外観を示しています。

/*
 * For the purposes of this example, the d3dDevice variable is the 
 * address of an IDirect3DDevice9 interface exposed by a 
 * Direct3DDevice object, g_IB is a variable of type 
 * LPDIRECT3DINDEXBUFFER9.
 */

if( FAILED( d3dDevice->CreateIndexBuffer( 16384 *sizeof(WORD),
           D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, 
           &g_IB, NULL ) ) )
    return E_FAIL;

インデックス バッファーにアクセスする

インデックス バッファー オブジェクトを使用すると、アプリケーションはインデックス データに割り当てられたメモリに直接アクセスできます。 インデックス バッファー メモリへのポインターを取得するには、 IDirect3DIndexBuffer9::Lock メソッドを呼び出し、必要に応じてメモリにアクセスして、バッファーに新しいインデックス データを入力するか、格納されているデータを読み取ります。 Lock メソッドは、4 つのパラメーターを受け入れます。 1 つ目の OffsetToLock は、インデックス データへのオフセットです。 2 番目のパラメーターは、インデックス データのサイズ (バイト単位) です。 IDirect3DIndexBuffer9::Lock メソッド ppbData で受け入れられる 3 番目のパラメーターは、呼び出しが成功した場合にインデックス データへのポインターが入力された BYTE ポインターのアドレスです。

最後のパラメーター Flags は、メモリをロックする方法をシステムに指示します。 これを使用して、アプリケーションがバッファー内のデータにアクセスする方法を示すことができます。 アプリケーションがインデックス データにアクセスする方法に従って、 Flags パラメーターの定数を指定します。 これにより、ドライバーはメモリをロックし、要求されたアクセスの種類に応じて最高のパフォーマンスを提供できます。 アプリケーションがインデックス バッファー メモリからのみ読み取る場合は、D3DLOCK_READONLY フラグを使用します。 このフラグを含めると、メモリへのアクセスが読み取り専用になる場合、Direct3D は内部プロシージャを最適化して効率を向上させることができます。

インデックス データを入力または読み取った後、次のコード例に示すように 、IDirect3DIndexBuffer9::Unlock メソッドを呼び出します。

// This code example assumes the m_pIndexBuffer is a variable of type 
// LPDIRECT3DINDEXBUFFER9 and that g_Indices has been properly 
// initialized with indices.

// To fill the index buffer, you must lock the buffer to gain 
// access to the indices. This mechanism is required because index
// buffers may be in device memory.

VOID* pIndices;

if( FAILED( m_pIndexBuffer->Lock( 
      0,                 // Fill from start of the buffer
      sizeof(g_Indices), // Size of the data to load
      BYTE**)&pIndices,  // Returned index data
      0 ) ) )            // Send default flags to the lock
{
    SAFE_RELEASE(m_pIndexBuffer);
    return E_FAIL;
}

memcpy( pIndices, g_Indices, sizeof(g_Indices) );
m_pIndexBuffer->Unlock();

注意

D3DUSAGE_WRITEONLY フラグを使用してインデックス バッファーを作成する場合は、D3DLOCK_READONLYロック フラグを使用しないでください。 アプリケーションがインデックス バッファー メモリからのみ読み取る場合は、D3DLOCK_READONLY フラグを使用します。 このフラグを含めると、メモリへのアクセスが読み取り専用になる場合、Direct3D は内部プロシージャを最適化して効率を向上させることができます。

IDirect3DIndexBuffer9::Lock メソッドの Flags パラメーターにD3DLOCK_DISCARDまたはD3DLOCK_NOOVERWRITEを使用する方法については、「パフォーマンスの最適化 (Direct3D 9)」を参照してください。

 

C++ では、インデックス バッファーに割り当てられたメモリに直接アクセスするため、アプリケーションが割り当てられたメモリに適切にアクセスしていることを確認します。 それ以外の場合は、そのメモリが無効なレンダリングのリスクがあります。 アプリケーションで使用するインデックス形式のストライドを使用して、割り当てられたバッファー内の 1 つのインデックスから別のインデックスに移動します。

IDirect3DIndexBuffer9::GetDesc メソッドを呼び出して、インデックス バッファーに関する情報を取得します。 このメソッドは、インデックス バッファーに関する情報を D3DINDEXBUFFER_DESC 構造体のメンバーに入力します。

Direct3D リソース

頂点バッファーとインデックス バッファーからのレンダリング (Direct3D 9)

頂点バッファー (Direct3D 9)