Erste Schritte (DirectXMath)
Die DirectXMath-Bibliothek implementiert eine optimale und portable Schnittstelle für arithmetische und lineare Algebra-Vorgänge für Gleitkommavektoren (2D, 3D und 4D) oder Matrizen (3×3 und 4×4). Die Bibliothek verfügt über eine eingeschränkte Unterstützung für ganzzahlige Vektorvorgänge. Diese Vorgänge werden von Grafikprogrammen häufig zum Rendern und zur Animation verwendet. Es gibt keine Unterstützung für Vektoren mit doppelter Genauigkeit (einschließlich Longs, Shorts oder Bytes) und nur begrenzte ganzzahlige Vektorvorgänge.
Die Bibliothek ist auf einer Vielzahl von Windows-Plattformen verfügbar. Da die Bibliothek Funktionen bereitstellt, die zuvor nicht verfügbar waren, ersetzt diese Version die folgenden Bibliotheken:
- Xbox Math-Bibliothek, die vom Xboxmath.h-Header bereitgestellt wird
- D3DX 9-Bibliothek, die von den D3DX 9-DLLs bereitgestellt wird
- D3DX 10-Mathebibliothek, die über die D3DX 10-DLLs bereitgestellt wird
- XNA Math-Bibliothek, die vom xnamath.h-Header im DirectX SDK und Xbox 360 XDK bereitgestellt wird
In diesen Abschnitten werden die Grundlagen der ersten Schritte beschrieben.
- Download
- Systemanforderungen für Laufzeit
- Entwurfsübersicht
- Matrixkonvention
- Grundlegende Nutzung
- Richtlinien zur Typverwendung
- Erstellen von Vektoren
- Extrahieren von Komponenten aus Vektoren
- Zugehörige Themen
Herunterladen
Die DirectXMath-Bibliothek ist im Windows SDK enthalten. Alternativ können Sie es von GitHub/Microsoft/DirectXMath herunterladen. Diese Website enthält auch verwandte Beispielprojekte.
Run-Time Systemanforderungen
Die DirectXMath-Bibliothek verwendet spezielle Prozessoranweisungen für Vektorvorgänge, sofern diese verfügbar sind. Um zu vermeiden, dass ein Programm Fehler mit "unbekannten Anweisungsausnahmeregelungen" generiert, suchen Sie nach Prozessorunterstützung, indem Sie XMVerifyCPUSupport aufrufen, bevor Sie die DirectXMath-Bibliothek verwenden.
Dies sind die grundlegenden Anforderungen für die DirectXMath-Bibliothek zur Laufzeitunterstützung:
- Die Standardkompilierung auf einer Windows-Plattform (x86/x64) erfordert die Unterstützung von SSE/SSE2-Anweisungen.
- Für die Standardkomplikation auf einer Windows RT Plattform ist ARM-NEON-Anweisungsunterstützung erforderlich.
- Die Kompilierung mit definierten _XM_NO_INTRINSICS_ erfordert nur Standard-Gleitkommabetriebsunterstützung.
Hinweis
Wenn Sie XMVerifyCPUSupport aufrufen, schließen <Sie windows.h> ein, bevor Sie DirectXMath.h> einschließen<. Dies ist die einzige Funktion in der Bibliothek, die Inhalte von <windows.h> erfordert, sodass Sie windows.h> nicht in jedes Modul einschließen <müssen, das DirectXMath.h> verwendet<.
Entwurfsübersicht
Die DirectXMath-Bibliothek unterstützt in erster Linie die Programmiersprache C++. Die Bibliothek wird mithilfe von Inlineroutinen in den Headerdateien DirectXMath*.inl, DirectXPackedVector.inl und DirectXCollision.inl implementiert. Bei dieser Implementierung werden leistungsfähige Compilertrins verwendet.
Die DirectXMath-Bibliothek bietet Folgendes:
- Eine Implementierung, die SSE/SSE2-systeminterne Funktionen verwendet.
- Eine Implementierung ohne systeminterne Funktionen.
- Eine Implementierung, die arm-NEON-systeminterne Funktionen verwendet.
Da die Bibliothek mithilfe von Headerdateien bereitgestellt wird, verwenden Sie den Quellcode, um Ihre eigene App anzupassen und zu optimieren.
Matrixkonvention
DirectXMath verwendet Zeilenmatrizen, Zeilenvektoren und Prämultiplikation. Die Händigkeit wird durch die verwendete Funktionsversion bestimmt (RH im Vergleich zu LH), andernfalls arbeitet die Funktion entweder mit links- oder rechtshändigen Ansichtskoordinaten.
Als Referenz hat Direct3D in der Vergangenheit linkshändiges Koordinatensystem, Zeilenmatrizen, Zeilenvektoren und Prämultiplikation verwendet. Moderne Direct3D hat keine starken Anforderungen für links- und rechtshändige Koordinaten, und in der Regel verwenden HLSL-Shader standardmäßig Spalten-Hauptmatrizen. Weitere Informationen finden Sie unter HLSL-Matrixreihenfolge .
Grundlegende Verwendung
Um DirectXMath-Bibliotheksfunktionen zu verwenden, schließen Sie die Header DirectXMath.h, DirectXPackedVector.h, DirectXColors.h und/oder DirectXCollision.h ein. Die Header befinden sich im Windows Software Development Kit für Windows Store-Apps.
Richtlinien zur Typverwendung
Die Typen XMVECTOR und XMMATRIX sind die Arbeitspferde für die DirectXMath-Bibliothek. Jeder Vorgang nutzt oder erzeugt Daten dieser Art. Die Arbeit mit ihnen ist der Schlüssel zur Verwendung der Bibliothek. Da DirectXMath jedoch die SIMD-Befehlssätze verwendet, unterliegen diese Datentypen einer Reihe von Einschränkungen. Es ist wichtig, dass Sie diese Einschränkungen verstehen, wenn Sie die DirectXMath-Funktionen gut nutzen möchten.
Sie sollten sich XMVECTOR als Proxy für ein SIMD-Hardwareregister und XMMATRIX als Proxy für eine logische Gruppierung von vier SIMD-Hardwareregistern vorstellen. Diese Typen werden mit Anmerkungen versehen, um anzugeben, dass eine 16-Byte-Ausrichtung erforderlich ist, um ordnungsgemäß zu funktionieren. Der Compiler platziert sie automatisch ordnungsgemäß auf dem Stapel, wenn sie als lokale Variable verwendet werden, oder platziert sie im Datensegment, wenn sie als globale Variable verwendet werden. Bei ordnungsgemäßen Konventionen können sie auch sicher als Parameter an eine Funktion übergeben werden (ausführliche Informationen finden Sie unter Aufrufen von Konventionen ).
Zuordnungen aus dem Heap sind jedoch komplizierter. Daher müssen Sie vorsichtig sein, wenn Sie entweder XMVECTOR oder XMMATRIX als Member einer Klasse oder Struktur verwenden, die aus dem Heap zugewiesen werden soll. Unter Windows x64 sind alle Heapzuordnungen 16 Byte ausgerichtet, für Windows x86 sind sie jedoch nur 8 Byte ausgerichtet. Es gibt Optionen zum Zuweisen von Strukturen aus dem Heap mit 16-Byte-Ausrichtung (siehe Zuordnungen richtig ausrichten). Für C++-Programme können Sie operator new/delete/new[]/delete[]/delete[]]-Überladungen (entweder global oder klassenspezifisch) verwenden, um bei Bedarf eine optimale Ausrichtung zu erzwingen.
Hinweis
Alternativ zum direkten Erzwingen der Ausrichtung in Ihrer C++-Klasse durch Überladen von new/delete können Sie die pImpl-Redewendung verwenden. Wenn Sie sicherstellen, dass Ihre Impl-Klasse über _aligned_malloc intern ausgerichtet ist, können Sie ausgerichtete Typen innerhalb der internen Implementierung frei verwenden. Dies ist eine gute Option, wenn die "public"-Klasse eine Windows-Runtime Ref-Klasse ist oder für die Verwendung mit std::shared_ptr<> vorgesehen ist, was andernfalls die sorgfältige Ausrichtung stören kann.
Häufig ist es jedoch einfacher und kompakter, XMVECTOR oder XMMATRIX direkt in einer Klasse oder Struktur zu vermeiden. Verwenden Sie stattdessen XMFLOAT3, XMFLOAT4, XMFLOAT4X3, XMFLOAT4X4 usw. als Elemente Ihrer Struktur. Darüber hinaus können Sie die Funktionen Vektorladen und Vektorspeicher verwenden, um die Daten effizient in lokale XMVECTOR - oder XMMATRIX-Variablen zu verschieben, Berechnungen durchzuführen und die Ergebnisse zu speichern. Es gibt auch Streamingfunktionen (XMVector3TransformStream, XMVector4TransformStream usw.), die effizient direkt auf Arrays dieser Datentypen ausgeführt werden.
Erstellen von Vektoren
KONSTANTE VEKTOREN
Viele Vorgänge erfordern die Verwendung von Konstanten in Vektorberechnungen, und es gibt eine Reihe von Möglichkeiten, einen XMVECTOR mit den gewünschten Werten zu laden.
Wenn Sie eine skalare Konstante in alle Elemente eines XMVECTOR laden, verwenden Sie XMVectorReplicate oder XMVectorReplicateInt.
XMVECTOR vFive = XMVectorReplicate( 5.f );
Wenn Sie eine Vektorkonstante mit anderen festen Werten als XMVECTOR verwenden, verwenden Sie die Strukturen XMVECTORF32, XMVECTORU32, XMVECTORI32 oder XMVECTORU8 . Auf diese kann dann direkt an jeder Stelle verwiesen werden, an der Sie einen XMVECTOR-Wert übergeben würden.
static const XMVECTORF32 vFactors = { 1.0f, 2.0f, 3.0f, 4.0f };
Hinweis
Verwenden Sie Initialisiererlisten nicht direkt mit XMVECTOR (d. h. XMVECTOR v = { 1.0f, 2.0f, 3.0f, 4.0f }). Dieser Code ist ineffizient und nicht auf allen Plattformen portierbar, die von DirectXMath unterstützt werden.
DirectXMath enthält eine Reihe vordefinierter globaler Konstanten, die Sie in Ihrem Code verwenden können (g_XMOne, g_XMOne3, g_XMTwo, g_XMOneHalf, g_XMHalfPi, g_XMPi usw.). Durchsuchen Sie den DirectXMath.h-Header nach den XMGLOBALCONST-Werten .
Es gibt eine Reihe von Vektorkonstanten für gängige RGB-Farben (Rot, Grün, Blau, Gelb usw.). Weitere Informationen zu diesen Vektorkonstanten finden Sie unter DirectXColors.h und im DirectX::Colors-Namespace.
VEKTOREN AUS VARIABLEN
Informationen zum Erstellen eines Vektors aus einer einzelnen skalaren Variablen finden Sie unter XMVectorReplicate und XMVectorReplicateInt.
XMVECTOR v = XMVectorReplicate( f );
Informationen zum Erstellen eines Vektors aus vier skalaren Variablen finden Sie unter XMVectorSet und XMVectorSetInt.
XMVECTOR v = XMVectorSet( fx, fy, fz, fw );
VEKTOREN AUS VEKTOREN
Wenn Sie einen Vektor aus einem anderen Vektor erstellen, bei dem eine bestimmte Komponente auf eine Variable festgelegt ist, können Sie die Verwendung von Vektorzugriffsfunktionen in Betracht ziehen.
XMVECTOR v2 = XMVectorSetW( v1, fw );
Wenn Sie einen Vektor aus einem anderen Vektor mit einer replizierten Komponente erstellen, verwenden Sie XMVectorSplatX, XMVectorSplatY, XMVectorSplatZ und XMVectorSplatW.
XMVECTOR vz = XMVectorSplatZ( v );
Wenn Sie einen Vektor aus einem anderen Vektor oder Vektorpaar mit neu sortierten Komponenten erstellen, lesen Sie XMVectorSwizzle und XMVectorPermute.
XMVECTOR v2 = XMVectorSwizzle<XM_SWIZZLE_Z, XM_SWIZZLE_Y, XM_SWIZZLE_W, XM_SWIZZLE_X>( v1 ); XMVECTOR v3 = XMVectorPermute<XM_PERMUTE_0W, XM_PERMUTE_1X, XM_PERMUTE_0X, XM_PERMUTE_1Z>( v1, v2 );
VEKTOREN AUS DEM ARBEITSSPEICHER
- Informationen zum Laden eines einzelnen Floatwerts aus dem Arbeitsspeicher finden Sie unter XMVectorReplicatePtr, XMVectorReplicateIntPtr, XMLoadFloat und XMLoadInt.
- Gängige Methoden zum Laden von Floatarrays sind XMLoadFloat2, XMLoadFloat3, XMLoadFloat4, XMLoadFloat3x3, XMLoadFloat4x3 und XMLoadFloat4x4.
- DirectXMath umfasst einen umfangreichen Satz von Typen und zugehörigen Ladevorgängen und -speichern für die Verarbeitung verschiedener Datenstrukturen und gängiger GPU-Formate. Weitere Informationen finden Sie unter Vektorlast und Vektorspeicher.
Extrahieren von Komponenten aus Vektoren
Die SIMD-Verarbeitung ist am effizientesten, wenn Daten in die SIMD-Register geladen und vor dem Extrahieren der Ergebnisse vollständig verarbeitet werden. Die Konvertierung zwischen skalaren und vektoren Formularen ist ineffizient, daher wird empfohlen, dies nur bei Bedarf zu tun. Aus diesem Grund werden Funktionen in der DirectXMath-Bibliothek, die einen skalaren Wert erzeugen, in einer Vektorform zurückgegeben, in der das skalare Ergebnis über den resultierenden Vektor repliziert wird (also XMVector2Dot, XMVector3Length usw.). Wenn Sie jedoch skalare Werte benötigen, finden Sie hier einige Optionen für die Vorgehensweise:
Wenn eine einzelne skalare Antwort berechnet wird, ist die Verwendung der Vektorzugriffsfunktionen geeignet:
float f = XMVectorGetX( v );
Wenn mehrere Komponenten des Vektors extrahiert werden müssen, sollten Sie den Vektor in einer Speicherstruktur speichern und zurücklesen. Beispiel:
XMFLOAT4A t; XMStoreFloat4A( &t, v ); // t.x, t.y, t.z, and t.w can be individually accessed now
Die effizienteste Form der Vektorverarbeitung ist die Verwendung von Memory-to-Memory-Streaming, bei dem die Eingabedaten aus dem Arbeitsspeicher geladen werden (mithilfe von Vektorladefunktionen), vollständig in SIMD-Form verarbeitet und dann (mithilfe von Vector Store Functions) in den Arbeitsspeicher geschrieben werden.
Zugehörige Themen