Indexpuffer (Direct3D 9)

Indexpuffer, die durch die IDirect3DIndexBuffer9-Schnittstelle dargestellt werden, sind Speicherpuffer, die Indexdaten enthalten. Indexdaten oder Indizes sind ganzzahlige Offsets in Vertexpuffer und werden zum Rendern von Primitiven mithilfe der IDirect3DDevice9::D rawIndexedPrimitive-Methode verwendet.

Ein Vertexpuffer enthält Scheitelpunkte; deshalb können Sie einen Vertexpuffer mit oder ohne indizierten Grundtypen zeichnen. Da ein Indexpuffer jedoch Indizes enthält, können Sie einen Indexpuffer nicht ohne entsprechenden Vertexpuffer verwenden. (Nebenbemerkung: IDirect3DDevice9::D rawIndexedPrimitiveUP und IDirect3DDevice9::D rawPrimitiveUP sind die einzigen Draw-Methoden, die ohne Index oder Vertexpuffer zeichnen.)

Beschreibung des Indexpuffers

Ein Indexpuffer wird anhand seiner Fähigkeiten beschrieben, wie z. B. wo im Speicher er vorhanden ist, ob Lese- und Schreibberechtigungen unterstützt werden, und nach Typ und Anzahl der enthaltenen Indizes. Diese Merkmale werden in einer D3DINDEXBUFFER_DESC-Struktur gespeichert.

Die Beschreibungen von Indexpuffern geben Ihrer Anwendung Hinweise darauf, wie ein vorhandener Puffer erstellt wurde. Sie stellen eine leere Beschreibungsstruktur für das System bereit, die mit den Fähigkeiten eines vorher erstellten Indexpuffers gefüllt wird.

  • Das Format-Element beschreibt das Oberflächenformat der Indexpufferdaten.
  • Der Typ identifiziert den Ressourcentyp des Indexpuffers.
  • Das Member der Verwendungsstruktur enthält allgemeine Funktionsflags. Das flag D3DUSAGE_SOFTWAREPROCESSING gibt an, dass der Indexpuffer bei der Softwarevertexverarbeitung verwendet werden soll. Das Vorhandensein des flags D3DUSAGE_WRITEONLY in Usage gibt an, dass der Indexpufferspeicher nur für Schreibvorgänge verwendet wird. Dadurch kann der Treiber die Indexdaten am besten speichern, um eine schnelle Verarbeitung und ein schnelles Rendering zu ermöglichen. Wenn das flag D3DUSAGE_WRITEONLY nicht verwendet wird, ist es weniger wahrscheinlich, dass der Treiber die Daten an einem Speicherort platziert, der für Lesevorgänge ineffizient ist. Dadurch wird eine gewisse Verarbeitungs- und Renderinggeschwindigkeit geopfert. Wenn dieses Flag nicht angegeben ist, wird davon ausgegangen, dass Anwendungen Lese- und Schreibvorgänge für die Daten im Indexpuffer ausführen.
  • Pool gibt die Speicherklasse an, die dem Indexpuffer zugeordnet ist. Das flag D3DPOOL_SYSTEMMEM gibt an, dass das System den Indexpuffer im Systemspeicher erstellt hat.
  • Das Element Größe speichert die Größe der Vertexpufferdaten in Byte.
  • Der letzte Parameter pSharedHandle wird nicht verwendet. Legen Sie sie auf NULL fest.

Indexverarbeitungsanforderungen

Die Leistung von Indexverarbeitungsvorgängen ist hauptsächlich davon abhängig, wo der Index im Speicher vorhanden ist, und welche Art von Renderinggerät verwendet wird. Anwendungen steuern die Speicherreservierung für Indexpuffer, wenn sie erstellt werden. Wenn das D3DPOOL_SYSTEMMEM-Speicherflag festgelegt ist, wird der Indexpuffer im Systemspeicher erstellt. Wenn das D3DPOOL_DEFAULT-Speicherflag verwendet wird, bestimmt der Gerätetreiber, wo der Speicher für den Indexpuffer am besten zugeordnet wird, was häufig als treiberoptimalen Arbeitsspeicher bezeichnet wird. Treiberoptimierter Arbeitsspeicher kann lokaler Videospeicher, nicht lokaler Videospeicher oder Systemspeicher sein.

