開始入門(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 命名空間。
來自變數的向量
如果從單一純量變數建立向量,請參閱 XMVectorReplicate 和 XMVectorReplicateInt。
XMVECTOR v = XMVectorReplicate( f );
如果從四個純量變數建立向量,請參閱 XMVectorSet 和 XMVectorSetInt。
XMVECTOR v = XMVectorSet( fx, fy, fz, fw );
從向量中產生的向量
如果從另一個向量建立向量,並將特定元件設定為變數,您可以考慮使用 向量存取子函式。
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 );
來自記憶體的向量
- 若要從記憶體載入單一浮點數,請參閱 XMVectorReplicatePtr、XMVectorReplicateIntPtr、XMLoadFloat和 XMLoadInt。
- 載入 float 陣列的常見方式包括:XMLoadFloat2、XMLoadFloat3、XMLoadFloat4、 XMLoadFloat3x3、XMLoadFloat4x3和 XMLoadFloat4x4。
- DirectXMath 包含一組豐富的類型和相關的載入,以及處理各種數據結構和一般 GPU 格式的存放區。 請參見 向量載入 和 向量存放區。
從向量擷取元件
當資料載入 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 形式完整處理,然後寫入記憶體(使用 向量存放區函式)。
相關主題