OpenGL改变背景而不改变以前绘制的图片的透视
OpenGL change background without changing perspective of previously drawn pictures
所以我画了一个 'I' 并使用 gluLookAt(0.f,0.f,3.f,0.f,0.f,0.f,0.f,1.f,0.f), I 大小适中。然后我添加了一个 drawScene() 函数,用渐变颜色绘制背景,然后 'I' 变得非常大。我想这是因为我在 drawScene() 中将矩阵模式更改为 GL_PROJECTION 和 GL_MODELVIEW,这些可能会改变视角?我想需要 glPushMatrix() 和 glPopMatrix() 来保留矩阵状态,但我很难找到将它们放在哪里。那么如何使 'I' 看起来正常大小呢?这是我的 drawI() 和 drawScene():
void drawI(int format)
{
glBegin(format);
glColor3f(0, 0, 1);
glVertex2f(point[3][0], point[3][1]);
glVertex2f(point[2][0], point[2][1]);
glVertex2f(point[1][0], point[1][1]);
glVertex2f(point[12][0], point[12][1]);
glVertex2f(point[10][0], point[10][1]);
glEnd();
glBegin(format);
glVertex2f(point[10][0], point[10][1]);
glVertex2f(point[11][0], point[11][1]);
glVertex2f(point[12][0], point[12][1]);
glEnd();
glBegin(format);
glVertex2f(point[9][0], point[9][1]);
glVertex2f(point[10][0], point[10][1]);
glVertex2f(point[3][0], point[3][1]);
glVertex2f(point[4][0], point[4][1]);
glVertex2f(point[6][0], point[6][1]);
glColor3f(1, 0.5, 0);
glVertex2f(point[7][0], point[7][1]);
glVertex2f(point[8][0], point[8][1]);
glEnd();
glBegin(format);
glColor3f(0, 0, 1);
glVertex2f(point[5][0], point[5][1]);
glVertex2f(point[6][0], point[6][1]);
glVertex2f(point[4][0], point[4][1]);
glEnd();
}
void drawScene()
{
glBegin(GL_QUADS);
//red color
glColor3f(1.0,0.0,0.0);
glVertex2f(-1.0,-1.0);
glVertex2f(1.0,-1.0);
//blue color
glColor3f(0.0,0.0,1.0);
glVertex2f(1.0, 1.0);
glVertex2f(-1.0, 1.0);
glEnd();
}
非常感谢!
所以我从 drawScene() 和 drawI() 中取出 glMatrixMode() 和 glLoadIdentity() 并将它们放在 display() 中。我更改了上面的 drawScene() 和 drawI(),这里是我的 display()
void display()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70.f,1.f,0.001f,30.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawScene();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.f,0.f,3.f,0.f,0.f,0.f,0.f,1.f,0.f);
drawI(GL_TRIANGLE_FAN);
glutSwapBuffers();
}
执行此操作(在 3D 模式下)的正常方法是在您的代码中,在您调用 drawI 或 drawScene 之前:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fov, aspect, near, far); // fov is camera angle in degrees, aspect is width/height of your viewing area, near and far are your near and far clipping planes.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,0.0,3.0,0.0,0.0,0.0,0.0,1.0,0.0)
在您的 2D 渲染中,您可能不需要调用 gluPerspective,但这些调用应该在您调用 drawI 或 drawScene 之前在您的代码中完成。执行此操作并从 drawI 和 drawScene 中删除 glMatrixMode() 和 glLoadIdentity() 调用。
编辑:
如果您的 "I" 仍然太大,您可以做很多事情,但您可能应该在 3D 模式下操作(也给出 Z 坐标)。
您可以缩放对象:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,0.0,3.0,0.0,0.0,0.0,0.0,1.0,0.0)
glScalef(0.5, 0.5, 0.5);
您可以将相机进一步向后移动(您还需要包含 gluPerspective() 调用):
gluLookAt(0.0,0.0,50.0,0.0,0.0,0.0,0.0,1.0,0.0);
也许在 3D 模式下控制渲染图像大小的最简单方法是将相机(眼睛)向后移动一段距离,然后通过更改相机孔径角(gluPerspective() 中的 fov)来控制图像大小称呼)。更宽的 fov 会缩小渲染图像;更小的 fov 会放大它。
我不知道 drawI 中你的坐标值是多少,因为它们是变量,但是相机位置 3.0、视野 70.0 和纵横比 1 应该会给你左、右、上和Z = 0 处的底部裁剪平面约为 +/- 2.1。
如果您保持其他一切不变并将相机移动到 50.0,则裁剪平面将在 +/- 35.0 左右,因此您的 "I" 将占据更小的查看区域部分。
如果您随后将相机位置保留在 50.0,但将 fov 更改为 40.0,则裁剪平面将约为 +/- 18.2。您的 "I" 将填充比 cameraZ = 50.0、fov = 70.0 时更大的区域,但比 cameraZ = 3.0、fov = 70.0 时的区域更小。
您可以调整相机位置和视野以获得您想要的图像大小,或者您可以只缩放图像。我喜欢保持相机位置不变并改变 fov。如果我提供一个根据用户输入(可能是鼠标滚动)改变 fov 的功能,这是提供缩放 in/out 效果的好方法。
顺便说一句,在你的原始代码中,如果你调用:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,0.0,3.0,0.0,0.0,0.0,0.0,1.0,0.0)
然后稍后在 DrawI 或 drawScene 中调用:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
您已经丢弃了之前调用 gluLookAt() 时加载的矩阵。
所以我画了一个 'I' 并使用 gluLookAt(0.f,0.f,3.f,0.f,0.f,0.f,0.f,1.f,0.f), I 大小适中。然后我添加了一个 drawScene() 函数,用渐变颜色绘制背景,然后 'I' 变得非常大。我想这是因为我在 drawScene() 中将矩阵模式更改为 GL_PROJECTION 和 GL_MODELVIEW,这些可能会改变视角?我想需要 glPushMatrix() 和 glPopMatrix() 来保留矩阵状态,但我很难找到将它们放在哪里。那么如何使 'I' 看起来正常大小呢?这是我的 drawI() 和 drawScene():
void drawI(int format)
{
glBegin(format);
glColor3f(0, 0, 1);
glVertex2f(point[3][0], point[3][1]);
glVertex2f(point[2][0], point[2][1]);
glVertex2f(point[1][0], point[1][1]);
glVertex2f(point[12][0], point[12][1]);
glVertex2f(point[10][0], point[10][1]);
glEnd();
glBegin(format);
glVertex2f(point[10][0], point[10][1]);
glVertex2f(point[11][0], point[11][1]);
glVertex2f(point[12][0], point[12][1]);
glEnd();
glBegin(format);
glVertex2f(point[9][0], point[9][1]);
glVertex2f(point[10][0], point[10][1]);
glVertex2f(point[3][0], point[3][1]);
glVertex2f(point[4][0], point[4][1]);
glVertex2f(point[6][0], point[6][1]);
glColor3f(1, 0.5, 0);
glVertex2f(point[7][0], point[7][1]);
glVertex2f(point[8][0], point[8][1]);
glEnd();
glBegin(format);
glColor3f(0, 0, 1);
glVertex2f(point[5][0], point[5][1]);
glVertex2f(point[6][0], point[6][1]);
glVertex2f(point[4][0], point[4][1]);
glEnd();
}
void drawScene()
{
glBegin(GL_QUADS);
//red color
glColor3f(1.0,0.0,0.0);
glVertex2f(-1.0,-1.0);
glVertex2f(1.0,-1.0);
//blue color
glColor3f(0.0,0.0,1.0);
glVertex2f(1.0, 1.0);
glVertex2f(-1.0, 1.0);
glEnd();
}
非常感谢!
所以我从 drawScene() 和 drawI() 中取出 glMatrixMode() 和 glLoadIdentity() 并将它们放在 display() 中。我更改了上面的 drawScene() 和 drawI(),这里是我的 display()
void display()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70.f,1.f,0.001f,30.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawScene();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.f,0.f,3.f,0.f,0.f,0.f,0.f,1.f,0.f);
drawI(GL_TRIANGLE_FAN);
glutSwapBuffers();
}
执行此操作(在 3D 模式下)的正常方法是在您的代码中,在您调用 drawI 或 drawScene 之前:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fov, aspect, near, far); // fov is camera angle in degrees, aspect is width/height of your viewing area, near and far are your near and far clipping planes.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,0.0,3.0,0.0,0.0,0.0,0.0,1.0,0.0)
在您的 2D 渲染中,您可能不需要调用 gluPerspective,但这些调用应该在您调用 drawI 或 drawScene 之前在您的代码中完成。执行此操作并从 drawI 和 drawScene 中删除 glMatrixMode() 和 glLoadIdentity() 调用。
编辑:
如果您的 "I" 仍然太大,您可以做很多事情,但您可能应该在 3D 模式下操作(也给出 Z 坐标)。
您可以缩放对象:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,0.0,3.0,0.0,0.0,0.0,0.0,1.0,0.0)
glScalef(0.5, 0.5, 0.5);
您可以将相机进一步向后移动(您还需要包含 gluPerspective() 调用):
gluLookAt(0.0,0.0,50.0,0.0,0.0,0.0,0.0,1.0,0.0);
也许在 3D 模式下控制渲染图像大小的最简单方法是将相机(眼睛)向后移动一段距离,然后通过更改相机孔径角(gluPerspective() 中的 fov)来控制图像大小称呼)。更宽的 fov 会缩小渲染图像;更小的 fov 会放大它。
我不知道 drawI 中你的坐标值是多少,因为它们是变量,但是相机位置 3.0、视野 70.0 和纵横比 1 应该会给你左、右、上和Z = 0 处的底部裁剪平面约为 +/- 2.1。
如果您保持其他一切不变并将相机移动到 50.0,则裁剪平面将在 +/- 35.0 左右,因此您的 "I" 将占据更小的查看区域部分。
如果您随后将相机位置保留在 50.0,但将 fov 更改为 40.0,则裁剪平面将约为 +/- 18.2。您的 "I" 将填充比 cameraZ = 50.0、fov = 70.0 时更大的区域,但比 cameraZ = 3.0、fov = 70.0 时的区域更小。
您可以调整相机位置和视野以获得您想要的图像大小,或者您可以只缩放图像。我喜欢保持相机位置不变并改变 fov。如果我提供一个根据用户输入(可能是鼠标滚动)改变 fov 的功能,这是提供缩放 in/out 效果的好方法。
顺便说一句,在你的原始代码中,如果你调用:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,0.0,3.0,0.0,0.0,0.0,0.0,1.0,0.0)
然后稍后在 DrawI 或 drawScene 中调用:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
您已经丢弃了之前调用 gluLookAt() 时加载的矩阵。