GluPerspective行为奇怪

时间:2015-05-30 11:48:01

标签: opengl glut scene glu

我正在尝试在触摸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时,场景变小到一个像素(aprox)的大小但是如果我继续按F3,场景越来越近,然后它正常工作(F2和F3)。 / p>

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();
}

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

1 个答案:

答案 0 :(得分:3)

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

您似乎也错过了对glutInit()的调用,这应该是最开始的。我很惊讶你的代码在没有它的情况下工作。

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

这样做的原因很可能是你的相机很远。由于未在初始渲染上设置投影/相机,因此不会应用投影/相机,并且会显示几何体。然后第一次应用投影/相机时,一切都变得非常小,因为你从很远的地方看它。然后,当您使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);
}

然后在init期间调用它:

glutCreateWindow(...);
setTransformations();

当FOV发生变化时:

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