【问题标题】:Where is the camera in OpenGL perspective projection?OpenGL透视投影中的相机在哪里?
【发布时间】:2018-01-23 20:46:58
【问题描述】:

我正在使用 openGL 并遇到一个奇怪的问题。

定义我的截锥体的代码:

glFrustum(0.0, 50.0, 0.0, 50.0, 5.0, 35.0);

生成多边形和曲线的代码

glBegin(GL_POLYGON); // a rectangle
    glVertex3f(20.0, 20.0, -6.0); 
    glVertex3f(20.0, 20.0, -10.0); 
    glVertex3f(20.0, 60.0, -10.0); // point A 
    glVertex3f(20.0, 60.0, -6.0); // point B
glEnd();
glBegin(GL_LINE_STRIP);
for (float i = -PI; i < -PI/3; i += 2 * PI / numSides) {
    glVertex3f(X+14*i, Y + sin(i)*R, -6.0);
}

正如你所看到的,即使 B 点被定义为更靠近投影屏幕,它在 Oxz 平面上的投影也比 A 点的投影要短。这几乎就好像这两个点以某种方式交换了位置,或者相机位置在它们后面,而不是在 (0, 0, 0)。谁可以给我解释一下这个?

【问题讨论】:

  • @Rabbid76 我不明白。 A点的位置(z=-10)比B点的位置(z=-6)离相机更远,对吧?那为什么A点的边比较大呢?
  • 你没有说明相机在哪里。视锥体参数是相对于眼睛空间指定的,但glVertex中的坐标指定物体空间。在应用投影矩阵之前,还有一个步骤是使用 ModelView 矩阵从 object space 转换到 eye space。由于完全不清楚您的转换状态是如何设置的,因此这个问题相当无法回答。您的截锥体参数也很奇怪。此外,您在此处使用的每个单个 GL 函数自十年以来已弃用,并且在现代 OpenGL 中不可用。
  • @derhass 你在说这个吗? glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(0.0, 50.0, 0.0, 50.0, 5.0, 35.0); //glOrtho(0.0, 100.0, 0.0, 100.0, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity();我才开始使用openGL,遵循一本书,它告诉我忽略上面的代码块,所以......
  • 你的假设是错误的。 A 点为 (20.0, 60.0, -6.0),B 点为 (20.0, 60.0, -10.0) - 使用glFrustum(-60.0, 60.0, -60.0, 60.0, 5.0, 35.0); 可以更好地查看场景,因为此时截锥体的原点位于窗口
  • @Rabbid76 如果是这样的话,A点不应该更靠近屏幕吗?由于正 z 轴指向屏幕外

标签: opengl graphics perspectivecamera


【解决方案1】:

你的假设是错误的。 A 点位于 (20.0, 60.0, -6.0),B 点位于 (20.0, 60.0, -10.0强>)。

使用glFrustum(-60.0, 60.0, -60.0, 60.0, 5.0, 35.0); 可以获得更好的场景视图,因为截锥体的原点位于窗口的中间,并将四边形扩展为立方体,通过添加正面和底边,使场景更具空间感:

glFrustum(-60.0, 60.0, -60.0, 60.0, 5.0, 35.0);
glLineWidth( 3.0f );
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

glColor4f( 1.0f, 0.0f, 0.0f, 1.0f );
glBegin(GL_POLYGON);
glVertex3f(20.0, 20.0, -6.0); 
glVertex3f(60.0, 20.0, -6.0); 
glVertex3f(60.0, 60.0, -6.0); 
glVertex3f(20.0, 60.0, -6.0); 
glEnd();
glBegin(GL_POLYGON);
glVertex3f(20.0, 20.0, -6.0); 
glVertex3f(60.0, 20.0, -6.0); 
glVertex3f(60.0, 20.0, -10.0);
glVertex3f(20.0, 20.0, -10.0);
glEnd();

glColor4f( 0.0f, 0.0f, 0.0f, 1.0f );
glBegin(GL_POLYGON);
glVertex3f(20.0, 20.0, -6.0); 
glVertex3f(20.0, 20.0, -10.0); 
glVertex3f(20.0, 60.0, -10.0);
glVertex3f(20.0, 60.0, -6.0);
glEnd();

const float PI = 3.1415917f;
static float X = 20.0f + PI *14;
static float Y = 60.0f;
static float R = 20.0f;
int numSides = 30;
glBegin(GL_LINE_STRIP);
for (float i = -PI; i < -PI/3; i += 2 * PI / numSides) {
    glVertex3f(X+14*i, Y + sin(i)*R, -6.0);
}
glEnd();

看图片,洋红色的十字标记了视角:

【讨论】:

    猜你喜欢
    • 2016-06-26
    • 2015-09-21
    • 2012-05-15
    • 2013-04-17
    • 2013-11-26
    • 1970-01-01
    • 2016-02-11
    • 2021-09-21
    • 2018-07-15
    相关资源
    最近更新 更多