索引緩衝區 (Direct3D 9)
索引緩衝區,由 IDirect3DIndexBuffer9 介面表示,是包含索引數據的記憶體緩衝區。 索引數據或索引是頂點緩衝區的整數位移,可用來使用 IDirect3DDevice9::D rawIndexedPrimitive 方法轉譯基本類型。
頂點緩衝區包含頂點; 因此,您可以使用或不使用索引基本類型來繪製頂點緩衝區。 不過,因為索引緩衝區包含索引,所以您無法在沒有對應的頂點緩衝區的情況下使用索引緩衝區。 (作為側注, IDirect3DDevice9::D rawIndexedPrimitiveUP 和 IDirect3DDevice9::D rawPrimitiveUP 是唯一繪製不含索引或頂點緩衝區的繪製方法。
索引緩衝區描述
索引緩衝區會以其功能來描述,例如其存在於記憶體中的位置、它是否支援讀取和寫入,以及它可以包含的索引類型和數目。 這些特性會保留在D3DINDEXBUFFER_DESC結構中。
索引緩衝區描述會告知您的應用程式如何建立現有的緩衝區。 您可以為系統提供空的描述結構,以填滿先前建立之索引緩衝區的功能。
- Format 成員描述索引緩衝區數據的介面格式。
- Type 會識別索引緩衝區的資源類型。
- Usage 結構成員包含一般功能旗標。 D3DUSAGE_SOFTWAREPROCESSING 旗標表示索引緩衝區要與軟體頂點處理搭配使用。 Usage 中D3DUSAGE_WRITEONLY旗標的存在表示索引緩衝區內存僅用於寫入作業。 這可釋放驅動程式將索引數據放在最佳記憶體位置,以啟用快速處理和轉譯。 如果未使用D3DUSAGE_WRITEONLY旗標,則驅動程式不太可能將數據放在讀取作業效率不佳的位置。 這會犧牲一些處理和轉譯速度。 如果未指定此旗標,則會假設應用程式對索引緩衝區中的數據執行讀取和寫入作業。
- 集區會指定為索引緩衝區配置的記憶體類別。 D3DPOOL_SYSTEMMEM旗標表示系統在系統記憶體中建立了索引緩衝區。
- Size 成員會儲存頂點緩衝區數據的大小,以位元組為單位。
- 不會使用最後一個參數 pSharedHandle。 將它設定為 NULL。
索引處理需求
索引處理作業的效能在很大程度上取決於記憶體中存在索引緩衝區的位置,以及正在使用哪種類型的轉譯裝置。 應用程式會在建立索引緩衝區時控制其記憶體配置。 設定D3DPOOL_SYSTEMMEM記憶體旗標時,會在系統記憶體中建立索引緩衝區。 使用D3DPOOL_DEFAULT記憶體旗標時,設備驅動器會判斷索引緩衝區的記憶體配置最佳位置,通常稱為驅動程式最佳記憶體。 驅動程式優化記憶體可以是本機視訊記憶體、非本機視訊記憶體或系統記憶體。
呼叫 IDirect3DDevice9::CreateIndexBuffer 方法時設定D3DUSAGE_SOFTWAREPROCESSING行為旗標,會指定索引緩衝區要與軟體頂點處理搭配使用。 使用軟體頂點處理時,在混合模式頂點處理中需要此旗標(D3DCREATE_MIXED_VERTEXPROCESSING)。
應用程式可以直接將索引寫入驅動程式最佳記憶體中配置的索引緩衝區。 這項技術可防止稍後進行備援複製作業。 如果您的應用程式從索引緩衝區讀取資料,則這項技術無法正常運作,因為主機從驅動程式優化記憶體完成的讀取作業可能會非常慢。 因此,如果您的應用程式需要在處理期間讀取或將資料寫入緩衝區,則系統記憶體索引緩衝區是較佳的選擇。
注意
請一律使用D3DPOOL_DEFAULT,除非您不想使用視訊記憶體,或在驅動程式將頂點或索引緩衝區放入 AGP 記憶體時,使用大量的頁面鎖定 RAM。
建立索引緩衝區
呼叫可接受六個參數的 IDirect3DDevice9::CreateIndexBuffer 方法來建立索引緩衝區物件。
第一個參數會指定索引緩衝區長度,以位元組為單位。
第二個參數是一組使用控件。 除此之外,其值會決定索引所參考的頂點是否能夠包含裁剪資訊。 若要改善效能,請在不需要裁剪時指定D3DUSAGE_DONOTCLIP。
當該裝置啟用混合模式或軟體頂點處理(D3DCREATE_MIXED_VERTEXPROCESSING/D3DCREATE_SOFTWARE_VERTEXPROCESSING)時,可以設定D3DUSAGE_SOFTWAREPROCESSING旗標。 D3DUSAGE_SOFTWAREPROCESSING必須設定緩衝區,才能與混合模式中的軟體頂點處理搭配使用,但在混合模式中使用硬體索引處理時,不應該設定為最佳效能 D3DCREATE_HARDWARE_VERTEXPROCESSING。 不過,當單一緩衝區同時搭配硬體和軟體頂點處理使用時,設定D3DUSAGE_SOFTWAREPROCESSING是唯一的選項。 混合和軟體裝置允許D3DUSAGE_SOFTWAREPROCESSING。
即使在硬體中完成索引處理,也可以藉由指定 D3DPOOL_SYSTEMMEM,強制將頂點和索引緩衝區強制進入系統記憶體。 當驅動程式將這些緩衝區放入 AGP 記憶體時,這是避免大量頁面鎖定記憶體的方法。
第三個參數是指定每個索引大小的D3DFORMAT列舉型別D3DFMT_INDEX16或D3DFMT_INDEX32成員。
第四個參數是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 方法接受四個參數。 第一個 OffsetToLock 是索引數據的位移。 第二個參數是索引數據的大小,以位元組為單位。 IDirect3DIndexBuffer9::Lock 方法 ppbData 所接受的第三個參數,是在呼叫成功時填入索引數據指標的 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++ 中,因為您直接存取為索引緩衝區配置的記憶體,因此請確定您的應用程式正確地存取配置的記憶體。 否則,您會有將記憶體轉譯為無效的風險。 使用應用程式用來從配置緩衝區中的一個索引移至另一個索引的索引格式的步調。
呼叫 IDirect3DIndexBuffer9::GetDesc 方法來擷取索引緩衝區的相關信息。 這個方法會將索引緩衝區的相關信息填入D3DINDEXBUFFER_DESC結構的成員。
相關主題