Partager via


Prise en main (DirectXMath)

La bibliothèque DirectXMath implémente une interface optimale et portable pour les opérations d’algèbre arithmétique et linéaire sur des vecteurs à virgule flottante simple précision (2D, 3D et 4D) ou des matrices (3×3 et 4×4). La bibliothèque a une prise en charge limitée des opérations de vecteur entier. Ces opérations sont largement utilisées dans le rendu et l’animation par les programmes graphiques. Il n’existe aucune prise en charge des vecteurs à double précision (y compris les longs, les courts ou les octets), et uniquement les opérations de vecteur entier limitées.

La bibliothèque est disponible sur diverses plateformes Windows. Étant donné que la bibliothèque fournit des fonctionnalités qui n’étaient pas disponibles auparavant, cette version remplace les bibliothèques suivantes :

  • Bibliothèque Xbox Math fournie par l’en-tête Xboxmath.h
  • Bibliothèque D3DX 9 fournie par les DLL D3DX 9
  • Bibliothèque mathématique D3DX 10 fournie via les DLL D3DX 10
  • Bibliothèque mathématique XNA fournie par l’en-tête xnamath.h dans le Kit de développement logiciel (SDK) DirectX et Xbox 360 XDK

Ces sections décrivent les principes de base de la prise en main.

Télécharger

La bibliothèque DirectXMath est incluse dans le Kit de développement logiciel (SDK) Windows. Vous pouvez également le télécharger à partir de GitHub/Microsoft/DirectXMath. Ce site contient également des exemples de projets connexes.

configuration requise pour Run-Time

La bibliothèque DirectXMath utilise des instructions de processeur spécialisées pour les opérations vectorielles lorsqu’elles sont disponibles. Pour éviter qu’un programme génère des erreurs d'« exception d’instruction inconnue », case activée pour la prise en charge du processeur en appelant XMVerifyCPUSupport avant d’utiliser la bibliothèque DirectXMath.

Voici les exigences de base de prise en charge de l’exécution de la bibliothèque DirectXMath :

  • La compilation par défaut sur une plateforme Windows (x86/x64) nécessite la prise en charge des instructions SSE/SSE2.
  • La duplication par défaut sur une plateforme Windows RT nécessite la prise en charge des instructions ARM-NEON.
  • La compilation avec _XM_NO_INTRINSICS_ définie nécessite uniquement la prise en charge des opérations à virgule flottante standard.

Notes

Lorsque vous appelez XMVerifyCPUSupport, incluez <windows.h> avant d’inclure <DirectXMath.h>. Il s’agit de la seule fonction de la bibliothèque qui nécessite du contenu de <windows.h> . Vous n’êtes donc pas obligé d’inclure <windows.h> dans chaque module qui utilise <DirectXMath.h>.

 

Vue d’ensemble de la conception

La bibliothèque DirectXMath prend principalement en charge le langage de programmation C++. La bibliothèque est implémentée à l’aide de routines inline dans les fichiers d’en-tête, DirectXMath*.inl, DirectXPackedVector.inl et DirectXCollision.inl. Cette implémentation utilise des intrinsèques de compilateur hautes performances.

La bibliothèque DirectXMath fournit :

  • Implémentation utilisant des intrinsèques SSE/SSE2.
  • Implémentation sans intrinsèque.
  • Implémentation utilisant des intrinsèques ARM-NEON.

Étant donné que la bibliothèque est fournie à l’aide de fichiers d’en-tête, utilisez le code source pour personnaliser et optimiser votre propre application.

Convention matricielle

DirectXMath utilise des matrices principales de lignes, des vecteurs de ligne et la pré-multiplication. La remise est déterminée par la version de la fonction utilisée (RH par rapport à LH), sinon la fonction fonctionne avec les coordonnées de vue gaucher ou droitier.

À titre de référence, Direct3D a historiquement utilisé le système de coordonnées gaucher, les matrices principales de lignes, les vecteurs de ligne et la pré-multiplication. Direct3D moderne n’a pas d’exigence forte pour les coordonnées gauche et droite, et généralement, les nuanceurs HLSL consomment par défaut des matrices principales de colonnes. Pour plus d’informations, consultez Classement de matrice HLSL .

