Zuordnen von FVF-Codes zu einer Direct3D 9-Deklaration (Direct3D 9)

Diese Tabelle ordnet FVF-Codes einer D3DVERTEXELEMENT9-Struktur zu.

FVF Datentyp Verbrauch Nutzungsindex
D3DFVF_XYZ D3DDECLTYPE_FLOAT3 D3DDECLUSAGE_POSITION 0
D3DFVF_XYZRHW D3DDECLTYPE_FLOAT4 D3DDECLUSAGE_POSITIONT 0
D3DFVF_XYZW D3DDECLTYPE_FLOAT4 D3DDECLUSAGE_POSITION 0
D3DFVF_XYZB5 und D3DFVF_LASTBETA_UBYTE4 D3DVSDT_FLOAT3, D3DVSDT_FLOAT4, D3DVSDT_UBYTE4 D3DDECLUSAGE_POSITION, D3DDECLUSAGE_BLENDWEIGHT, D3DDECLUSAGE_BLENDINDICES 0
D3DFVF_XYZB5 und D3DFVF_LASTBETA_D3DCOLOR D3DVSDT_FLOAT3, D3DVSDT_FLOAT4, D3DVSDT_D3DCOLOR D3DDECLUSAGE_POSITION, D3DDECLUSAGE_BLENDWEIGHT, D3DDECLUSAGE_BLENDINDICES 0
D3DFVF_XYZB5 D3DDECLTYPE_FLOAT3, D3DDECLTYPE_FLOAT4, D3DDECLTYPE_FLOAT1 D3DDECLUSAGE_POSITION, D3DDECLUSAGE_BLENDWEIGHT, D3DDECLUSAGE_BLENDINDICES 0
D3DFVF_XYZBn (n=1.4) D3DDECLTYPE_FLOAT3, D3DDECLTYPE_FLOATn D3DDECLUSAGE_POSITION, D3DDECLUSAGE_BLENDWEIGHT 0
D3DFVF_XYZBn (n=1..4) und D3DFVF_LASTBETA_UBYTE4 D3DDECLTYPE_FLOAT3, D3DDECLTYPE_FLOAT(n-1), D3DDECLTYPE_UBYTE4 D3DDECLUSAGE_POSITION, D3DDECLUSAGE_BLENDWEIGHT, D3DDECLUSAGE_BLENDINDICES 0
D3DFVF_XYZBn (n=1..4) und D3DFVF_LASTBETA_D3DCOLOR D3DDECLTYPE_FLOAT3, D3DDECLTYPE_FLOAT(n-1), D3DDECLTYPE_D3DCOLOR D3DDECLUSAGE_POSITION, D3DDECLUSAGE_BLENDWEIGHT, D3DDECLUSAGE_BLENDINDICES 0
D3DFVF_NORMAL D3DDECLTYPE_FLOAT3 D3DDECLUSAGE_NORMAL 0
D3DFVF_PSIZE D3DDECLTYPE_FLOAT1 D3DDECLUSAGE_PSIZE 0
D3DFVF_DIFFUSE D3DDECLTYPE_D3DCOLOR D3DDECLUSAGE_COLOR 0
D3DFVF_SPECULAR D3DDECLTYPE_D3DCOLOR D3DDECLUSAGE_COLOR 1
D3DFVF_TEXCOORDSIZEm(n) D3DDECLTYPE_FLOATm D3DDECLUSAGE_TEXCOORD n

 

Scheitelpunktdeklarationen mit D3DDECLUSAGE_POSITIONT

Das Vorhandensein eines Vertexelements mit (D3DUSAGE_POSITIONT, 0) wird verwendet, um dem Gerät anzuzeigen, dass die eingetretenen Vertexdaten bereits die Vertexverarbeitung durchlaufen haben (z. B. eine FVF mit D3DFVF_XYZRHW Bitsatz). Wenn die aktuell festgelegte Deklaration über ein Element mit der Semantik (D3DUSAGE_POSITIONT, 0) verfügt, wird die gesamte Vertexverarbeitung übersprungen (so, als ob eine FVF mit D3DFVF_XYZRHW Bit festgelegt wurde).

Es gibt einige Einschränkungen für Vertexdeklarationen mit (D3DDECLUSAGE_POSITIONT, 0):

  • Nur stream zero kann in solchen Deklarationen verwendet werden.
  • Vertexelemente müssen durch Erhöhen des Streamoffsets sortiert werden.
  • Der Streamoffset muss DWORD ausgerichtet sein.
  • Das gleiche Paar (Verwendung, Nutzungsindex) sollte nur einmal aufgeführt werden.
  • Es kann nur die D3DDECLMETHOD_DEFAULT-Methode verwendet werden.
  • Andere Vertexelemente können nicht die Semantik (D3DDECLUSAGE_POSITION, 0) aufweisen.

