【问题标题】:Why does QMatrix4x4::lookAt() result in a upside down camera为什么 QMatrix4x4::lookAt() 会导致相机倒置
【发布时间】:2014-02-25 18:56:00
【问题描述】:

我有一个简单的 OpenGL 程序,它按如下方式设置相机:

void
SimRenderer::render() {
glDepthMask(true);

glClearColor(0.5f, 0.5f, 0.7f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

glFrontFace(GL_CW);
glCullFace(GL_FRONT);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);

QMatrix4x4 mMatrix;
QMatrix4x4 vMatrix;

QMatrix4x4 cameraTransformation;
cameraTransformation.rotate(mAlpha, 0, 1, 0); // mAlpha = 25
cameraTransformation.rotate(mBeta, 1, 0, 0);  // mBeta = 25

QVector3D cameraPosition = cameraTransformation * QVector3D(0, 0, mDistance);
QVector3D cameraUpDirection = cameraTransformation * QVector3D(0, 1, 0);

vMatrix.lookAt(cameraPosition, QVector3D(0, 0, 0), cameraUpDirection);

mProgram.bind();
mProgram.setUniformValue(mMatrixUniformLoc, mProjMatrix *  vMatrix * mMatrix );

// render a grid....
}

但结果是一个倒置的相机!

!1

当我将视图矩阵更改为: QVector3D cameraUpDirection = cameraTransformation * QVector3D(0, -1, 0);

有效!但是,当我的实际向上方向是正 Y 时,为什么我需要将我的向上方向设置为负 Y 呢?

在这里完成课程:https://code.google.com/p/rapid-concepts/source/browse/trunk/simviewer/simrenderer.cpp

其他信息:我正在渲染到 QQuickFramebufferObject,它在调用渲染函数之前将 FBO 绑定到小部件表面。不要认为这将是一个问题,但无论如何。而且这根本不是纹理问题,没有要翻转的纹理等。似乎相机正在以相反的方式解释向上的方向!

http://doc.qt.digia.com/qt-maemo/qmatrix4x4.html#lookAt


更新:

因此,由于同时使用 lookat 和 cameraTransformations 可能不起作用,我正在尝试:

QMatrix4x4 mMatrix;
QMatrix4x4 vMatrix;

QMatrix4x4 cameraTransformation;
cameraTransformation.rotate(mAlpha, 0, 1, 0); // 25
cameraTransformation.rotate(mBeta, 1, 0, 0);  // 25

cameraTransformation.translate(0, 0, mDistance);  

vMatrix = cameraTransformation.inverted();

产生完全相同的结果:)

我认为需要以某种方式考虑相机上轴。

【问题讨论】:

    标签: opengl fbo qt5.1


    【解决方案1】:

    实际上倒置的不是相机,而是将纹理渲染到 QML 表面的倒置。这真的很令人困惑,因为如果您使用基于小部件的堆栈 (QOpenGLWidget) 或仅使用 QOpenGLWindow,您确实会得到正确的方向(Y 向上)。

    this question基本相同。可以在on the forumin the bug tracker找到一些解释。

    我认为最好的解决方案是错误跟踪器中的解决方案,它不需要对 QML 项或矩阵进行额外的转换:覆盖 updatePaintNodesetTextureCoordinatesTransform 到垂直镜像。

    QSGNode *MyQQuickFramebufferObject::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *nodeData)
    {
        if (!node) {
            node = QQuickFramebufferObject::updatePaintNode(node, nodeData);
            QSGSimpleTextureNode *n = static_cast<QSGSimpleTextureNode *>(node);
            if (n)
                n->setTextureCoordinatesTransform(QSGSimpleTextureNode::MirrorVertically);
            return node;
        }
        return QQuickFramebufferObject::updatePaintNode(node, nodeData);
    }
    

    【讨论】:

      【解决方案2】:

      通常,这种影响是由几件事之一引起的。

      • 混合弧度和度数
      • 忘记将模型视图矩阵设置为相机变换的
      • 搞砸输入以查看

      我怀疑这是最后一个问题。

      QVector3D cameraUpDirection = cameraTransformation * QVector3D(0, 1, 0);
      

      为什么要将向上向量乘以这个变换?我可以理解乘以距离,以便转换相机位置,旋转发送到查看函数的向上轴会导致我怀疑的怪异。

      通常,使用相机矩阵和使用lookat 进行变换有点奇怪。如果您已经有一个具有适当旋转的相机矩阵,您可以将该矩阵平移所需的距离,表示为适当长度的 Z 向量,可能是QVector3D(0, 0, mDistance),然后将视图矩阵设置为相机的倒数矩阵:

      vMatrix = cameraTransformation.inverted();
      

      【讨论】:

      • 好的,我尝试单独使用 cameraTransformation,但它仍然产生完全相同的结果(请参阅主要问题的编辑)。我想知道现在如何决定相机上轴。
      猜你喜欢
      • 2018-08-14
      • 2020-06-18
      • 2011-12-12
      • 1970-01-01
      • 2021-02-18
      • 2012-08-19
      • 2013-01-08
      • 2013-10-04
      • 1970-01-01
      相关资源
      最近更新 更多