我有一个简单的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();
产生完全相同的结果:)
我认为需要以某种方式考虑相机向上轴。
答案 0 :(得分:2)
实际上并非倒置的相机,而是将纹理渲染到QML表面上下颠倒。这真是令人困惑,因为如果你使用基于小部件的堆栈(QOpenGLWidget)或只是QOpenGLWindow,你确实得到了正确的方向(Y up)。
基本上与this question相同。可以找到一些解释on the forum或in the bug tracker。
我认为最好的解决方案是bug跟踪器中的一个,它不需要对QML项目或矩阵进行额外的转换:覆盖updatePaintNode
到setTextureCoordinatesTransform
以进行垂直镜像。
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);
}
答案 1 :(得分:1)
通常,此效果是由以下几种原因之一引起的。
我怀疑这是最后一个问题。
QVector3D cameraUpDirection = cameraTransformation * QVector3D(0, 1, 0);
为什么要通过此变换乘以向上矢量?我可以理解乘以距离,以便相机位置被转换,旋转上轴发送到lookat函数将导致我怀疑的怪异。
通常,使用相机矩阵进行变换并使用lookat进行变换有点奇怪。如果您已经有一个具有正确旋转的相机矩阵,您可以将该矩阵转换为所需的距离,表示为适当长度的Z向量,可能是QVector3D(0, 0, mDistance)
,然后将视图矩阵设置为相机矩阵:
vMatrix = cameraTransformation.inverted();