Darüber hinaus gibt es einige Einschränkungen für eine solche Deklaration im Zusammenhang mit der Gerätetreiberversion. Diese Einschränkungen gelten, da Direct3D solche Deklarationen ohne Konvertierung direkt an den Treiber sendet.

Vertexdeklarationen ohne D3DDECLUSAGE_POSITIONT

Die Laufzeit überprüft die Erstellung von Deklarationen. Im Folgenden sind die allgemeinen Regeln für die rechtlichen Erklärungen aufgeführt.

  • Alle Scheitelpunktelemente für einen Stream müssen aufeinanderfolgende und nach Offset sortiert sein.
  • Der Streamoffset muss DWORD ausgerichtet sein.
  • Das gleiche Paar (Verwendung, Nutzungsindex) sollte nur einmal aufgeführt werden.
  • Wenn die D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET festgelegt ist, dann
    • Mehrere Vertexelemente können denselben Offset in einem Stream verwenden.
    • Die Scheitelpunkteelemente können unterschiedliche Typen aufweisen, die unterschiedlich groß sein können.
    • Die Vertexelemente können sich beliebig überlappen. Beispielsweise kann ein Element an einer Position eines Datenstroms gestartet werden, der sich gleichzeitig in der Mitte eines anderen Elements befindet.
    • Vertexelemente dürfen einen Streamoffset in beliebiger Reihenfolge aufweisen.
  • Die Anzahl der Vertexelemente darf nicht größer als 64 sein.
  • UsageIndex sollte im Bereich [0-15] liegen.
  • Die Deklaration, die mit der DrawPrimitive-API verwendet wird, darf keine anderen Vertexelemente als D3DDECLMETHOD_DEFAULT, D3DDECLMETHOD_LOOKUPPRESAMPLED oder D3DDECLMETHOD_LOOKUP enthalten.
  • Die Deklaration, die D3DDECLMETHOD_LOOKUP oder LOOKUPPRESAMPLED enthält, sollte nur mit der programmierbaren Vertexpipeline verwendet werden.
  • Die Deklaration, die mit der DrawRectPatch/DrawTriPatch-API verwendet wird, kann keine Vertexelemente mit D3DDECLMETHOD_LOOKUPPRESAMPLED oder D3DDECLMETHOD_LOOKUP enthalten.
  • Die Deklaration sollte nur über ein Element mit D3DDECLMETHOD_LOOKUP oder D3DDECLMETHOD_LOOKUPPRESAMPLED Methode verfügen.
  • Die Deklaration mit D3DDECLMETHOD_LOOKUP oder D3DDECLMETHOD_LOOKUPPRESAMPLED sollte keine anderen Elemente als D3DDECLMETHOD_DEFAULT enthalten, da die Verschiebungszuordnung nur für N-Patches erfolgt.
  • Vertexelemente mit D3DDECLMETHOD_LOOKUP oder D3DDECLMETHOD_LOOKUPPRESAMPLED können nur mit der Semantik (D3DDECLUSAGE_SAMPLE, n) verwendet werden und umgekehrt.
  • Wenn ein Vertexelement mit D3DDECLMETHOD_LOOKUP Methode über einen Streamindex und einen Offset eines bereits vorhandenen Vertexelements verfügt, sollte dieses Vertexelement denselben Datentyp aufweisen.
  • Ein Vertexelement mit der D3DDECLMETHOD_LOOKUP-Methode sollte den Datentyp D3DDECLTYPE_FLOAT2/3/4 aufweisen
  • Vertexelemente mit Typen D3DDECLMETHOD_CROSSUV, D3DDECLMETHOD_PARTIALU und D3DDECLMETHOD_PARTIALV sollten einen Offset eines Vertexelements mit einem kompatiblen Datentyp aufweisen.
  • Ein Vertexelement mit der Methode D3DDECLMETHOD_UV oder D3DDECLMETHOD_LOOKUPPRESAMPLED muss den Typ D3DDECLTYPE_UNUSED, den Streamindex Null und den Streamoffset Null aufweisen.
  • Deklarationen mit Methoden D3DDECLMETHOD_UV, D3DDECLMETHOD_PARTIALU und D3DDECLMETHOD_PARTIALV können nur mit DrawRectPatch verwendet werden.
  • Verwendung D3DDECLUSAGE_TESSFACTOR sollte nur mit dem Datentyp D3DDECLTYPE_FLOAT1 und dem Nutzungsindex 0 verwendet werden.
  • Wenn eine Deklaration für tessellation (DrawRectPatch, DrawTriPatch, N-patches) verwendet wird, muss der Datentyp kleiner oder gleich D3DDECLTYPE_SHORT4 sein.
  • Deklarationen, die Methoden enthalten, die bestimmte Gerätefunktionen erfordern (z. B. Verschiebungszuordnung, RT-Patches), können nur erstellt werden, wenn sie vom Gerät unterstützt werden.
  • Eine Scheitelpunktdeklaration, die zum Zeichnen von Punkten und Linien verwendet wird, darf keine anderen Methoden als D3DDECLMETHOD_DEFAULT haben.
  • Welche Deklarationen erstellt werden können, hängt auch von den Treiberfunktionen ab.

