glFrustum,gluPerspective和FOV

时间:2013-12-18 10:48:34

标签: opengl glut augmented-reality perspectivecamera frustum

我有一个程序来做增强现实,我在OpenGL中使用:

glFrustum(-near*centerImageX/(GLfloat)fx, near*(imageWidth-centerImageX)/(GLfloat)fx, near*(centerImageY-imageHeight)/(GLfloat)fy, near*centerImageY/(GLfloat)fy, near, far);

这没关系,我得到了很好的视角,我的3D对象很好地插在我的照片上。现在我希望能够放大/缩小。通常,它是通过改变gluPerspective中的fov来完成的,但我不使用gluPerspective,因为我无法获得良好的插入。

使用http://dmi.uib.es/~josemaria/files/OpenGLFAQ/transformations.htm,问题“9.085如何调用glFrustum()以匹配我对gluPerspective()的调用?”,我试过:

fov=360.0*atan(imageHeight/(2*fy))/Pi;  //computed with parameters top and bottom of my glFrustum
aspect=-centerImageY*fx/(fy*(centerImageX-imageWidth)); //computed with parameters left and bottom of my glFrustum

void glFrustum(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble near,GLdouble far);

void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble near,GLdouble far);

然后:

gluPerspective(fov, aspect, near, far);

但是我的物体被扭曲了,它在所有轴上都没有正确缩放,比例没有保留。

那么我需要在glFrustum参数中做什么/修改才能获得放大/缩小效果?

2 个答案:

答案 0 :(得分:0)

通常情况下,不是通过更改gluPerspective()中的 fov 来完成的。

通常,您可以将转换应用于模型和/或视图矩阵。如果要移动模型,通常在模型矩阵中执行此操作。如果要更改“摄像机位置”,通常在视图矩阵中执行此操作。

在您的情况下,您可能会翻译View Matrix。因为这可以解决3D物体移开或靠近相机的错觉。

如果您仍在使用固定功能管道,则可以通过调用以下某些功能来执行这些更改。

  • glMatrixMode(x); - 其中x为GL_PROJECTION_MATRIXGL_MODELVIEW_MATRIX
  • glLoadIdentity(); - “重置”当前选定的矩阵。
  • glTranslate*(x, y, z);
  • glRotate*(angle, x, y, z);
  • glScale*(x, y, z);

但是,如果您使用的是现代OpenGL,那么请不要使用上面的内容(当时您也不能使用)。相反,您希望自己计算所有矩阵变换并将它们传递给着色器。如果您不想自己计算所有这些高级矩阵运算,可以使用GLM(OpenGL数学)。

答案 1 :(得分:0)

我不是OpenGL程序员。我的兴趣主要在于代数射影几何。

根据我的理解,OpenGL函数GLFrustum()中投影矩阵的几何含义,在OpenGL官方指南(本书的第9版,OpenGL编程指南-OpenGL从代数的角度来看,学习OpenGL)实际上对应于许多几何意义,这些意义与作者所期望的不同。

它们之间的显着区别是: 1.在官方指南中,作者正在说明一个复合线性变换,其中一个因子为central projection,因此最终的复合透视投影矩阵应该是奇异矩阵或退化矩阵; 2.虽然仍在官方指南中,但在附录中,GLFrustum()透视投影矩阵是非奇异的4乘4方阵!

请注意:作者正在尝试将非奇异矩阵解释为理论上奇异的矩阵!

以下矩阵分解(不是唯一的)对应于非奇异GLFrustum()矩阵的几何含义之一: enter image description here

配方的LaTeX代码:

$$n\underbrace{\color{blue}\left[
\begin{array}{cccc}
 1 & 0 & 0 & 0 \\[12pt]
 0 & 1 & 0 & 0 \\[12pt]
 0 & 0 &\dfrac{n+f}{(n-f) n} & 0 \\[12pt]
 0 & 0 & 0 & 1 \\[12pt]
\end{array}
\right]}_{\color{red}(1)}\cdot \underbrace{\color{blue}\left[
\begin{array}{cccc}
\dfrac{ -2}{l-r} & 0 & 0 & \dfrac{l+r}{l-r} \\[12pt]
 0 & \dfrac{ -2}{b-t} & 0 & \dfrac{b+t}{b-t} \\[12pt]
 0 & 0 & 1 & 0 \\[12pt]
 0 & 0 & 0 & 1 \\[12pt]
\end{array}
\right]}_{\color{red}(2)}\cdot\underbrace{\color{blue}\left[
\begin{array}{cccc}
 1 & 0 & 0 & 0 \\[12pt]
 0 & 1 & 0 & 0 \\[12pt]
 0 & 0 & 1 & 0 \\[12pt]
 0 & 0 & -\dfrac{1}{n} & 1 \\[12pt]
\end{array}
\right]}_{\color{red}(3)}\cdot\underbrace{\color{blue}\left[
\begin{array}{cccc}
 1 & 0 & 0 & 0 \\[12pt]
 0 & 1 & 0 & 0 \\[12pt]
 0 & 0 & 1 & 1 \\[12pt]
 0 & 0 & 0 & \dfrac{1}{n} \\[12pt]
\end{array}
\right]}_{\color{red}(4)}\cdot\underbrace{\color{blue}\left[
\begin{array}{cccc}
 1 & 0 & 0 & 0 \\[12pt]
 0 & 1 & 0 & 0 \\[12pt]
 0 & 0 & 1 & 0 \\[12pt]
 0 & 0 & 0 & \dfrac{2 n f}{f+n} \\[12pt]
\end{array}
\right]}_{\color{red}(5)} $$

除了(2)以外,上述所有矩阵因子的几何地义在Unified Framework of Elementary Geometric Transformations中都有清晰的定义。如果选择这种分解作为GLFrustum()透视投影矩阵的几何含义的解释,则必须确保在代码中进行的任何计算或变换都与其几何含义一致。

因此,当您使用OpenGL GLFrustum()进行编程时,可能必须与官方指南中说明的内容以及从纯代数的角度来看GLFrustum()透视投影矩阵的真正含义进行比较射影几何,并使用任何您自己的几何。