2015-07-13 55 views
1

我有一个奇怪的问题,我猜是由qt引起的。 我使用Qt的OpenGL窗口小部件和我的重绘常规和MouseMove事件是这样的:OpenGL重绘不同渲染结果的相同参数

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; 
} 

当我在Widget上移动鼠标,我得到的输出的全码流通过qDebug()所以它是确保Even触发器和redraw()得到执行。

为了测试,我想要一个4个三角形的方形区域被渲染,其中1个三角形跟随着光标。

但是只有3种形状,第四种缺失......那至少是我在想什么。虽然当我正在摸索时,我想象出当我在窗外跳动时,当我按下alt时,关键redraw()方法被再次调用,其输出与最后一次鼠标移动完全相同,但现在第四个形状获得呈现(不是我想要的位置,但这可能只是我的3d逻辑中的错误)

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

编辑:

-I注意到,刚刚按下alt - 键,以引起期望的呈现是难以重现(Tab键切换到其他applicantions同时点击不同而alt + tab菜单中的某些时间上的工作)。但什么是可重现的是: 当我从应用程序中退出,然后再次选项卡时,重画就像它应该那样工作。但不是从mousemove事件中调用时。

-I删除了不是问题的静态形状,所以代码更容易阅读。

回答

2

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

报价Qt文档:

[...]当前的OpenGL上下文的状态将被绘图引擎进行修改,以反映其需求。应用程序不应依赖将OpenGL状态重置为其原始状态,特别是当前着色器程序,OpenGL视口,纹理单元和绘图模式。

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

+0

+1迄今为止,因为ti听起来符合我的逻辑。但在我接受这个之前,我希望看到一个解决方案或解释如何实施重置。 – dhein

+0

在您的特定场景中,我会查看视口和矩阵值,看看它们是否处于理智状态。您目前正在将它们用于未投影,但Qt可能已将它们设置为不正确的值,您可能必须重置它们。您可以使用[apitrace](http://apitrace.github.io/)查看Qt究竟在做什么以及需要重置哪些状态。 –

+0

但我记录了gluUnProject返回的值,它依赖于矩阵。所以他们的输出在正确和不正确的行为之间应该是不同的,不是吗?目前在这两种情况下gluUnProject输出是相同的。但我会看。 – dhein

1

我通过在事件监听器中更改redraw()updateGL()的方法调用来解决此问题。这可能是对自己的qt行为的影响,正如Lukas Boersma在他的回答中所描述的那样。

现在按预期运行的版本有这种实施方法:

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

注: updateGL()是外部函数!

相关问题