Das Festlegen des D3DUSAGE_SOFTWAREPROCESSING Verhaltensflags beim Aufrufen der IDirect3DDevice9::CreateIndexBuffer-Methode gibt an, dass der Indexpuffer bei der Softwarevertexverarbeitung verwendet werden soll. Dieses Flag ist bei der Vertexverarbeitung im gemischten Modus (D3DCREATE_MIXED_VERTEXPROCESSING) erforderlich, wenn die Softwarevertexverarbeitung verwendet wird.

Die Anwendung kann direkt Indizes in einen Indexpuffer schreiben, der im treiberoptimierten Arbeitsspeicher reserviert ist. Mit dieser Technik wird später ein redundanter Kopiervorgang verhindert. Diese Technik funktioniert nicht optimal, wenn Ihre Anwendung Daten aus dem Indexpuffer zurückliest, da vom Host ausgeführte Lesevorgänge auf den treiberoptimierten Arbeitsspeicher sehr langsam sein können. Wenn Ihre Anwendung also während der Verarbeitung unregelmäßig Daten in oder aus dem Puffer lesen oder schreiben muss, ist ein Indexpuffer im Systemspeicher die bessere Wahl.

Hinweis

Verwenden Sie immer D3DPOOL_DEFAULT, es sei denn, Sie möchten keinen Videospeicher oder große Mengen von seitensperrten RAM verwenden, wenn der Treiber Vertex- oder Indexpuffer in den AGP-Speicher einlegt.

 

Erstellen eines Indexpuffers

Erstellen Sie ein Indexpufferobjekt, indem Sie die IDirect3DDevice9::CreateIndexBuffer-Methode aufrufen, die sechs Parameter akzeptiert.

  • Der erste Parameter gibt die Länge des Indexpuffers in Bytes an.

  • Der zweite Parameter ist ein Satz von Verwendungssteuerelementen. Sein Wert bestimmt unter anderem, ob die Scheitelpunkte, auf die von den Indizes verwiesen wird, Beschneidungsinformationen enthalten können. Um die Leistung zu verbessern, geben Sie D3DUSAGE_DONOTCLIP an, wenn kein Clipping erforderlich ist.

    Das D3DUSAGE_SOFTWAREPROCESSING-Flag kann festgelegt werden, wenn die Verarbeitung von gemischten Oder Softwarevertexen (D3DCREATE_MIXED_VERTEXPROCESSING/D3DCREATE_SOFTWARE_VERTEXPROCESSING) für dieses Gerät aktiviert ist. D3DUSAGE_SOFTWAREPROCESSING muss festgelegt werden, damit Puffer mit der Softwarevertexverarbeitung im gemischten Modus verwendet werden können, sie sollten jedoch nicht für die bestmögliche Leistung festgelegt werden, wenn die Hardwareindexverarbeitung im gemischten Modus (D3DCREATE_HARDWARE_VERTEXPROCESSING) verwendet wird. Das Festlegen D3DUSAGE_SOFTWAREPROCESSING ist jedoch die einzige Option, wenn ein einzelner Puffer sowohl bei der Hardware- als auch bei der Softwarevertexverarbeitung verwendet wird. D3DUSAGE_SOFTWAREPROCESSING ist für Gemischt- und Softwaregeräte zulässig.

    Es ist möglich, Vertex- und Indexpuffer in den Systemspeicher zu erzwingen, indem D3DPOOL_SYSTEMMEM angegeben wird, auch wenn die Indexverarbeitung auf Hardware erfolgt. Dies ist eine Möglichkeit, zu große Mengen an seitengesperrten Speicher zu vermeiden, wenn ein Treiber diese Puffer in den AGP-Speicher einlegt.

  • Der dritte Parameter ist entweder der D3DFMT_INDEX16 oder D3DFMT_INDEX32 Member des aufgezählten D3DFORMAT-Typs , der die Größe jedes Indexes angibt.

  • Der vierte Parameter ist ein Member des aufgezählten D3DPOOL-Typs , der dem System mitteilt, wo der neue Indexpuffer im Arbeitsspeicher platziert werden soll.

  • Der letzte Parameter, den IDirect3DDevice9::CreateIndexBuffer akzeptiert, ist die Adresse einer Variablen, die mit einem Zeiger auf die neue IDirect3DIndexBuffer9-Schnittstelle des Vertexpufferobjekts gefüllt ist, wenn der Aufruf erfolgreich ist.

