等效于Qt和openGL的gluPerspective

gluPerspective equivalent for Qt and openGL

本文关键字:openGL gluPerspective Qt      更新时间:2023-10-16

我正试图让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 );
}

您的透视图函数是正确的(在某种意义上,它与gluPerspective()所做的相同)。但是你应该意识到在resizeGL()中,你同时使用Ortho和Frustum,所以你最终得到一个投影矩阵Ortho* perspective,这基本上在透视失真应用后增加了一些缩放和平移。

你可以使用glFrustum重新实现gluPerspective,或者你正在做未来证明的事情并使用矩阵数学库,如GLM, Eigen或linmath.h,使用它计算矩阵并使用glLoadMatrix或glUniform将其预先计算到OpenGL中。

glFrustum的fNear和fFar参数必须为正