OpenGL为什么我从相同的参数得到三个不同的投影矩阵

时间:2017-05-19 07:56:20

标签: opengl matrix

我的问题是为什么我有三个不同的矩阵,有什么区别,这是从剪辑到眼睛空间转换坐标的正确方法。

详细说明:

我正在尝试使用OpenGL的投影矩阵来实现虚拟扫描仪,我使用此矩阵将坐标从剪辑转换为眼睛空间。 我找到了三种方法:

  1. glGetFloatv(GL_PROJECTION_MATRIX,projection_tmp);

  2. glm :: mat4 Proj = glm :: perspective(   FOV,   方面,   zNear,zFar);

  3. 通过此页面提供的方法手动计算:gluperspective source code
  4. 传递给这三种方法的参数如下:

    const double zNear = 1;
    const double zFar = 10001;//for computational convenience
    const double fov = _model.getCamera().getFieldOfViewAngle();//60
    //w(523)h(489) 
    const double aspect = static_cast<double>(w) / static_cast<double>(h);
    

    然后我得到三个不同的矩阵:

    glGetFloatv:

    1.61945       0       0       0
          0 1.73205       0       0
          0       0 -1.0002      -1
          0       0 -2.0002       0
    

    GLM:

    -0.145971         0         0         0
            0  -0.15612         0         0
            0         0   -1.0002        -1
            0         0   -2.0002         0
    

    手册:

    0.504724        0        0        0
           0  0.57735        0        0
           0        0  -1.0002        1
           0        0  -2.0002        0
    

    谢谢!

1 个答案:

答案 0 :(得分:2)

glGetFloatv版本是三者中唯一正确的版本。

GLM版本希望角度为弧度,因此您应该将fovy更正为tau/360

第三个版本与链接答案中的版本不完全相同。链接答案中的代码将否定一个写入m[11],而您发布正面一个。让我们假设它是一个拼写错误并查看其他数字。这里的代码完全错误:它乘以tan(fov/2)而不是除以它。这就是它获得0.57735 = 1/1.73205的原因。

我不知道为什么人们在实施它时遇到了麻烦。只需从gluPerspective specification获取公式并将其写在代码中:

void gluPerspectivInRadians(double m[16],
    double fovy, double aspect, double zNear, double zFar)
{
    double f = 1/tan(fovy/2);
    m[0] = f/aspect; m[1] = 0; m[2] = 0; m[3] = 0;
    m[4] = 0; m[5] = f; m[6] = 0; m[7] = 0;
    m[8] = 0; m[9] = 0; m[10] = (zFar+zNear)/(zNear-zFar); m[11] = -1;
    m[12] = 0; m[13] = 0; m[14] = 2*zFar*zNear/(zNear-zFar); m[15] = 0;
}