C++ OpenGL为相同的参数重新绘制不同的渲染结果

C++ OpenGL为相同的参数重新绘制不同的渲染结果,c++,qt,opengl,C++,Qt,Opengl,我有一个奇怪的问题,我猜是qt引起的。 我正在使用qt OpenGL小部件和重画例程,MouseMove事件如下所示: void RenderGraphFrame::redraw() { GLdouble objX, objY, objZ; GLdouble ModelViewMatrixvector[16], ProjectionViewMatrixVector[16]; GLint ViewportVector[4]; glGetIntegerv (GL_V

我有一个奇怪的问题,我猜是qt引起的。 我正在使用qt OpenGL小部件和重画例程,MouseMove事件如下所示:

void RenderGraphFrame::redraw()
{
    GLdouble objX, objY, objZ;
    GLdouble ModelViewMatrixvector[16], ProjectionViewMatrixVector[16];
    GLint ViewportVector[4];

    glGetIntegerv (GL_VIEWPORT, ViewportVector);
    glGetDoublev (GL_MODELVIEW_MATRIX, ModelViewMatrixvector);
    glGetDoublev (GL_PROJECTION_MATRIX, ProjectionViewMatrixVector);

    gluUnProject(mousepositionX, mousepositionY, 0,
                 ModelViewMatrixvector,
                 ProjectionViewMatrixVector,
                 ViewportVector,
                 &objX,  &objY, &objZ);

    qDebug() << "objX: " << objX << " objY: " << objY << " objZ: " << objZ;

    qglColor(Qt::red);
    glBegin(GL_TRIANGLES);
        glNormal3f(0,-1,0.707);
        glVertex3f(objX-1,objY-1,0);
        glVertex3f(objX+1,objY-1,0);
        glVertex3f(objX,objY,1.2);
    glEnd();
}

void RenderGraphFrame::mouseMoveEvent (QMouseEvent *event)
{
    mousepositionX = event->x();
    mousepositionY = event->y();
    redraw();
    return;
}
void RenderGraphFrame::redraw()
{
GLdouble-objX,objY,objZ;
GLdouble ModelViewMatrixvector[16],ProjectionViewMatrixVector[16];
闪烁视口向量[4];
glGetIntegerv(GL_视口,ViewportVector);
glGetDoublev(GL_模型视图_矩阵、模型视图矩阵向量);
glGetDoublev(GL_投影矩阵,ProjectionViewMatrixVector);
gluUnProject(鼠标位置X,鼠标位置,0,
ModelViewMatrixvector,
投影视图矩阵向量,
视口向量,
&objX、objY和objZ);

qDebug()您的错误是假设OpenGL上下文在每次函数调用时处于相同的状态。但是,Qt在呈现自己的内容时会修改许多状态。这就是为什么即使每次在代码中执行完全相同的GL调用,也会得到不同的结果

引用Qt文档:

[…]绘制引擎将更改当前OpenGL上下文的状态以反映其需要。应用程序不应依赖将OpenGL状态重置为其原始状态,尤其是当前着色器程序、OpenGL视口、纹理单元和绘图模式


因此,很多状态,如绑定纹理、多边形模式、混合、深度测试等,基本上在每次调用
redraw()
时都处于随机状态。您必须在
redraw()开始时重置所有状态
以确保每次都得到相同的结果。

我通过在事件侦听器中将
redraw()
的方法调用更改为
updateGL()
。这可能与qt自身的行为有关,正如Lukas Boersma在其回答中所述

现在按计划运行的版本具有此方法的实现:

void RenderGraphFrame::mouseMoveEvent (QMouseEvent *event)
{
    mousepositionX = event->x();
    mousepositionY = event->y();
    updateGL();
    return;
}
注:
updateGL()
是一个外部函数!

+1到目前为止,因为我觉得ti是合乎逻辑的。但在我接受这一点之前,我想看看如何实现重置的解决方案或解释。在您的特定场景中,我会查看视口和矩阵值,看看它们是否处于正常状态。您当前正在使用它们进行未投影打开,但Qt可能将它们设置为不正确的值,您可能必须重置它们。您可以使用来查看Qt到底在做什么以及需要重置的状态。但我正在记录gluUnProject返回的值,它依赖于矩阵。因此,它们的输出在正确行为和不正确行为之间应该有所不同,不是吗?如cu所示目前,在这两种情况下,gluUnProject的输出都是相同的。但我会查看一下。我解决了这个问题:我必须使用
updateGL();
而不是调用redraw方法。我会提供自己的答案。但是如果你能更好地解释它,我会(编辑到你的答案中),我仍然倾向于接受你的答案。不,继续写你自己的答案,好像我当时错了。