開始入門(DirectXMath)

DirectXMath 連結庫會針對單精度浮點向量(2D、3D 和 4D)或矩陣(3×3 和 4×4)實作算術和線性代數運算的最佳可攜式介面。 程式庫對整數向量運算的支援有限。 這些作業在圖形程序轉譯和動畫中廣泛使用。 不支援雙精度向量(包括 longs、shorts 或 bytes),且僅有限支援整數向量運算。

連結庫可在各種 Windows 平臺上使用。 因為連結庫提供先前無法使用的功能,因此此版本會取代下列連結庫:

  • 由 Xboxmath.h 標頭提供的 Xbox 數學函式庫
  • D3DX 9 的 DLL 所提供的 D3DX 9 庫檔
  • 透過 D3DX 10 DLL 提供的 D3DX 10 數學函式庫
  • DirectX SDK 和 Xbox 360 XDK 中由 xnamath.h 標頭檔案提供的 XNA 數學庫

這些章節概述入門的基本概念。

下載

DirectXMath 連結庫包含在 Windows SDK 中。 或者,您可以從 GitHub/Microsoft/DirectXMath下載。 此網站也包含相關的範例專案。

Run-Time 系統需求

DirectXMath 函式庫會在可使用向量作業時,使用特殊的處理器指令。 若要避免程序產生「未知的指令例外狀況」錯誤,請在使用 DirectXMath 連結庫之前呼叫 XMVerifyCPUSupport 來檢查處理器支援。

以下是基本的 DirectXMath 連結庫運行時間支援需求:

  • Windows (x86/x64) 平臺上的預設編譯需要 SSE/SSE2 指示支援。
  • Windows RT 平臺上的預設相容性需要 ARM-NEON 指示支援。
  • 使用 _XM_NO_INTRINSICS_ 定義的編譯需要標準浮點運算支援。

注意

當您呼叫 XMVerifyCPUSupport時,請先包含 <windows.h>,再包含 <DirectXMath.h>。 這是程式庫中唯一需要 <windows.h 內容> 的函式,因此您不需要在每一個使用 <DirectXMath.h>的模組中包含 <windows.h>。

 

設計概觀

DirectXMath 連結庫主要支援C++程式設計語言。 程式庫是使用頭檔中的內聯函式來實作的,包括 DirectXMath*.inl、DirectXPackedVector.inl 和 DirectXCollision.inl。 此實作會使用高效能編譯程式內部函數。

DirectXMath 函式庫提供:

  • 使用 SSE/SSE2 內部函數的實作。
  • 沒有內部函數的實作。
  • 使用內建函數 ARM-NEON 實作。

由於此程式庫是透過標頭檔提供的,請使用原始碼來自訂和優化您自己的應用程式。

矩陣慣例

DirectXMath 使用數據列主要矩陣、數據列向量和預先乘法。 手動性取決於使用哪個函式版本(RH 與 LH),否則函式可與左側或右手檢視座標搭配運作。

參考而言,Direct3D 過去曾使用左手座標系、列優先矩陣、行向量和預先乘法。 新式 Direct3D 對左側與右手座標沒有很強的需求,而且通常 HLSL 著色器預設為取用數據行主要矩陣。 如需詳細資訊,請參閱 HLSL 矩陣排序。

基本使用方式

若要使用 DirectXMath 函式庫函式,請包含 DirectXMath.h、DirectXPackedVector.h、DirectXColors.h 和/或 DirectXCollision.h 標頭檔案。 標頭位於適用於 Windows 市集應用程式的 Windows 軟體開發工具包中。

類型使用方針

XMVECTOR 和 XMMATRIX 類型是 DirectXMath 函式庫的核心組件。 每個作業都會取用或產生這些類型的數據。 與它們合作是使用圖書館的關鍵。 不過,由於 DirectXMath 會使用 SIMD 指令集,因此這些數據類型受限於一些限制。 如果您想要善用 DirectXMath 函式,請務必了解這些限制。

您應該將 XMVECTOR 視為 SIMD 硬體快取器的 Proxy,而 XMMATRIX 作為四個 SIMD 硬體快取器的邏輯群組 Proxy。 這些類型會加上批注,指出它們需要16位元組的對齊才能正確運作。 編譯程式會在當做局部變數使用時,自動將它們正確地放在堆疊上,或將它們當成全域變數使用時,將它們放在數據區段中。 使用適當的慣例,它們也可以安全地當做參數傳遞至函式(如需詳細資訊,請參閱 呼叫慣例)。

