OpenGL GLSL - 投影矩阵不起作用

Posted

技术标签:

【中文标题】OpenGL GLSL - 投影矩阵不起作用【英文标题】:OpenGL GLSL - Projection matrix not working 【发布时间】:2016-05-26 18:09:31 【问题描述】:

我有一个基本的 OpenGL 应用程序,我想使用我的投影矩阵。

这是我的矩阵:

WorldCoordinates.m[0][0] = 2.0f / Width - 1.0f; WorldCoordinates.m[0][1] = 0; WorldCoordinates.m[0][2] = 0, WorldCoordinates.m[0][3] = 0;
WorldCoordinates.m[1][0] = 0; WorldCoordinates.m[1][1] = 2.0f / Height - 1.0f; WorldCoordinates.m[1][2] = 0, WorldCoordinates.m[1][3] = 0;
WorldCoordinates.m[2][0] = 0; WorldCoordinates.m[2][1] = 0; WorldCoordinates.m[2][2] = 0, WorldCoordinates.m[2][3] = 0;
WorldCoordinates.m[3][0] = 0; WorldCoordinates.m[3][1] = 0; WorldCoordinates.m[3][2] = 0, WorldCoordinates.m[3][3] = 0;

(WorldCoordinates 是 Matrix4 结构,它只包含一个名为 m 的变量,它是一个 float[4][4])(Width 和 Height 是两个 ints)。 然后我将这个坐标应用到我的 vertex 着色器上:

shader.Bind();
glUniformMatrix4fv(glGetUniformLocation(shader.GetProgramID(), "worldCoordinates"), 1, GL_TRUE, &WorldCoordinates.m[0][0]);

(Shader 是一个类,并且有一个 Bind() 方法,即 glUseProgram)。

这是我的顶点着色器 GLSL

#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;
layout (location = 2) in vec2 texCoord;

out vec3 Color;
out vec2 TexCoord;

uniform mat4 worldCoordinates;

void main()

    gl_Position = worldCoordinates * vec4(position, 1.0f);
    Color = color;
    TexCoord = texCoord;

使用它,它不起作用。但是将 gl_Position 调用更改为:

gl_Position = vec4(vec3(position.x * 1/400 -1, position.y * 1/300 -1, 1.0f), 1.0f);

它按预期呈现。这是为什么呢?

【问题讨论】:

投影矩阵看起来很奇怪(而且还有一个奇怪的名字:投影从世界坐标到屏幕坐标)。为什么只设置了[0][0][1][1] @pingul 不要看名字,我还是得改变一切。这个投影矩阵应该只是将我的坐标从屏幕更改为 OpenGL 坐标。所以 OpenGL 中的 -1,-1 是我的 0,0,而 1,1 是我的宽度、高度。然后我计算出,要应用这种转换,我只需要设置矩阵的这两个变量 我认为你想错了。投影矩阵的要点是从您的世界坐标(即您正在创建的 3D 世界)到屏幕坐标。本质上,我们将点投影到 3D 空间到我们的 2D 屏幕。最简单的投影矩阵是单位矩阵(即没有投影)。你试过用那个吗? 设置对角矩阵为1,即[0][0] = 1[1][1] = 1 我会尽量试试这个。顺便说一句,我在着色器中应用矩阵的方式是否正确? 【参考方案1】:

这是构建正交投影矩阵的方式:

static void
mat4_ortho(mat4_t m, float left, float right, float bottom, float top, float near, float far)

        float rl = right -  left;
        float tb =   top - bottom;
        float fn =   far -  near;

        mat4_zero(m);

        m[ 0] =  2.0f / rl;
        m[ 5] =  2.0f / tb;
        m[10] = -2.0f / fn;
        m[12] = -(left +  right) / rl;
        m[13] = -( top + bottom) / tb;
        m[14] = -( far +   near) / fn;
        m[15] = 1.0f;

对于您的情况,您可以设置 left=0、right=width、bottom=0、top=height,远近无关紧要,例如设置 -1.0 和 1.0。

使用这样的矩阵,您用于绘图的顶点坐标将与屏幕上的像素 1:1 映射。

【讨论】:

它比我以前的要好,但仍然不是我想要的。它现在渲染屏幕的右上角四分之一,但它应该在左下角渲染一个 32x32 的四边形。这是为什么? PS:使用我问题中的最后一个代码,它可以按我的意愿工作。 好的,现在可以了。显然我在我的矩阵中设置了错误的变量。非常感谢!

以上是关于OpenGL GLSL - 投影矩阵不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 OpenGL 正确投影和扭曲 3d 点

如何在 OpenGL ES 2.0 中将视图/模型/投影矩阵传递给我的顶点着色器?

GLSL:如何使用投影矩阵计算光线方向?

现代 OpenGL 投影视图模型转换不起作用

opengl 矩阵问题

OpenGL 3.2 设置矩阵的麻烦