共用方式為


開始入門(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 軟體開發工具包中。

類型使用方針

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

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

不過,從堆疊的分配更為複雜。 因此,每當您使用 XMVECTORXMMATRIX 作為需要從堆積中分配的類別或結構的成員時,您都必須小心。 在 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<>使用時,這是一個很好的選擇,否則可能會破壞精確的對齊。

 

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

建立向量

常數向量

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

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

    XMVECTOR vFive = XMVectorReplicate( 5.f );
    
  • 如果使用具有不同固定值的向量常數做為 XMVECTOR,請使用 XMVECTORF32XMVECTORU32XMVECTORI32XMVECTORU8 結構。 然後,您可以在任何需要傳遞 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 );
    
  • 如果要從另一個向量中複製單一元件來建立向量,請使用 XMVectorSplatXXMVectorSplatYXMVectorSplatZXMVectorSplatW

    XMVECTOR vz = XMVectorSplatZ( v );
    
  • 如果從另一個向量或具有重新排序元件的向量組建立向量,請參閱 XMVectorSwizzleXMVectorPermute

    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 連結庫中的函式會以向量形式傳回,其中純量結果會復寫到產生的向量中(也就是 XMVector2DotXMVector3Length等等)。 不過,當您需要純量值時,以下是一些關於如何進行的選項:

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

    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 程式設計手冊