2016-10-26 69 views
0

我已經閱讀了多篇有關前/後乘法,列/行專業版,DirectX與OpenGL的文章和文章,而且我可能會比開頭更困惑。OpenGL vs DirectX,本地還是全球?

所以,讓我們說我們寫在OpenGL的指令(僞):

旋轉(...) 翻譯(...)

據我瞭解,OpenGL的將盡訴」 = R * T * v,有效地轉換矢量的本地座標幀。

但在DirectX中,如果我們做的轉換(僞)以相同的順序,

旋轉(...) 翻譯(...)

結果會不一樣,對?由於DirectX預乘,結果將是v'= v * R * T,因此使用全局座標轉換矢量。

所以,當我說OpenGL是後乘法,DirectX是預乘法就像說OpenGL在本地座標中移動,而DirectX在全局座標中移動時,我是否正確?

謝謝。

+2

沒有'旋轉()'或'翻譯()'在OpenGL或DirectX的方法。那你指的是什麼?舊的OpenGL矩陣堆棧函數'glRotatef()'等不計數。 –

+1

這就是爲什麼我提到僞代碼的原因,因爲我想比較2個庫,而沒有語法方式。 –

+0

但是,如果兩個庫都不支持這種語法,那麼使用這種僞代碼就毫無意義。更具體地說,OpenGL沒有任何集成數學,並且DirectX的數學庫已經被自己提取到一個庫中。 –

回答

0

在OpenGL中沒有預乘的事情。

爲什麼你認爲OpenGL的反轉乘法是,它存儲在列優先佈局矩陣的原因:

a c 
b d 

的換位矩陣相乘的數學規則是:

A^T * B^T = (B*A)^T 

所以如果你想計算v' = v * R * T(所有行 - 主矩陣),你將不得不寫

(v')^T = v * R * T 

或在您的僞代碼:

translate(...) rotate(...) translate(...) 

或者你可以存儲你的旋轉和平移矩陣列主了。

1

你最好打賭是讀Matrices, Handedness, Pre and Post Multiplication, Row vs Column Major, and Notations

  • OpenGL代碼通常使用右手座標系,列主矩陣,列向量和後乘法。

  • Direct3D代碼通常使用左手座標系,行主矩陣,行向量和預乘法。

的XNA Game Studio的數學庫(因此Monogame,團結等)使用右手座標系,行爲主的矩陣,行向量和預乘法。

DirectXMath庫使用行主矩陣,行向量和前乘法,但留給你選擇使用左手或右手座標系統。現在更老的是deprecated D3DXMath

在任一系統中,你還在做同樣的物體座標 - >世界座標 - >眼睛座標 - >剪輯座標轉換。

所以用OpenGL GLM你可以這樣做:

using namespace glm; 

mat4 myTranslationMatrix = translate(10.0f, 0.0f, 0.0f); 

mat4 myRotationMatrix = rotate(90.f, vec3(0, 1, 0)); 

mat4 myScaleMatrix = scale(2.0f, 2.0f, 2.0f); 

mat4 myModelMatrix = myTranslationMatrix * myRotationMatrix * myScaleMatrix; 
vec4 myTransformedVector = myModelMatrix * myOriginalVector; 

在DirectXMath你會怎麼做:

using namespace DirectX; 

XMMATRIX myTranslationMatrix = XMMatrixTranslation(10.0f, 0.0f, 0.0f); 

XMMATRIX myRotationMatrix = XMMatrixRotationY(XMConvertToRadians(90.f)); 

XMMATRIX myScaleMatrix = XMMatrixScaling(2.0f, 2.0f, 2.0f) 

XMMATRIX myModelMatrix = myScaleMatrix * myRotationMatrix * myTranslationMatrix; 
XMVECTOR myTransformedVector = XMVector4Transform(myOriginalVector, myModelMatrix); 

,你會得到相同的變換結果。

如果你是新的DirectXMath,那麼你應該看看在DirectX Tool KitSimpleMath包裝裏面隱藏一些與C++構造函數和運營商嚴格的SIMD友好對齊要求。由於SimpleMath基於XNA Game Studio C#數學設計,因此它假定右手視圖座標,但如果需要,您可以輕鬆地將其與「原生」DirectXMath混合使用以使用左手視圖座標。

大多數這些決定是任意的,但確實有合理的設計推理。 OpenGL的數學庫試圖匹配正常的後乘法數學約定,這導致他們採用列主矩陣。在Direct3D的早期階段,團隊認爲連接順序的顛倒是令人困惑的,所以他們翻轉了所有的約定。多年以後,XNA Game Studio團隊認爲傳統的Direct3D串聯順序很直觀,但是「向前」是負向z令人困惑,所以他們轉向右手座標。因此,許多更現代的Direct3D樣本都使用右手視圖系統,但您仍然可以看到Direct3D樣本的左手和右手視圖設置組合。因此,在這一點上,我們確實擁有「OpenGL風格」,「經典Direct3D風格「和」現代Direct3D風格「。

請注意,當使用固定功能硬件完成某些事情時,這些約定真的很重要,但對可編程着色器流水線而言,重要的是您是一致的。實際上,HLSL着色器默認預期矩陣爲列主要形式,所以您經常會看到DirectXMath矩陣在複製到常量緩衝區時進行轉置。