我很难理解在对 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;
}
}
为了避免向任一方向拉伸对象,您需要使 (右 - 左)/(上 - 下) 与窗口的宽高比匹配。在您的情况下,您可以通过将 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。