Utilisation de base

Pour utiliser les fonctions de bibliothèque DirectXMath, incluez les en-têtes DirectXMath.h, DirectXPackedVector.h, DirectXColors.h et/ou DirectXCollision.h. Les en-têtes se trouvent dans le Kit de développement logiciel Windows pour les applications du Windows Store.

Instructions relatives à l’utilisation des types

Les types XMVECTOR et XMMATRIX sont les chevaux de travail de la bibliothèque DirectXMath. Chaque opération consomme ou produit des données de ces types. L’utilisation de ces ressources est essentielle à l’utilisation de la bibliothèque. Toutefois, étant donné que DirectXMath utilise les jeux d’instructions SIMD, ces types de données sont soumis à un certain nombre de restrictions. Il est essentiel que vous compreniez ces restrictions si vous souhaitez utiliser les fonctions DirectXMath.

Vous devez considérer XMVECTOR comme un proxy pour un registre matériel SIMD et XMMATRIX comme un proxy pour un regroupement logique de quatre registres matériels SIMD. Ces types sont annotés pour indiquer qu’ils nécessitent un alignement de 16 octets pour fonctionner correctement. Le compilateur les place automatiquement correctement sur la pile lorsqu’ils sont utilisés en tant que variable locale, ou les place dans le segment de données lorsqu’ils sont utilisés en tant que variable globale. Avec des conventions appropriées, elles peuvent également être transmises en toute sécurité en tant que paramètres à une fonction (pour plus d’informations, consultez Conventions d’appel ).

Toutefois, les allocations à partir du tas sont plus compliquées. Par conséquent, vous devez être prudent chaque fois que vous utilisez XMVECTOR ou XMMATRIX comme membre d’une classe ou d’une structure à allouer à partir du tas. Sur Windows x64, toutes les allocations de tas sont alignées sur 16 octets, mais pour Windows x86, elles ne sont alignées que sur 8 octets. Il existe des options d’allocation de structures à partir du tas avec un alignement de 16 octets (voir Aligner correctement les allocations). Pour les programmes C++, vous pouvez utiliser les surcharges de l’opérateur new/delete/new[]/delete[] (globalement ou spécifiques à la classe) pour appliquer un alignement optimal si vous le souhaitez.

Notes

Comme alternative à l’application directe de l’alignement dans votre classe C++ en surchargeant new/delete, vous pouvez utiliser l’idiome pImpl. Si vous vérifiez que votre classe Impl est alignée via _aligned_malloc en interne, vous pouvez utiliser librement des types alignés au sein de l’implémentation interne. Il s’agit d’une bonne option lorsque la classe « public » est une classe ref Windows Runtime ou destinée à être utilisée avec std::shared_ptr<>, ce qui peut sinon perturber l’alignement soigné.

 

Toutefois, il est souvent plus facile et plus compact d’éviter d’utiliser XMVECTOR ou XMMATRIX directement dans une classe ou une structure. Utilisez plutôt les XMFLOAT3, XMFLOAT4, XMFLOAT4X3, XMFLOAT4X4, etc. en tant que membres de votre structure. En outre, vous pouvez utiliser les fonctions Chargement vectoriel et Stockage vectoriel pour déplacer efficacement les données dans des variables locales XMVECTOR ou XMMATRIX , effectuer des calculs et stocker les résultats. Il existe également des fonctions de streaming (XMVector3TransformStream, XMVector4TransformStream, etc.) qui fonctionnent efficacement directement sur des tableaux de ces types de données.

Création de vecteurs

VECTEURS CONSTANTS

