opengl - 无法实现透视图

时间:2014-04-30 21:38:33

标签: opengl

我正在编写一个OpenGL应用程序。程序需要在中心具有简单的形状,并且用户可以将视图从正交视图改变为透视视图,反之亦然。我在处理正交视图方面没有任何问题,但我无法从正交视角切换到视角,即使gluPerspective看起来非常简单。

我写的代码看起来像这样:

void myDisplay(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();
    glTranslatef(0, 0, -3);
    glRotatef(xRot, 1.0, 0.0, 0.0);
    glRotatef(yRot, 0.0, 1.0, 0.0);
    glRotatef(zRot, 0.0, 0.0, 1.0);
    glScalef(scale, scale, scale);
    glPushAttrib(GL_ENABLE_BIT);

    if (currentStyle) {
        if (currentStyle == STYLE_DOTTED)  glLineStipple(currentStyle, 0xAAAA);
        else glLineStipple(currentStyle, 0x0F0F * currentStyle);
        glEnable(GL_LINE_STIPPLE);
    }
    setColor();
    drawObjectOfType();

    glPopAttrib();
    glFlush();
}

void myKeyboard(unsigned char key, int x, int y)
{
    switch (key)
    {
    case 'p':
        isOrtho = !isOrtho;

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        if(!isOrtho) {
            gluPerspective(55,1,5,3);
            gluLookAt(0,0,-7,0,0,0,0,1,0);
        } else {
            glOrtho(-2.0, 2.0, -2.0, 2.0, -10.0, 10.0);
        }
        glMatrixMode(GL_MODELVIEW);
        break;
    }
    glutPostRedisplay();
}

该计划也有照明。这是处理光照的init函数。

void init()
{
    GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat mat_shininess = { 100.0 };
    GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat light_position[] = { 0.0, 0.0, 10.0, 0.0 };

    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);

    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess);

    glShadeModel(GL_SMOOTH);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

    createMenus();

    glEnable(GL_DEPTH_TEST);
    glClearColor(0.0, 0.0, 0.0, 1.0);
}

此代码发生的变化是视图从正交到透视的变化,但摄像机和多边形之间的距离似乎已恢复,这意味着多边形越接近摄像机,它看起来越小。例如,我有一个立方体作为形状,靠近我的脸看起来更小,而对立面应该是这样。

2 个答案:

答案 0 :(得分:1)

gluPerspective()的最后两个参数是zNearzFar。您已将近剪裁平面设置得比远剪裁平面更远,这反转了透视校正。

答案 1 :(得分:0)

gluLookAt定义了一个查看转换,因此应该成为您的MODELVIEW转换的一部分。您的代码将其乘以PROJECTION转换。尝试使用这样的序列作为透视设置案例:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(55,1,3,5);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,-7,0,0,0,0,1,0);

然后在glPushMatrix函数中使用glPopMatrixglLoadIdentity代替myDisplay

你的近处和远处的飞机彼此非常接近。我们在代码中没有看到您发布的对象坐标范围。你要小心它会在你的近距离和远距离之间结束,这样它就不会被夹住。