1. ホーム
  2. c++

[解決済み] glm::ortho()は実は間違っている?

2022-03-02 12:16:17

質問

最近、OpenGLが提供する行列演算や固定関数パイプラインなどの古い(非推奨)機能から乗り換えるのは良いアイデアだと思いました。

私は、物事を少し単純化するために、GLMを行列ライブラリとして使用しています。問題は、それが単純化するよりも多くの問題を引き起こしているかもしれないことです...。

透視投影は私のシェーダーとセットアップで問題なく動作しましたが、直交投影に切り替えようとしたところ、すべてが崩壊してしまいました。ポイントやシンプルな四角形が表示されないのです。古いOpenGLのマトリクスを使用すると、物事は再び動作し始めました。

その結果、投影行列に行き着いたのです。以下はその呼び方です。

glm::mat4 projMat = glm::ortho( 0, 400, 0, 400, -1, 1 );

これを一旦openglが提供する"と比較しました。

glOrtho( 0, 400, 0, 400, -1, 1 );

唯一の違いは [0][0] 要素と [1][1] 要素です (私の知る限り、それぞれ "2/width" と "2/height" に等しいです)。OpenGLの行列から、その値はまさにそれでした! しかし、glmのマトリックスでは、値は0でした。

glm::orthoを呼び出した後、glmマトリックスの値を手動で切り替えると、すべてが再び動作するようになりました!

そこで質問ですが、glm::ortho()関数は本当に壊れているのでしょうか、それとも私の使い方が間違っているだけなのでしょうか?

解決方法は?

ソースコード(v 0.9.3.4)を見る限りでは壊れているはずはないようです

template <typename valType> 
GLM_FUNC_QUALIFIER 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;
}

ただひとつ思うのは、このテンプレートは整数の行列を作成しており(関数にすべてのintを渡しているため)、その結果浮動小数点ではなく整数の除算を行っているのではないかということです。そこで .f をすべてのパラメータに追加してください。

glm::mat4 projMat = glm::ortho( 0.f, 400.f, 0.f, 400.f, -1.f, 1.f );