2013-04-13 15 views
15

私は青い3Dボックス(上の部分は赤色です)を持っているとしましょう。行列変換のOpenglの順

  1. ここで私はglScalef(1、10、1)を呼び出します。
  2. 次に、glRotatef(90、0、1、0)を呼び出します。
  3. 次に、キューブをレンダリングします。

赤い側面が画面に向かって(モデルのY軸に沿って)伸びていることが予想されます。

これは私が見ているものです: 赤い面が画面に向いています(期待通り)。 しかし、ストレッチは(モデルではなく)ビュースペースのY軸上で発生しています。

スケールをZ軸に沿って設定すると、正しい結果が得られることが分かります。 しかし私の混乱は、私がY軸上でスケールアップし、ボックスを回転させて、私に正しい結果を与えると思ったことです。

何が欠けていますか?

+0

私はこの答えが好きです:http://stackoverflow.com/questions/6118996/matrix-mult-order-in-direct3d – AlvinfromDiaspar

答えて

19

OpenGLは、その行列をcolumn major orderという名前で読み取ります。その結果、各後続の演算は、それ以前のすべての演算の事前乗算であり、後の乗算ではありません。したがって、それぞれOpenGL操作(glScale、glTranslate、glRotate)を呼び出すと、オブジェクトに影響を与えるものはどのように書くのか逆になります。最初です。

だから、あなたはあなたの乗算の順序を変更する必要があります。

glRotatef(90, 0, 1, 0); // Notice how this is the first operation ... 
// ... but will be applied after 
glScalef(1, 10, 1); // This will be applied first, but is the last operation 
// Zany, right? 

真実が語られるあなたがプログラムを書くと逆の順序で物事を指定する必要がコンピュータを使用しているとき、それはあまり直感的に感じています。しかし、Graphics Godsは、OpenGLのマトリックススタックが(HLSL、GLSL、および他のシステムと一緒に動作するようにしたいと思っています。上記のリンクを参照してください)。

+2

列の主要な順序でデータを格納することは、操作の順序と関係がありますか? –

+1

詳細については、http://stackoverflow.com/questions/17717600/confusion-between-c-and-opengl-matrix-order-row-major-vs-column-majorを参照してください。 – ToolmakerSteve

+2

これに関するいくつかの背景(またはグラフィックス神の推論):http://steve.hollasch.net/cgindex/math/matrix/column-vec.html – Vitaly

-1

このような4×4行列を表す配列がある場合:

float mat[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; 

を、あなたは、OpenGL行列にこれをロードし、OpenGLは、行列の最初の列のような第2の第4フロートが表示されます2列目は4つの浮動小数点数、3つ目は行列の3列目の浮動小数点数などです。

したがって、4つの浮動小数点数ごとにOpenGLは別の列として認識します。これはColumn-Major orderと呼ばれます。 データを列に格納します。コラムメジャーマトリックスを転置しなければならないのであれば、それは行メジャーマトリックスとして終わり、その逆もあります。

カラムメジャーマトリックスを使用しているため、カラムベクトルを使用する必要があります。つまり、乗算の順番は:M * vです。

これを自分で証明するには、2x1列ベクトルの単純な2x2行列をとり、M * vと乗算します。 K =転置(M)、r =行ベクトル(1×2)とする。あなたのコード内の列または行の主な表記を使用した後

その後 M *のV = R * K

ボトムラインは、あなたはそれに固執する必要があります。

+1

メモリ内の格納順序(行メジャーと列メジャー)は、右側の列として、または左側の行として乗算ベクトルの選択とは無関係です。たとえば、行列が列メジャー順に格納されていても、GLSLの左からベクトルを掛けることができます。 –

+0

はい、GLSLの左から乗算できますが、行列を転置することを忘れないでください。だからこそ、ラケットの質問に答えるだけで、一組の方法に固執するほうが賢明です。ありがとう。 – Michael