c++ - 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_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() 获得了整个输出流,因此可以肯定 Even 触发器和 redraw() 得到执行。

为了测试,我想要呈现一个由 4 个三角形组成的正方形,其中 1 个三角形跟随光标。

但是只有 3 个形状缺少第 4 个...至少我是这么想的。当我在调试时,我发现当我按 alt+tab 键跳出窗口时,当我按下 alt 键时,redraw() 方法再次被调用与上次鼠标移动的输出完全相同,但现在渲染了第 4 个形状(不在我想要的位置,但这可能只是我的 3d 逻辑中的错误)

怎么可能呢? qt 在导致此问题的小部件中做了什么神秘的事情吗?如果这不是我的错,我能做些什么让 qt 允许我按要求做?

编辑:

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

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

最佳答案

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

引用Qt文档:

[...] the state of the current OpenGL context will be altered by the paint engine to reflect its needs. Applications should not rely upon the OpenGL state being reset to its original conditions, particularly the current shader program, OpenGL viewport, texture units, and drawing modes.

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

关于c++ - OpenGL 重绘相同参数的不同渲染结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31381405/

相关文章:

c++ - 在Qt/C++中通过光标选择一个单词并获取它的位置

c++ - 如何在不使用委托(delegate)的情况下在 QML 中显示模型数据

c++ - ffmpeg转OpenGL纹理黑屏

c++ - 如果您始终将其存储在 shared_ptr 中,您的接口(interface)是否需要虚拟析构函数?

Qt4 QSslSocket 触发 HTTP 406 响应

macos - go + SDL + OpenGL + MacOS示例=在DrawArrays()之后我得到了INVALID_OPERATION

c++ - 偏航、俯仰和滚动到 glm::rotate

c++ - 在使用 gdb 检查核心转储时,有没有办法运行函数(如 std::string.size())?

c++:运行时链接共享对象与主机应用程序,符号表问题

c++ - 这个 std::cout 最终会打印垃圾或意外的东西吗?