我有一个奇怪的问题,我猜是由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事件中调用的。
- 我删除了不是问题的静态形状,因此代码更容易阅读。
答案 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()
是一个外部函数!