GluPerspective 表现怪异

GluPerspective acting strange

我正在尝试在触摸 F2 和 F3 时更改场景中的视野。 为此,我在我的 specialKey 函数中有这个:

void specialKey(int key, int x, int y) {
    switch (key) {
    case GLUT_KEY_F2:
        changeFOV = true;
        fovScale = 0.05;
        break;
    case GLUT_KEY_F3:
        changeFOV = true;
        fovScale = -0.05;
        break;
}

我有一个定时函数,它每毫秒调用一次 myDisplay,在那个函数中我做了:

if(changeFOV){
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    fovAngle += fovScale;
    gluPerspective(fovAngle, screenWidth/screenHeight, 2, 200);
    glTranslatef(camera.x, camera.y, camera.z);
    glMatrixMode(GL_MODELVIEW);
    changeFOV = false;
}

现在我第一次按 F2 或 F3 时,场景会变小到一个像素的大小(大约),但如果我继续按 F3,场景会越来越近,然后它会正常工作(F2 和 F3) .

fovAngle一开始是60.0f(不按F2或F3场景好看)

这是我的 init() 函数:

void init() {
    glInitNames();
    gluPerspective(fovAngle, screenWidth/screenHeight, 2, 200);
    glTranslatef(camera.x, camera.y, camera.z);
    glClearColor(0, 0, 0, 1);
    glViewport(0.0, 0.0, screenWidth, screenHeight);

    glutInitWindowSize(screenWidth, screenHeight);
    string windowName = "AMAZING 3D MODELING - ";
    windowName += (sceneMode ? "Scene" : "Camera");
    glutCreateWindow(windowName.c_str());
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_NORMALIZE);
    glEnable(GL_COLOR_MATERIAL);
    glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
    glMaterialfv(GL_FRONT, GL_AMBIENT, object_ambient);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, object_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, object_specular);
    glMaterialfv(GL_FRONT, GL_SHININESS, object_shine);
    glutDisplayFunc(displayFunc);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutSpecialFunc(specialKey);
    glutKeyboardFunc(keyboard);
    glutTimerFunc(2, idle, 1);
    glutMainLoop();
}

有什么想法吗? (如果需要更多代码,请询问,我将编辑问题)

主要问题是您在拥有 OpenGL 上下文之前调用 GL 函数。上下文是作为 glutCreateWindow() 的一部分创建的,因此您的所有 OpenGL 调用,例如您的整个初始投影设置,都需要移动 after glutCreateWindow().

您似乎还缺少对 glutInit() 的调用,它应该在最开始。我很惊讶你的代码没有它也能正常工作。

摄像机平移通常应处于模型视图矩阵模式。它不会改变几何体的结果位置,但否则光照会出错。

出现这种情况的原因很可能是您的相机距离很远。由于 projection/camera 没有在初始渲染上设置,所以没有应用,几何图形出现了。然后第一次应用 projection/camera 时,一切都变得非常小,因为你从很远的地方看它。然后,当您缩小 FOV 时,几何尺寸会增加。

所以你需要做的是:

  • 在开头添加对 glutInit() 的调用。
  • 将所有初始化调用移到 glutCreateWindow() 之后。
  • 在模型视图模式下设置相机平移。
  • 把相机移近一点。

我会将转换设置放在一个函数中,您可以在初始化时和更改时调用该函数。该函数将包含如下内容:

void setTransformations() {
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(fovAngle, screenWidth/screenHeight, 2, 200);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(camera.x, camera.y, camera.z);
}

然后你在初始化时调用它:

glutCreateWindow(...);
setTransformations();

当 FOV 改变时:

if (changeFOV) {
    fovAngle += fovScale;
    changeFOV = false;
    setTransformations();
}