次の方法で共有


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

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

頂点バッファーには、頂点が含まれているため、インデックス化されたプリミティブがあってもなくても頂点バッファーを描画できます。 ただし、インデックス バッファーにはインデックスが含まれているため、対応する頂点バッファーがなければインデックス バッファーを使うことができません。 (サイド ノートとして、IDirect3DDevice9::D rawIndexedPrimitiveUP および IDirect3DDevice9::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) で必要となります。

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

Note

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

 

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

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

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

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

    D3DUSAGE_SOFTWAREPROCESSING フラグは、そのデバイスに対して混合モードまたはソフトウェア頂点処理 (D3DCREATE_MIXED_VERTEXPROCESSING/D3DCREATE_SOFTWARE_VERTEXPROCESSING) が有効になっている場合に設定できます。 混合モードでソフトウェア頂点処理で使用するバッファーには D3DUSAGE_SOFTWAREPROCESSING を設定する必要がありますが、混合モードでハードウェア インデックス処理を使用する場合は、最高のパフォーマンスを得るためにこれを設定しないでください (D3DCREATE_HARDWARE_VERTEXPROCESSING)。 ただし、ハードウェアとソフトウェアの両方の頂点処理で単一のバッファーを使用する場合は、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 つのパラメーターを受け取ります。 最初の 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();

Note

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

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

 

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

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

Direct3D のリソース

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

頂点バッファー (Direct3D 9)