OpenGL重绘相同参数的不同渲染结果

时间:2015-07-13 10:51:13

标签: c++ qt opengl

我有一个奇怪的问题,我猜是由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;
}

当我将鼠标移到窗口小部件上时,我会通过qDebug()获得整个输出流,因此确保偶数触发器和redraw()被执行。

为了进行测试,我希望渲染一个包含4个三角形的sqaure,其中1个跟随光标。

但是只有3种形状,第4种缺失......至少是我在想什么。虽然我是dbeugging,但是当我在窗外进行alt + tabbing时,我想到了,当我按下alt - 键时,redraw()方法再次被调用,输出完全相同最后一次鼠标移动,但现在第四个形状被渲染(不是在我想要的位置,但这可能只是我的3d逻辑中的错误)

怎么会这样? 有没有什么神秘的东西在小部件中做了什么导致这个?如果这不是我的错,那我能做什么,qt让我按照自己的意愿去做?

修改

- 我注意到只需按alt - 键即可进行所需的渲染很难重现(在alt + tab菜单上单击不同的工作时,可以选中其他应用程序)。但可重复的是: 当我退出应用程序然后再次选中时,重绘工作正常。但不是从mousemove事件中调用的。

- 我删除了不是问题的静态形状,因此代码更容易阅读。

2 个答案:

答案 0 :(得分:2)

你的错误是假设OpenGL上下文在每个函数调用时都处于相同的状态。但是,Qt在渲染自己的东西时会修改很多状态。这就是为什么即使每次在代码中执行完全相同的GL调用,也会得到不同的结果。

引用Qt文档:

  

[...]当前OpenGL上下文的状态将由paint引擎改变以反映其需求。应用程序不应该依赖于将OpenGL状态重置为其原始条件,尤其是当前着色器程序,OpenGL视口,纹理单元和绘图模式。

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

答案 1 :(得分:1)

我通过在事件监听器中将redraw()的方法调用更改为updateGL()来修复此行为。正如Lukas Boersma在他的回答中所描述的那样,这可能与自己的qt行为有关。

现在正在运行的版本具有此方法的实现:

void RenderGraphFrame::mouseMoveEvent (QMouseEvent *event)
{
    mousepositionX = event->x();
    mousepositionY = event->y();
    updateGL();
    return;
}

请注意: updateGL()是一个外部函数!