2016-10-26 16 views
0

前/後の乗算、列/行のメジャー、DirectXとOpenGLについて複数の記事や記事を読みましたが、最初よりも混乱するかもしれません。だから、OpenGL対DirectX、ローカル対グローバル?

、我々はOpenGLでこれらの命令(擬似コード)を書きましょう:

回転(...) は=「OpenGLはVを行います、私が理解から(...)

を翻訳R * T * vであり、ベクトルのローカル座標フレームを効果的に変換する。

しかし、DirectXの中、私たちは同じ順序で変換(擬似コード)を行う場合、

回転(...) 翻訳(...)

結果は、同じではありません右? DirectXはあらかじめ乗算するので、結果はv '= v * R * Tになり、グローバル座標を使用してベクトルが変換されます。

OpenGLがポスト乗算であり、DirectXが事前乗算されていると言うと、DirectXがグローバル座標で移動している間にOpenGLがローカル座標で移動すると言うのは正しいですか?

ありがとうございます。

+2

OpenGLまたはDirectXに 'rotate()'または 'translate()'メソッドはありません。あなたは何を指していますか?そして古い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ゲームStudioの数学ライブラリ(したがってなどMonogame、ユニティ、)右手系、行優先の行列、行ベクトル、および事前乗算を使用しています。

DirectXMathライブラリは、行優先行列、行ベクトル、および事前乗算を使用しますが、重要なところで左利きまたは右手座標システムを使用することを選ぶことができます。これは今も年上の人にも当てはまりましたdeprecated D3DXMath

どちらのシステムでも、同じオブジェクト座標 - >ワールド座標 - >アイ座標 - >クリップ座標変換を行っています。

だから、OpenGLのGLMであなたが行う可能性があります:

あなたは思いDirectXMathで
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; 

を:

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に新しいしている場合は、C++のコンストラクタと事業者と厳格なSIMDフレンドリーなアライメント要件の一部を隠しDirectX Tool KitSimpleMathラッパーを見てみる必要があります。 SimpleMathはXNA Game Studio C#の数学デザインに基づいているため、右利きのビュー座標を前提としていますが、必要に応じて「ネイティブ」DirectXMathと簡単に混合して左利きのビュー座標を使用することもできます。

これらの決定のほとんどは恣意的ですが、健全な設計思考がありました。 OpenGLの数学ライブラリは、ポスト乗法の通常の数学的慣習に合致しようとしていました。 Direct3Dの初期の段階で、チームは連結順序の逆転が混乱していると感じ、すべての規則を逆転させました。

XNA Game Studioチームは、従来のDirect3D連結命令は直感的であると感じましたが、「進む」が負のzであることは混乱して右利きの座標に切り替わりました。したがって、より現代的なDirect3Dサンプルの多くは、右利きビューシステムを使用していますが、Direct3Dサンプルの左右の両方の表示設定が混在しています。この時点で、実際には「OpenGLスタイル」、古典的なDirect3Dスタイル "、および"近代的なDirect3Dスタイル "です。

固定機能のハードウェアを使用していたものの、プログラマブルなシェーダパイプラインを使用していたとき、これらの規約は本当に重要でした。実際、HLSLシェーダは、行列が列メジャー形式であることを期待しているため、DirectXMath行列が定数バッファにコピーされるときに転置されることがよくあります。

関連する問題