不過,從堆疊的分配更為複雜。 因此,每當您使用 XMVECTOR 或 XMMATRIX 作為需要從堆積中分配的類別或結構的成員時,您都必須小心。 在 Windows x64 上,所有堆積配置都對齊 16 位元組,但針對 Windows x86,它們只會對齊 8 位元組。 有選項可以從堆中配置結構體,以16位元對齊方式進行配置(請參閱 正確對齊配置)。 針對C++程式,您可以使用運算符 new/delete/new[]/delete[] 多載(全域或特定類別),視需要強制執行最佳對齊方式。

注意

除了直接在 C++ 類別中透過多載 new/delete 強制執行對齊,您可以使用 pImpl 設計模式 。 如果您確定 Impl 類別透過內部 _aligned_malloc 對齊,則可以在內部實作中自由使用對齊的類型。 當 'public' 類別是 Windows 執行階段 ref 類別,或搭配 std::shared_ptr<>使用時,這是一個很好的選擇,否則可能會破壞精確的對齊。

 

不過,避免直接在類別或結構中使用 XMVECTOR 或 XMMATRIX,通常比較簡單且更精簡。 請改用 XMFLOAT3、XMFLOAT4、XMFLOAT4X3、XMFLOAT4X4等作為結構的成員。 此外,您可以使用 向量載入 和 向量儲存 函式,有效率地將數據移至 XMVECTOR 或 XMMATRIX 局部變數、執行計算,以及儲存結果。 還有串流函式(XMVector3TransformStream、XMVector4TransformStream等等),可有效地在這些數據類型的陣列上直接作。

建立向量

常數向量

許多作業都需要在向量計算中使用常數,而且有許多方法可以使用所需的值來載入 XMVECTOR。

  • 如果將純量常數載入 XMVECTOR的所有元素,請使用 XMVectorReplicate 或 XMVectorReplicateInt。

    XMVECTOR vFive = XMVectorReplicate( 5.f );
    
  • 如果使用具有不同固定值的向量常數做為 XMVECTOR,請使用 XMVECTORF32、XMVECTORU32、XMVECTORI32或 XMVECTORU8 結構。 然後,您可以在任何需要傳遞 XMVECTOR 值的地方直接參考這些值。

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

    注意

    請勿直接使用初始化列表搭配 XMVECTOR(即 XMVECTOR v = { 1.0f, 2.0f, 3.0f, 4.0f })。 這類程式代碼沒有效率,而且無法在 DirectXMath 支援的所有平臺上移植。

     

  • DirectXMath 包含數個預先定義的全域常數,您可以在程式代碼中使用這些常數(g_XMOne、g_XMOne3、g_XMTwo、g_XMOneHalf、g_XMHalfPi、g_XMPi等等)。 搜尋 DirectXMath.h 標頭中 XMGLOBALCONST 值。

  • 常見的 RGB 色彩有一組向量常數(紅色、綠色、藍色、黃色等等)。 如需這些向量常數的詳細資訊,請參閱 DirectXColors.h 和 DirectX::Colors 命名空間。

來自變數的向量

從向量中產生的向量

  • 如果從另一個向量建立向量,並將特定元件設定為變數,您可以考慮使用 向量存取子函式。

    XMVECTOR v2 = XMVectorSetW( v1, fw );
    
  • 如果要從另一個向量中複製單一元件來建立向量,請使用 XMVectorSplatX、XMVectorSplatY、XMVectorSplatZ和 XMVectorSplatW。

    XMVECTOR vz = XMVectorSplatZ( v );
    
  • 如果從另一個向量或具有重新排序元件的向量組建立向量,請參閱 XMVectorSwizzle 和 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 );
    

來自記憶體的向量

從向量擷取元件

當資料載入 SIMD 暫存器,並在擷取結果之前完整處理時,SIMD 處理最有效率。 純量和向量窗體之間的轉換效率不佳,因此我們建議您只在需要時才這麼做。 因此,產生純量值的 DirectXMath 連結庫中的函式會以向量形式傳回,其中純量結果會復寫到產生的向量中(也就是 XMVector2Dot、XMVector3Length等等)。 不過,當您需要純量值時,以下是一些關於如何進行的選項:

  • 如果計算單一純量回應,則適當使用 向量存取子函式:

    float f = XMVectorGetX( v );
    
  • 如果需要擷取向量的多個元件,請考慮將向量儲存在記憶體結構中,並將它讀回。 例如:

    XMFLOAT4A t;
    XMStoreFloat4A( &t, v );
    // t.x, t.y, t.z, and t.w can be individually accessed now
    
  • 向量處理最有效率的形式是使用記憶體到記憶體串流,其中輸入數據會從記憶體載入(使用 向量載入函式),並以 SIMD 形式完整處理,然後寫入記憶體(使用 向量存放區函式)。

DirectXMath 程式設計手冊