我有一个程序来做增强现实,我在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参数中做什么/修改才能获得放大/缩小效果?
答案 0 :(得分:0)
通常情况下,不是通过更改gluPerspective()
中的 fov 来完成的。
通常,您可以将转换应用于模型和/或视图矩阵。如果要移动模型,通常在模型矩阵中执行此操作。如果要更改“摄像机位置”,通常在视图矩阵中执行此操作。
在您的情况下,您可能会翻译View Matrix。因为这可以解决3D物体移开或靠近相机的错觉。
如果您仍在使用固定功能管道,则可以通过调用以下某些功能来执行这些更改。
glMatrixMode(x);
- 其中x为GL_PROJECTION_MATRIX
或GL_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()
透视投影矩阵的真正含义进行比较射影几何,并使用任何您自己的几何。