2

我有一个程序来做增强现实,我在 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 如何调用与我对 gluPerspective() 的调用相匹配的 glFrustum()?”,我尝试了:

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 参数以获得放大/缩小效果?

4

2 回答 2

0

通常,它不是通过更改fov in来完成的gluPerspective()

通常,您会为此对模型和/或视图矩阵应用转换。如果要移动模型,通常在模型矩阵中进行。如果要更改“相机位置”,通常在 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 数学)之类的东西。

于 2013-12-18T11:31:12.820 回答
0

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

根据我的理解,OpenGL函数中投影矩阵的几何意义,在OpenGLGLFrustum()官方指南(本书第九版,OpenGL编程指南——学习OpenGL的官方指南)中,从代数角度进行了解释看来,实际上对应于许多与作者预期不同的几何含义。

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

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

以下矩阵分解(不是唯一的)对应于非奇异GLFrustum()矩阵的几何含义之一: 在此处输入图像描述

公式的 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)项外,上述所有矩阵因子的几何意义在《初等几何变换统一框架》中都有明确的重新定义。如果您选择这种分解作为GLFrustum()透视投影矩阵的几何含义解释,您将必须确保您在代码中进行的任何计算或变换都与其几何含义一致。

所以当你在用 OpenGL 编程的时候GLFrustum(),可能要对比一下官方指南中已经说明的东西,以及GLFrustum()从纯代数投影几何的角度来看透视投影矩阵的真正含义,并使用你自己的任何一种。

于 2020-02-15T05:09:32.193 回答