Überlegungen zu Treibern

Pre-Direct3D 9-Treiber

  • Die Eingabedeklaration muss in einen gültigen FVF übersetzt werden können (mit der gleichen Reihenfolge der Vertexelemente und deren Datentypen).
  • Lücken in Texturkoordinaten sind nicht zulässig. Das bedeutet, dass bei einem Vertexelement mit (D3DDECLUSAGE_TEXCOORD, n) auch ein Vertexelement mit (D3DDECLUSAGE_TEXCOORD, n-1) vorhanden sein sollte.

Direct3D 9-Treiber ohne Pixel Shader Version 3-Unterstützung

  • Die Eingabedeklaration muss in einen gültigen FVF übersetzt werden können (mit der gleichen Reihenfolge der Vertexelemente und deren Datentypen).
  • Lücken in Texturkoordinaten sind zulässig.

Direct3D 9-Treiber mit Pixel Shader Version 3-Unterstützung

Allgemeinere Deklarationen sind zulässig.

  • Vertexelemente können in beliebiger Reihenfolge sein und beliebige Datentypen aufweisen.
  • Mehrere Scheitelpunkteelemente können denselben Streamoffset gemeinsam nutzen und einen anderen Typ zur gleichen Zeit aufweisen, wenn D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET vom Gerät festgelegt wird.

Vertexdeklarationsverwendung mit der programmierbaren Vertexpipeline

  • Zur Zeichnungszeit sucht Direct3D in der aktuellen Vertexdeklaration und der aktuellen Vertex-Shaderfunktion nach derselben Kombination "Verwendung – Nutzungsindex". Wenn die Kombination gefunden wird, wird die DCL der Shaderfunktion registrieren als Ziel für das Vertexelement verwendet.
  • Wenn ein Vertexelement in der aktuellen Vertexdeklaration eine Verwendung aufweist, die im aktuellen Vertex-Shader nicht gefunden wird, wird dieses Vertexelement ignoriert.
  • Wenn Sie eine Vertex-Shaderversion kleiner als 2.0 verwenden, müssen alle im Shadercode erwähnten Semantiken in der Deklaration vorhanden sein, die zum Zeitpunkt des Zeichnens gebunden ist. Bei Verwendung von Vertex-Shadern 2.0 und höher ist diese Einschränkung, die es Anwendungen ermöglicht, verschiedene Vertexdeklarationen mit demselben Vertex-Shader zu verwenden, nicht vorhanden. Dies ist nützlich, wenn ein Vertex-Shader Eingabedaten basierend auf statischen Bedingungen liest. Vertex-Shaderregister, die aus diesem Fall nicht initialisiert wurden, weisen nicht definierte Werte auf.

Es gibt zusätzliche Einschränkungen bei der Verwendung mit der Hardwarevertexverarbeitung auf einem DirectX 8-Treiber:

  • Vertexelemente können sich nicht überlappen oder denselben Offset gemeinsam nutzen.
  • Datentypen sind auf das beschränkt, was der DirectX 8-Treiber verstehen kann.

Die CreateVertexDeclaration schlägt möglicherweise fehl, wenn die bereitgestellte Deklaration nicht in eine DirectX 8-Deklaration konvertiert werden kann. Bei einem Gerät im gemischten Modus tritt dieser Fehler zur Draw*-Zeit auf, da nur dann bekannt werden kann, ob dieser Shader mit der Hardware- oder Softwarevertexverarbeitung verwendet wird.

Vertexdeklarationsverwendung mit der Pipeline für feste Funktionen