De nombreuses opérations nécessitent l’utilisation de constantes dans les calculs vectoriels, et il existe plusieurs façons de charger un XMVECTOR avec les valeurs souhaitées.

  • Si vous chargez une constante scalaire dans tous les éléments d’un XMVECTOR, utilisez XMVectorReplicate ou XMVectorReplicateInt.

    XMVECTOR vFive = XMVectorReplicate( 5.f );
    
  • Si vous utilisez une constante vectorielle avec des valeurs fixes différentes en tant que XMVECTOR, utilisez les structures XMVECTORF32, XMVECTORU32, XMVECTORI32 ou XMVECTORU8 . Vous pouvez ensuite les référencer directement partout où vous transmettez une valeur XMVECTOR .

    static const XMVECTORF32 vFactors = { 1.0f, 2.0f, 3.0f, 4.0f };
    

    Notes

    N’utilisez pas de listes d’initialiseurs directement avec XMVECTOR (autrement dit, XMVECTOR v = { 1.0f, 2.0f, 3.0f, 4.0f }). Ce code est inefficace et n’est pas portable sur toutes les plateformes prises en charge par DirectXMath.

     

  • DirectXMath inclut un certain nombre de constantes globales prédéfinies que vous pouvez utiliser dans votre code (g_XMOne, g_XMOne3, g_XMTwo, g_XMOneHalf, g_XMHalfPi, g_XMPi, etc.). Recherchez les valeurs XMGLOBALCONST dans l’en-tête DirectXMath.h.

  • Il existe un ensemble de constantes vectorielles pour les couleurs RVB courantes (rouge, vert, bleu, jaune, etc.). Pour plus d’informations sur ces constantes vectorielles, consultez DirectXColors.h et l’espace de noms DirectX::Colors.

VECTEURS À PARTIR DE VARIABLES

  • Si vous créez un vecteur à partir d’une variable scalaire unique, consultez XMVectorReplicate et XMVectorReplicateInt.

    XMVECTOR v = XMVectorReplicate( f  );
    
  • Si vous créez un vecteur à partir de quatre variables scalaires, consultez XMVectorSet et XMVectorSetInt.

    XMVECTOR v = XMVectorSet( fx, fy, fz, fw );
    

VECTEURS À PARTIR DE VECTEURS

  • Si vous créez un vecteur à partir d’un autre vecteur avec un composant spécifique défini sur une variable, vous pouvez envisager d’utiliser Vector Accessor Functions.

    XMVECTOR v2 = XMVectorSetW( v1, fw );
    
  • Si vous créez un vecteur à partir d’un autre vecteur avec un seul composant répliqué, utilisez XMVectorSplatX, XMVectorSplatY, XMVectorSplatZ et XMVectorSplatW.

    XMVECTOR vz = XMVectorSplatZ( v );
    
  • Si vous créez un vecteur à partir d’un autre vecteur ou d’une autre paire de vecteurs avec des composants réorganisés, consultez XMVectorSwizzle et 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 );
    

VECTEURS DE MÉMOIRE

Extraction de composants à partir de vecteurs

Le traitement SIMD est plus efficace lorsque des données sont chargées dans les registres SIMD et traitées entièrement avant d’extraire les résultats. La conversion entre les formes scalaires et vectorielles étant inefficace, nous vous recommandons de ne le faire que si nécessaire. Pour cette raison, les fonctions de la bibliothèque DirectXMath qui produisent une valeur scalaire sont retournées sous une forme vectorielle où le résultat scalaire est répliqué sur le vecteur résultant (autrement dit, XMVector2Dot, XMVector3Length, etc.). Toutefois, lorsque vous avez besoin de valeurs scalaires, voici quelques choix sur la façon de procéder :

  • Si une seule réponse scalaire est calculée, l’utilisation des fonctions d’accesseur vectoriel est appropriée :

    float f = XMVectorGetX( v );
    
  • Si plusieurs composants du vecteur doivent être extraits, envisagez de stocker le vecteur dans une structure de mémoire et de le relire. Par exemple :

    XMFLOAT4A t;
    XMStoreFloat4A( &t, v );
    // t.x, t.y, t.z, and t.w can be individually accessed now
    
  • La forme la plus efficace de traitement vectoriel consiste à utiliser la diffusion en continu de mémoire en continu où les données d’entrée sont chargées à partir de la mémoire (à l’aide des fonctions de charge vectorielle), traitées entièrement sous forme SIMD, puis écrites en mémoire (à l’aide de vector Store Functions).

Guide de programmation DirectXMath