9

私はGLMライブラリを使用して、OpenGL3とGLSLで数学演算を実行し始めました。2Dグラフィックスを描画するには正射影が必要なので、次の簡単なコードを記述しました。

glm::mat4 projection(1.0);
projection = glm::ortho( 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 500.0f);

glm::orthoが作成した値を画面に印刷すると次のようになります。

 0.00313   0.00000   0.00000   0.00000
 0.00000  -0.00417   0.00000   0.00000
 0.00000   0.00000  -0.00200   0.00000
-1.00000   1.00000  -1.00000   1.00000

私が知っているように、これはOpenGLの値の正しい順序ではありません。これは、この行列に位置ベクトルを乗算すると、すべての変換値が無視されるためです。

シェーダーといくつかのプリミティブを使用してそのマトリックスをテストしましたが、空白の画面しか表示されません。しかし、次のようにマトリックスを手動で変更すると、問題なく機能します。

 0.00313   0.00000   0.00000  -1.00000
 0.00000  -0.00417   0.00000   1.00000
 0.00000   0.00000  -0.00200  -1.00000
 0.00000   0.00000   0.00000   1.00000

さらに、「glm / gtc/matrix_transform.inl」ファイルの関数「ortho」を見てください。

template <typename valType>
inline detail::tmat4x4<valType> ortho(
    valType const & left,
    valType const & right,
    valType const & bottom,
    valType const & top,
    valType const & zNear,
    valType const & zFar)
{
    detail::tmat4x4<valType> Result(1);
    Result[0][0] = valType(2) / (right - left);
    Result[1][1] = valType(2) / (top - bottom);
    Result[2][2] = - valType(2) / (zFar - zNear);
    Result[3][0] = - (right + left) / (right - left);
    Result[3][1] = - (top + bottom) / (top - bottom);
    Result[3][2] = - (zFar + zNear) / (zFar - zNear);
    return Result;
}

最後の3つの初期化行を次のコードに置き換え、正常に機能しました。

    Result[0][3] = - (right + left) / (right - left);
    Result[1][3] = - (top + bottom) / (top - bottom);
    Result[2][3] = - (zFar + zNear) / (zFar - zNear);

これは、テストに使用している最小限の頂点シェーダーです(現時点では、uni_MVPは上記で説明した射影行列のみであることに注意してください)。

uniform mat4 uni_MVP;

in  vec2 in_Position;

void main(void)
{
  gl_Position = uni_MVP * vec4(in_Position.xy,0.0, 1.0);
}

すべての機能が同じように機能するため、これはバグではないと思います。多次元配列の順序を逆にする私のC++コンパイラの問題かもしれませんか?すべてのGLMソースコードを変更せずにこれを解決するにはどうすればよいですか?

WindowsVistaで実行されているCode:: BlocksとMinGWで最新バージョンのGLMライブラリ(0.9.1)を使用しています。

4

1 に答える 1

22

まず、それは反転ではなく転置と呼ばれます。反転とは、まったく異なることを意味します。第二に、これはまさにそれが想定されている方法です。OpenGLは、列の主要な順序で行列にアクセスします。つまり、行列要素は次のインデックスを使用する必要があります。

 0  4  8  12
 1  5  9  13
 2  6 10  14
 3  7 11  15

ただし、通常は次のように番号を付ける通常のC / C++多次元配列:

 0  1  2  3
 4  5  6  7
 8  9 10 11
12 13 14 15

つまり、行と列のインデックスが入れ替わります。古いバージョンのOpenGLは、コードを書き直す人を救うために、行列を転置形式で提供できる拡張機能を備えていました。GL_ARB_transpose_matrixhttp: //www.opengl.org/registry/specs/ARB/transpose_matrix.txt と呼ばれます

シェーダーを使用すると、新しい関数を使用するよりも簡単です。glUniformMatrixにはパラメーターがありGLboolean transpose、それが何をするかを3つ推測できます。

于 2011-02-23T21:59:13.313 に答える