Das folgende C++-Codebeispiel zeigt, wie das Erstellen eines Indexpuffers im Code aussehen kann.

/*
 * 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;

Zugreifen auf einen Indexpuffer

Indexpufferobjekte ermöglichen Anwendungen den direkten Zugriff auf den für Indexdaten zugeordneten Arbeitsspeicher. Sie können einen Zeiger auf den Indizierungspufferspeicher abrufen, indem Sie die IDirect3DIndexBuffer9::Lock-Methode aufrufen und dann nach Bedarf auf den Speicher zugreifen, um den Puffer mit neuen Indexdaten zu füllen oder alle darin enthaltenen Daten zu lesen. Die Lock-Methode akzeptiert vier Parameter. Die erste , OffsetToLock, ist der Offset in die Indexdaten. Der zweite Parameter ist die In Bytes gemessene Größe der Indexdaten. Der dritte Parameter, der von der IDirect3DIndexBuffer9::Lock-Methode akzeptiert wird, ppbData, ist die Adresse eines BYTE-Zeigers, der mit einem Zeiger auf die Indexdaten gefüllt ist, wenn der Aufruf erfolgreich ist.

Der letzte Parameter Flags teilt dem System mit, wie der Speicher gesperrt werden soll. Sie können damit angeben, wie die Anwendung auf die Daten im Puffer zugreift. Geben Sie Konstanten für den Flags-Parameter entsprechend der Art und Weise an, wie Ihre Anwendung auf die Indexdaten zugreift. Dadurch kann der Treiber den Arbeitsspeicher sperren und die beste Leistung für den angeforderten Zugriffstyp bereitstellen. Verwenden Sie D3DLOCK_READONLY Flag, wenn Ihre Anwendung nur aus dem Indexpufferspeicher liest. Durch das Einschließen dieses Flags kann Direct3D seine internen Prozeduren optimieren, um die Effizienz zu verbessern, da der Zugriff auf den Arbeitsspeicher schreibgeschützt ist.

Nachdem Sie die Indexdaten ausgefüllt oder gelesen haben, rufen Sie die IDirect3DIndexBuffer9::Unlock-Methode auf, wie im folgenden Codebeispiel gezeigt.

// 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();

Hinweis

Wenn Sie einen Indexpuffer mit dem D3DUSAGE_WRITEONLY-Flag erstellen, verwenden Sie nicht das D3DLOCK_READONLY Sperrenflag. Verwenden Sie das flag D3DLOCK_READONLY, wenn Ihre Anwendung nur aus dem Indexpufferspeicher liest. Durch das Einschließen dieses Flags kann Direct3D seine internen Prozeduren optimieren, um die Effizienz zu verbessern, da der Zugriff auf den Arbeitsspeicher schreibgeschützt ist.

Informationen zur Verwendung von D3DLOCK_DISCARD oder D3DLOCK_NOOVERWRITE für den Flags-Parameter der IDirect3DIndexBuffer9::Lock-Methode finden Sie unter Leistungsoptimierungen (Direct3D 9).

 

Stellen Sie in C++ sicher, dass Ihre Anwendung ordnungsgemäß auf den zugeordneten Arbeitsspeicher zugreift, da Sie direkt auf den für den Indexpuffer zugewiesenen Arbeitsspeicher zugreifen. Andernfalls besteht das Risiko, dass dieser Arbeitsspeicher ungültig wird. Verwenden Sie die Schrittart des Indexformats, das Ihre Anwendung verwendet, um von einem Index im zugeordneten Puffer zu einem anderen zu wechseln.

Rufen Sie Informationen zu einem Indexpuffer ab, indem Sie die IDirect3DIndexBuffer9::GetDesc-Methode aufrufen. Diese Methode füllt die Member der D3DINDEXBUFFER_DESC-Struktur mit Informationen zum Indexpuffer.

Direct3D-Ressourcen

Rendern aus Vertex- und Indexpuffern (Direct3D 9)

Vertexpuffer (Direct3D 9)