Introduzione (DirectXMath)

La libreria DirectXMath implementa un'interfaccia ottimale e portabile per operazioni di algebra aritmetica e lineare su vettori a virgola mobile a precisione singola (2D, 3D e 4D) o matrici (3×3 e 4×4). La libreria ha un supporto limitato per le operazioni vettoriali integer. Queste operazioni vengono usate ampiamente per il rendering e l'animazione da parte dei programmi grafici. Non è disponibile alcun supporto per i vettori a precisione doppia (inclusi longs, shorts o byte) e solo per operazioni di vettore integer limitate.

La libreria è disponibile in un'ampia gamma di piattaforme Windows. Poiché la libreria fornisce funzionalità non disponibili in precedenza, questa versione sostituisce le librerie seguenti:

  • Libreria matematica Xbox fornita dall'intestazione Xboxmath.h
  • Libreria D3DX 9 fornita dalle DLL D3DX 9
  • Libreria matematica D3DX 10 fornita tramite le DLL D3DX 10
  • Libreria matematica XNA fornita dall'intestazione xnamath.h in DirectX SDK e Xbox 360 XDK

Queste sezioni illustrano le nozioni di base per iniziare.

Scarica

La libreria DirectXMath è inclusa in Windows SDK. In alternativa, è possibile scaricarlo da GitHub/Microsoft/DirectXMath. Questo sito contiene anche progetti di esempio correlati.

requisiti di sistema Run-Time

La libreria DirectXMath usa istruzioni del processore specializzate per le operazioni vettoriali quando sono disponibili. Per evitare che un programma generi errori di "eccezione di istruzione sconosciuta", verificare il supporto del processore chiamando XMVerifyCPUSupport prima di usare la libreria DirectXMath.

Questi sono i requisiti di supporto di base della libreria DirectXMath:

  • La compilazione predefinita in una piattaforma Windows (x86/x64) richiede il supporto delle istruzioni SSE/SSE2.
  • La compatibilità predefinita in una piattaforma Windows RT richiede il supporto per le istruzioni ARM-NEON.
  • La compilazione con _XM_NO_INTRINSICS_ definita richiede solo il supporto delle operazioni a virgola mobile standard.

Nota

Quando chiami XMVerifyCPUSupport, includi <windows.h> prima di includere <DirectXMath.h>. Si tratta dell'unica funzione nella libreria che richiede qualsiasi contenuto da <windows.h> , quindi non è necessario includere <windows.h> in ogni modulo che usa <DirectXMath.h>.

 

Panoramica della progettazione

La libreria DirectXMath supporta principalmente il linguaggio di programmazione C++. La libreria viene implementata usando routine inline nei file di intestazione, DirectXMath*.inl, DirectXPackedVector.inl e DirectXCollision.inl. Questa implementazione usa funzioni intrinseche del compilatore ad alte prestazioni.

La libreria DirectXMath fornisce:

  • Implementazione che usa intrinseci SSE/SSE2.
  • Implementazione senza oggetti intrinseci.
  • Implementazione che usa gli intrinseci ARM-NEON.

Poiché la libreria viene recapitata usando i file di intestazione, usare il codice sorgente per personalizzare e ottimizzare l'app.

Convenzione matrice

DirectXMath usa matrici row-major, vettori di riga e pre-moltiplicazione. La mano è determinata dalla versione della funzione usata (RH vs. LH), in caso contrario la funzione funziona con coordinate di visualizzazione sinistrorse o destrorse.

Per riferimento, Direct3D ha usato storicamente il sistema di coordinate sinistrorso, le matrici principali di riga, i vettori di riga e la pre-moltiplicazione. Direct3D moderno non ha un requisito sicuro per le coordinate sinistro e destrorse e in genere gli shader HLSL usano per impostazione predefinita matrici principali della colonna. Per informazioni dettagliate, vedere HLSL Matrix Ordering .See HLSL Matrix Ordering for details.

Utilizzo di base

Per usare le funzioni della libreria DirectXMath, includere le intestazioni DirectXMath.h, DirectXPackedVector.h, DirectXColors.h e/o DirectXCollision.h. Le intestazioni sono disponibili in Windows Software Development Kit per le app di Windows Store.

Linee guida per l'utilizzo dei tipi

I tipi XMVECTOR e XMMATRIX sono i cavalli di lavoro per la libreria DirectXMath. Ogni operazione utilizza o produce dati di questi tipi. L'uso di tali librerie è fondamentale per l'uso della libreria. Tuttavia, poiché DirectXMath usa i set di istruzioni SIMD, questi tipi di dati sono soggetti a una serie di restrizioni. È fondamentale comprendere queste restrizioni se si vuole usare le funzioni DirectXMath.

È consigliabile considerare XMVECTOR come proxy per un registro hardware SIMD e XMMATRIX come proxy per un raggruppamento logico di quattro registri hardware SIMD. Questi tipi vengono annotati per indicare che richiedono l'allineamento a 16 byte per funzionare correttamente. Il compilatore li inserisce automaticamente nello stack quando vengono usati come variabile locale o li inserisce nel segmento di dati quando vengono usati come variabile globale. Con le convenzioni appropriate, possono anche essere passate in modo sicuro come parametri a una funzione (vedere Convenzioni di chiamata per informazioni dettagliate).