Es können nur Deklarationen verwendet werden, die den folgenden Regeln entsprechen:

  • Es sollten keine Lücken zwischen Vertexelementen vorhanden sein (SKIP war in einer DirectX 8-Deklaration nicht zulässig, die für die Feste Funktionspipeline verwendet wird).
  • Semantik (D3DDECLUSAGE_POSITION, 0) muss angegeben werden und sollte D3DDECLTYPE_FLOAT3 Datentyp aufweisen.
  • Ein Vertexelement mit D3DDECLMETHOD_UV Methode muss die Verwendung D3DDECLUSAGE_TEXCOORD oder D3DDECLUSAGE_BLENDWEIGHT angeben.
  • Ein Vertexelement mit der Methode D3DDECLMETHOD_PARTIALU, _PARTIALV oder _CROSSUV kann nur mit D3DDECLUSAGE_POSITION, _NORMAL, _BLENDWEIGHT oder _TEXCOORD verwendet werden und muss den Eingabetyp D3DDECLTYPE_FLOAT3 verwenden.

Wenn eine Deklaration mit der Hardwarevertexverarbeitung auf einem DirectX 8-Treiber verwendet wird, konvertiert die Direct3D-Runtime sie in eine Deklaration im DirectX-8-Format mit den folgenden Regeln:

  • Vertexelemente können sich nicht denselben Offset in einem Stream teilen und sich nicht überlappen.
  • Der Datentyp muss kleiner oder gleich D3DDECLTYPE_SHORT4 sein.
  • Nur die folgenden Methoden sind zulässig: D3DDECLMETHOD_DEFAULT, D3DDECLMETHOD_CROSSUV und D3DDECLMETHOD_UV
  • Die Zuordnung zwischen einer Direct3D 9-Deklaration und einer Direct3D 8-Deklaration (Direct3D 9) zeigt, welche Direct3D 9-Semantik in eine Deklaration im 8-Stil von DirectX konvertiert werden kann. Usage und UsageIndex werden in einen Registerwert konvertiert.
  • Wenn in einer Deklaration n Vertexelemente vorhanden sind und 0 - m (m < n) einem FVF zugeordnet ist (Elemente, die in der Zuordnung zwischen einer Direct3D-Deklaration und FVF-Codes (Direct3D 9) beschrieben werden), m + 1 jedoch nicht, dann:
    • Wenn eines von m + 2 bis n - 1 Scheitelpunktelementen FVF/dx8decl zugeordnet ist, ist die Deklaration ungültig.
    • Die Elemente 0 in m werden konvertiert (von der Runtime für DirectX 8 und ältere Treiber und von den Direct3D 9-Treibern) mithilfe der Zuordnung zwischen einer Direct3D-Deklaration und FVF-Codes (Direct3D 9), m + 1, m + 2 bis n - 1 werden zusammenhängenden texcoord(k), texcoord(k+1) zugeordnet, beginnend von jedem texcoord in Elementen 0 - m.
    • Es wird davon ausgegangen, dass der Datentyp bei einem zugeordneten texcoord float[1234] ist, der den Datentyp ersetzt, den das aktuelle Element enthält (aber dieselbe Größe). Daher kann der vorhandene Datentyp etwas sein, das sich nicht in der Zuordnung zwischen einer Direct3D-Deklaration und FVF-Codes (Direct3D 9) befindet.
    • Wenn k 8 erreicht, ist die Deklaration für FVF/dx8decl ungültig.
    • Wenn Zuordnungen zu texcoords aufgetreten sind, muss die gesamte Deklaration keine Elemente mit einer anderen Generierungsmethode als DEFAULT enthalten, oder die Deklaration ist für FVF/dx8decl ungültig.

Verwenden von Vertexdeklarationen mit ProcessVertices

Eine Vertexdeklaration kann verwendet werden, um die Ausgabe von ProcessVertices zu beschreiben. Eine solche Deklaration sollte den folgenden Regeln entsprechen:

  • Es muss nur Stream 0 verwendet werden.
  • Nur D3DDECLMETHOD_DEFAULT Methoden sind zulässig.
  • Es können nur D3DDECLTYPE_FLOATn- oder D3DDECLTYPE_D3DCOLOR-Datentypen verwendet werden.
  • Vertexelemente können nicht denselben Offset gemeinsam nutzen oder sich nicht miteinander überschneiden.
  • Vertexelemente mit (D3DDECLUSAGE_POSITION, 0) oder (D3DDECLUSAGE_POSITIONT,0) sind nicht erforderlich.
  • Vertexelemente mit (D3DDECLUSAGE_POSITION, 0) und (D3DDECLUSAGE_POSITIONT,0) können nicht in derselben Deklaration vorhanden sein.
  • Der aktuelle Vertex-Shader muss Version 3.0 oder höher sein, wenn eine solche Deklaration verwendet wird.

Vertexdeklaration