使用 Qt/OpenGL 保持正投影比例的问题

问题描述 投票:0回答:1

我很难理解在对 QMatrix4x4::ortho(left、right、bottom、top、near、far) 进行的调用中应该使用哪些值。

具体来说,我不理解有关 left、right、bottom 和 top 值的文档。 我有一个可以使用投影矩阵绘制 OpenGL 猴子的工作演示。 我设置了演示,以便当我按键盘上的“O”时,它将投影矩阵从透视切换为正交。 透视投影效果很好,因为它可以保持模型的纵横比恒定(即,它不会在宽度或高度上拉伸)。 这是当调用“O”或“P”键并更新 m_proj 时调用的函数。 正如你所看到的,这有点混乱,我尝试了很多想法,但没有一个真正按照我想要的方式工作。

感谢您提供任何有助于我理解这一点的见解。 其他有用的细节:我的视眼位于 z=2 处,面向中心 (0,0,0),向上为 (0,1,0)。

void AppGLScene::setProjectionMatrix(void)
{
    m_projectionMatrix.setToIdentity();
    float windowWidth = rect().width();
    float windowHeight = rect().height();
    float left, right, bottom, top;
    float aratio = (float) windowWidth / (float) windowHeight;
    qDebug() << "win wid, win hei" << windowWidth << windowHeight;

    // I modify the vertical FOV in an attempt to keep the size of the
    // model the same as the vertical size of the window changes.
    //
    float vFov = 90 * ((float)windowHeight / m_initialWinHeight);
    qDebug() << "vFov" << vFov;

    switch (m_proj)
    {
    case PROJ_PERSP:
        m_projectionMatrix.perspective(vFov, qreal(windowWidth)/qreal(windowHeight), 0.5, 40);
        break;
    case PROJ_ORTHO:
    default:
//        left = rect().x();
//        right = rect().x() + rect().width();
//        bottom = rect().y();
//        top = rect().y() + rect().height();
        if (windowWidth > windowHeight)
        {
            left = -(3.0 - ((float)windowHeight/(float)windowWidth));
            right = -left;
            bottom = -3.0;
            top = 3.0;
        }
        else
        {
            left = -3.0;
            right = 3.0;
            bottom = -(3.0 - ((float)windowWidth/(float)windowHeight));
            top = -bottom;
        }

        qDebug() << "l r b t = " << left << right << bottom << top;
        m_projectionMatrix.ortho(left, right, bottom, top, 0.5, 40);
//        m_projectionMatrix.ortho(-3.0, 3.0, -3.0, 3.0, 0.5, 40);
//        m_projectionMatrix.ortho(-aratio, aratio, -aratio, aratio, 0.5, 40);
        break;
    }
}
qt opengl orthographic
1个回答
3
投票

为了避免向任一方向拉伸对象,您需要使 (右 - 左)/(上 - 下) 与窗口的宽高比匹配。在您的情况下,您可以通过将 right 设为 top 乘以纵横比的值来确保这一点。

看起来您想使用范围 [-3.0, 3.0] 作为较短的窗口尺寸,并相应地调整较长的窗口尺寸。上面的内容翻译成:

if (windowWidth > windowHeight)
{
    top = 3.0f;
    bottom = -top;
    right = top * aratio;
    left = -right;
}
else
{
    right = 3.0f;
    left = -right;
    top = right / aratio;
    bottom = -top;
}

请注意,对于这两种情况,right / top = aratio

© www.soinside.com 2019 - 2024. All rights reserved.