我的问题是为什么我有三个不同的矩阵,有什么区别,这是从剪辑到眼睛空间转换坐标的正确方法。
详细说明:
我正在尝试使用OpenGL的投影矩阵来实现虚拟扫描仪,我使用此矩阵将坐标从剪辑转换为眼睛空间。 我找到了三种方法:
glGetFloatv(GL_PROJECTION_MATRIX,projection_tmp);
glm :: mat4 Proj = glm :: perspective( FOV, 方面, zNear,zFar);
传递给这三种方法的参数如下:
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
谢谢!
答案 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;
}