Qt和OpenGL中的gluPerspective等效函数是什么?

3
我正在尝试让Qt和OpenGL一起工作,以便我可以摆脱glu和glut。
除了我的透视矩阵之外,我已经让所有东西按照我想要的方式工作了。
我只是绘制一个简单的3D立方体,并希望我的视角呈倾斜状态。
我尝试编写替代gluPerspective的代码,但我无法得到我想要的结果。
因此,如何正确使用透视矩阵?
注意:我愿意尝试其他替代方案,因为我仍在努力适应OpenGL和Qt,以及如何正确地使用这两个框架。
以下是我的GLWidget类的实现:
GLWidget::GLWidget(QWidget *parent) : QGLWidget(parent) {
    setMouseTracking(true);
}

void GLWidget::initializeGL() {
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glEnable(GL_DEPTH_TEST);
}

void GLWidget::resizeGL(int w, int h) {
    glViewport(0,0,w,h);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-30.0, 30.0, -30.0, 30.0, -30.0, 30.0);

    GLdouble aspect = w / (h ? h : 1);

    const GLdouble zNear = -30.0, zFar = 30.0, fov = 30.0;

    perspective(fov, aspect, zNear, zFar);

    glMatrixMode(GL_MODELVIEW);
}

void GLWidget::paintGL() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3f(1.0, 1.0, 1.0);

    glBegin(GL_LINE_LOOP);
    glVertex3iv(a);
    glVertex3iv(b);
    glVertex3iv(c);
    glVertex3iv(d);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3iv(a);
    glVertex3iv(e);
    glVertex3iv(f);
    glVertex3iv(b);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3iv(d);
    glVertex3iv(h);
    glVertex3iv(g);
    glVertex3iv(c);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3iv(e);
    glVertex3iv(f);
    glVertex3iv(g);
    glVertex3iv(h);
    glEnd();

}

void GLWidget::keyPressEvent(QKeyEvent* event) {
    switch(event->key()) {
    case Qt::Key_Escape:
        close();
        break;
    default:
        event->ignore();
        break;
    }
}

void GLWidget::perspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
{
    GLdouble xmin, xmax, ymin, ymax;

    ymax = zNear * tan( fovy * M_PI / 360.0 );
    ymin = -ymax;
    xmin = ymin * aspect;
    xmax = ymax * aspect;

    glFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
}

为什么不能继续使用glu? - Andreas Haferburg
1
@AndreasHaferburg:也许OP的长期目标是放弃固定功能管线。 - datenwolf
3个回答

4

你的透视函数是正确的(它与gluPerspective()完成的任务相同)。但要注意,在resizeGL()中,你同时使用正交投影和视锥体投影,因此最终得到的投影矩阵是Ortho*Persepctive,这基本上会在应用透视畸变后添加一些缩放和平移。


好的,我只是在使用我的透视矩阵进行测试,但是当我只使用我的透视矩阵时,我只得到一个黑屏,而正交矩阵则使我能够看到我的立方体。从我的透视函数返回一个矩阵,然后使用glLoadMatrixd(...)是否可以解决这个问题? - Pete
@Pete:正如Andreas Haferburg在他的回答中所写的那样,你当前的fNear值是无效的,因此你得不到有用的输出结果也就不足为奇了。你不需要手动加载矩阵,在调用透视函数之前LoadIdentity即可。 - derhass

3

您可以通过使用glFrustum重新实现gluPerspective,或者进行未来的保护并使用矩阵数学库(如GLM、Eigen或linmath.h),使用该库计算矩阵,并使用glLoadMatrix或glUniform将其预先计算并加载到OpenGL中。


3

glFrustum函数中的参数fNear和fFar必须为正数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接