Le allocazioni dall'heap, tuttavia, sono più complesse. Di conseguenza, è necessario prestare attenzione ogni volta che si usa XMVECTOR o XMMATRIX come membro di una classe o di una struttura da allocare dall'heap. In Windows x64 tutte le allocazioni di heap sono allineate a 16 byte, ma per Windows x86 sono allineate solo a 8 byte. Sono disponibili opzioni per l'allocazione di strutture dall'heap con allineamento a 16 byte (vedere Allineamento corretto delle allocazioni). Per i programmi C++, è possibile usare overload new/delete/new[]/delete[] (globalmente o specifici della classe) per applicare l'allineamento ottimale, se necessario.

Nota

In alternativa all'applicazione dell'allineamento direttamente nella classe C++ eseguendo l'overload di new/delete, è possibile usare il linguaggio pImpl. Se si garantisce che la classe Impl sia allineata tramite _aligned_malloc internamente, è possibile usare liberamente i tipi allineati all'interno dell'implementazione interna. Si tratta di un'opzione valida quando la classe "public" è una classe di riferimento Windows Runtime o destinata all'uso con std::shared_ptr<>, che in caso contrario può interrompere l'allineamento accurato.

 

Tuttavia, spesso è più semplice e più compatto evitare di usare XMVECTOR o XMMATRIX direttamente in una classe o struttura. Usare invece XMFLOAT3, XMFLOAT4, XMFLOAT4X3, XMFLOAT4X4 e così via, come membri della struttura. Inoltre, è possibile usare le funzioni Vector Loading and Vector Storage per spostare i dati in modo efficiente in variabili locali XMVECTOR o XMMATRIX , eseguire calcoli e archiviare i risultati. Sono inoltre disponibili funzioni di streaming (XMVector3TransformStream, XMVector4TransformStream e così via) che operano in modo efficiente su matrici di questi tipi di dati.

Creazione di vettori

VETTORI COSTANTI

Molte operazioni richiedono l'uso di costanti nei calcoli vettoriali e esistono diversi modi per caricare un XMVECTOR con i valori desiderati.

  • Se si carica una costante scalare in tutti gli elementi di un XMVECTOR, usare XMVectorReplicate o XMVectorReplicateInt.

    XMVECTOR vFive = XMVectorReplicate( 5.f );
    
  • Se si usa una costante vettoriale con valori fissi diversi come XMVECTOR, usare le strutture XMVECTORF32, XMVECTORU32, XMVECTORI32 o XMVECTORU8 . È quindi possibile farvi riferimento direttamente ovunque si passerebbe un valore XMVECTOR .

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

    Nota

    Non usare elenchi di inizializzatori direttamente con XMVECTOR (ovvero XMVECTOR v = { 1.0f, 2.0f, 3.0f, 4.0f }). Questo codice è inefficiente e non è portabile in tutte le piattaforme supportate da DirectXMath.

     

  • DirectXMath include una serie di costanti globali predefinite che è possibile usare nel codice (g_XMOne, g_XMOne3, g_XMTwo, g_XMOneHalf, g_XMHalfPi, g_XMPi e così via). Cercare i valori XMGLOBALCONST nell'intestazione DirectXMath.h.

  • Esistono un set di costanti vettoriali per i colori RGB comuni (Rosso, Verde, Blu, Giallo e così via). Per altre info su queste costanti vettoriali, vedi DirectXColors.h e lo spazio dei nomi DirectX::Colors.

VETTORI DALLE VARIABILI

VETTORI DA VETTORI

  • Se si crea un vettore da un altro vettore con un componente specifico impostato su una variabile, è possibile usare funzioni di accesso vettoriale.

    XMVECTOR v2 = XMVectorSetW( v1, fw );
    
  • Se si crea un vettore da un altro vettore con un singolo componente replicato, usare XMVectorSplatX, XMVectorSplatY, XMVectorSplatZ eXMVectorSplatW.

    XMVECTOR vz = XMVectorSplatZ( v );
    
  • Se si crea un vettore da un altro vettore o una coppia di vettori con componenti riordinati, vedere XMVectorSwizzle e 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 );
    

VETTORI DALLA MEMORIA

Estrazione di componenti da vettori

L'elaborazione SIMD è più efficiente quando i dati vengono caricati nei registri SIMD e completamente elaborati prima di estrarre i risultati. La conversione tra forme scalari e vettoriali è inefficiente, pertanto è consigliabile farlo solo quando necessario. Per questo motivo, le funzioni nella libreria DirectXMath che producono un valore scalare vengono restituite in una forma vettoriale in cui il risultato scalare viene replicato nel vettore risultante, ovvero XMVector2Dot, XMVector3Length e così via. Tuttavia, quando sono necessari valori scalari, ecco alcune scelte su come procedere:

  • Se viene calcolata una singola risposta scalare, l'uso delle funzioni di accesso vettoriale è appropriato:

    float f = XMVectorGetX( v );
    
  • Se è necessario estrarre più componenti del vettore, è consigliabile archiviare il vettore in una struttura di memoria e leggerlo di nuovo. Ad esempio:

    XMFLOAT4A t;
    XMStoreFloat4A( &t, v );
    // t.x, t.y, t.z, and t.w can be individually accessed now
    
  • La forma più efficiente di elaborazione vettoriale consiste nell'usare lo streaming da memoria a memoria in cui i dati di input vengono caricati dalla memoria (usando Funzioni di caricamento vettoriale), elaborate completamente in formato SIMD e quindi scritte in memoria (usando Le funzioni dell'archivio vettoriale).

Guida alla programmazione DirectXMath