glm 中矩阵值的顺序不正确?

发布于 2024-10-18 14:37:29 字数 2101 浏览 1 评论 0原文

我开始使用 GLM 库通过 OpenGL 3 和 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 源代码的情况下解决这个问题?

我正在使用最新版本的 GLM 库 (0.9.1) 以及在 Windows Vista 上运行的 Code::Blocks 和 MinGW。

I started using GLM library to do mathematics operations over OpenGL 3 and GLSL.
I need an orthographic projection to draw 2D graphics, so I writed this simple code:

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

Printing on screen the values that glm::ortho has created I get:

 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

As I know this is not the correct order for the values in OpenGL, because multiplying this matrix by a position vector will ignore all translation values.

I tested that matrix with my shader and some primitives and I only get a blank screen. But if I modify by hand the matrix as follows it works ok:

 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

Moreover, looking at the function "ortho" in the "glm/gtc/matrix_transform.inl" file:

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;
}

I have replaced the last 3 initialization lines by the following code and also worked ok:

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

This is a minimal vertex shader that I'm using for test (note that at this moment the uni_MVP is only the projection matrix explained above):

uniform mat4 uni_MVP;

in  vec2 in_Position;

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

I thik that this is not a bug, because all functions works the same way.
Maybe is an issue of my C++ compiler that inverts the order of multidimensional arrays?
How can I solve this without modifying all GLM source code?

I'm using the last version of GLM library (0.9.1) with Code::Blocks and MinGW running on Windows Vista.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

雨后咖啡店 2024-10-25 14:37:29

首先,这叫转置,而不是倒置。反转意味着完全不同的东西。其次,这正是它应该的样子。 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_matrix http://www.opengl.org /registry/specs/ARB/transpose_matrix.txt

使用着色器甚至比使用新函数更容易。 glUniformMatrix 有一个参数 GLboolean transpose,你有 3 个猜测它的作用。

First, it's called transposition, not inversion. Inversion means something completely different. Second, this is exactly how it's supposed to be. OpenGL accesses matrices in column major order, i.e. the matrix elements have to following indices:

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

However your usual C/C++ multidimensional arrays you normally number like this:

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

i.e. row and column indices are transposed. Older versions of OpenGL sported some extension that allows to supply matrices in transposed form, to spare people rewriting their code. It's called GL_ARB_transpose_matrix http://www.opengl.org/registry/specs/ARB/transpose_matrix.txt

With shaders it's even easier than having to use new functions. glUniformMatrix has a parameter GLboolean transpose, you've got 3 guesses what it does.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文