Einführung in Puffer in Direct3D 11
Eine Pufferressource ist eine Sammlung vollständig typisierter Daten, die in Elementen gruppiert sind. Sie können Puffer verwenden, um eine Vielzahl von Daten zu speichern, einschließlich Positionsvektoren, normaler Vektoren, Texturkoordinaten in einem Vertexpuffer, Indizes in einem Indexpuffer oder Gerätezustand. Ein Pufferelement besteht aus 1 bis 4 Komponenten. Pufferelemente können gepackte Datenwerte (z. B. R8G8B8A8-Oberflächenwerte), einzelne 8-Bit-Ganzzahlen oder vier 32-Bit-Gleitkommawerte enthalten.
Ein Puffer wird als unstrukturierte Ressource erstellt. Da er unstrukturiert ist, kann ein Puffer keine Mipmapebenen enthalten, er kann beim Lesen nicht gefiltert werden und kann nicht mehrfach gestampelt werden.
Puffertypen
Im Folgenden werden die Pufferressourcentypen aufgeführt, die von Direct3D 11 unterstützt werden. Alle Puffertypen werden von der ID3D11Buffer-Schnittstelle gekapselt.
Vertexpuffer
Ein Scheitelpunktpuffer enthält die Scheitelpunktdaten, die zum Definieren Ihrer Geometrie verwendet werden. Vertexdaten umfassen Positionskoordinaten, Farbdaten, Texturkoordinatendaten, normale Daten usw.
Das einfachste Beispiel für einen Vertexpuffer ist ein Beispiel, das nur Positionsdaten enthält. Sie kann wie in der folgenden Abbildung visualisiert werden.
Häufiger enthält ein Scheitelpunktpuffer alle Daten, die zum vollständigen Angeben von 3D-Scheitelpunkten erforderlich sind. Ein Beispiel hierfür könnte ein Vertexpuffer sein, der die Position pro Vertex, Normal- und Texturkoordinaten enthält. Diese Daten werden normalerweise als Sätze von Elementen pro Vertex organisiert, wie in der folgenden Abbildung gezeigt.
Dieser Vertexpuffer enthält Vertexdaten pro Vertex; Jeder Scheitelpunkt speichert drei Elemente (Positions-, Normal- und Texturkoordinaten). Die Position und normal werden in der Regel mit drei 32-Bit-Floats (DXGI_FORMAT_R32G32B32_FLOAT) und die Texturkoordinaten mit zwei 32-Bit-Floats (DXGI_FORMAT_R32G32_FLOAT) angegeben.
Um auf Daten aus einem Vertexpuffer zuzugreifen, müssen Sie wissen, auf welchen Scheitelpunkt zugegriffen werden soll, sowie die folgenden zusätzlichen Pufferparameter:
- Offset: Die Anzahl der Bytes vom Start des Puffers bis zu den Daten für den ersten Scheitelpunkt. Sie können den Offset mit der ID3D11DeviceContext::IASetVertexBuffers-Methode angeben.
- BaseVertexLocation : Ein Wert, der jedem Index hinzugefügt wird, bevor ein Scheitelpunkt aus dem Vertexpuffer gelesen wird.
Bevor Sie einen Vertexpuffer erstellen, müssen Sie dessen Layout definieren, indem Sie eine ID3D11InputLayout-Schnittstelle erstellen. Dazu wird die ID3D11Device::CreateInputLayout-Methode aufgerufen. Nachdem das Eingabelayoutobjekt erstellt wurde, können Sie es an die Eingabeassemierungsstufe binden, indem Sie ID3D11DeviceContext::IASetInputLayout aufrufen.
Um einen Vertexpuffer zu erstellen, rufen Sie ID3D11Device::CreateBuffer auf.
Indexpuffer
Indexpuffer enthalten ganzzahlige Offsets in Vertexpuffer und werden verwendet, um Primitive effizienter zu rendern. Ein Indexpuffer enthält einen sequenziellen Satz von 16- oder 32-Bit-Indizes. Jeder Index wird verwendet, um einen Scheitelpunkt in einem Scheitelpunktpuffer zu identifizieren. Ein Indexpuffer kann wie in der folgenden Abbildung visualisiert werden.
Die in einem Indexpuffer gespeicherten sequenziellen Indizes befinden sich mit den folgenden Parametern:
- Offset: Die Anzahl der Bytes aus der Basisadresse des Indexpuffers. Der Offset wird für die ID3D11DeviceContext::IASetIndexBuffer-Methode bereitgestellt.
- StartIndexLocation: Gibt das erste Indexpufferelement aus der Basisadresse und den in IASetIndexBuffer bereitgestellten Offset an. Der Startspeicherort wird für die ID3D11DeviceContext::D rawIndexed - oder ID3D11DeviceContext::D rawIndexedInstanced-Methode bereitgestellt und stellt den ersten zu rendernden Index dar.
- IndexCount: Die Anzahl der zu rendernden Indizes. Die Zahl wird für die DrawIndexed-Methode angegeben.
Start des Indexpuffers = Indexpuffer-Basisadresse + Offset (Bytes) + StartIndexLocation * ElementSize (Bytes);
Bei dieser Berechnung ist ElementSize die Größe jedes Indexpufferelements, die entweder zwei oder vier Bytes beträgt.
Um einen Indexpuffer zu erstellen, rufen Sie ID3D11Device::CreateBuffer auf.
Konstantpuffer
Mit einem Konstantenpuffer können Sie Shaderkonstantendaten effizient an die Pipeline bereitstellen. Sie können einen konstanten Puffer verwenden, um die Ergebnisse der Streamausgabephase zu speichern. Konzeptionell sieht ein Konstantenpuffer wie ein Vertexpuffer mit einem Element aus, wie in der folgenden Abbildung gezeigt.
Jedes Element speichert eine 1:4-Komponentenkonstante, die durch das Format der gespeicherten Daten bestimmt wird. Um einen Shaderkonstantenpuffer zu erstellen, rufen Sie ID3D11Device::CreateBuffer auf, und geben Sie das D3D11_BIND_CONSTANT_BUFFER Member des aufgezählten typs D3D11_BIND_FLAG an.
Ein Konstantenpuffer kann nur ein einzelnes Bindungsflag (D3D11_BIND_CONSTANT_BUFFER) verwenden, das nicht mit einem anderen Bindungsflag kombiniert werden kann. Um einen Shaderkonstantenpuffer an die Pipeline zu binden, rufen Sie eine der folgenden Methoden auf: ID3D11DeviceContext::GSSetConstantBuffers, ID3D11DeviceContext::P SSetConstantBuffers oder ID3D11DeviceContext::VSSetConstantBuffers.
Um einen Shaderkonstantenpuffer aus einem Shader zu lesen, verwenden Sie eine HLSL-Ladefunktion (z. B . Load). Jede Shaderstufe ermöglicht bis zu 15 Shaderkonstantenpuffer; Jeder Puffer kann bis zu 4096 Konstanten aufnehmen.
Zugehörige Themen