C++ OpenGL为相同的参数重新绘制不同的渲染结果
我有一个奇怪的问题,我猜是qt引起的。 我正在使用qt OpenGL小部件和重画例程,MouseMove事件如下所示: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
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方法。我会提供自己的答案。但是如果你能更好地解释它,我会(编辑到你的答案中),我仍然倾向于接受你的答案。不,继续写你自己的答案,好像我当时错了。