qt - 我怎样才能找到这些在我的场景中扭曲对象的 OpenGL 调用?

标签 qt opengl-es qml openscenegraph

我正在混合使用 OpenGL 的两个库:Qt 和 OpenSceneGraph。我的目标是 OpenGL ES 2,所以一切都是通过着色器和 ES 2 兼容调用完成的。

通过尝试将 OSG 绘制到 QDeclarativeItem 上,我专门将 OSG 与 QtDeclarative 一起使用。我按照 Qt 文档中建议的方式执行此操作:在 beginNativePainting()/endNativePainting() 之间包装所有 OpenGL 调用。

这工作正常,直到我在我的 OpenSceneGraph 场景中使用纹理。当我这样做时,我的 QML 窗口会因为没有更好的词而“困惑”。为了使其尽可能简单,我的 OSG 场景由一个应用了纹理的平面组成。我使用基本的 OpenGL 调用重新创建了场景,并且不再出现问题。这里的问题总结为一堆图片:

  • QtDeclarative 引擎使用 OpenGL 来绘制东西。我设置了一个简单的 QML 页面:

  • enter image description here
  • 我直接使用 OpenGL 创建了一个简单的场景。这是一架飞机,上面涂有纹理。

  • enter image description here
  • 现在我尝试在 OSG 中设置相同的场景...相同的着色器等。

  • enter image description here

    您可以看到最后一个屏幕截图发生了一些奇怪的事情。不用担心原始 OpenGL 场景是透明的黑色背景,这只是 OSG 使用黑色透明色。问题是使用 QML(矩形)设置的其他项目搞砸了。

    编辑 :为了澄清会发生什么:我用 QML 绘制的矩形都被拉伸(stretch)到屏幕的右边缘。我还注意到,如果我在 QML 中的 OpenSceneGraph 项目之后绘制矩形,它们不会出现(我之前没有注意到这一点)。我在以下屏幕截图中的 OSG 项目之后绘制了紫色黑色矩形......请注意它消失了。可能会发生更多奇怪的事情,但这是我观察到的所有玩矩形的东西。

    之前
    enter image description here

    之后
    enter image description here

    我对 OpenGL 还很陌生,所以我不知道什么样的调用/状态设置会导致这样的事情发生。 我认为 OpenSceneGraph 会进行一些 OpenGL 状态更改,这会扰乱 Qt 的绘图引擎。我也知道这只发生在 OSG 使用纹理时……如果我不在我的 OSG 场景中应用纹理,这不会发生。 这就是我卡住的地方。

    此外,我尝试使用 BuGLe 来获取在 OSG 中启用和不启用纹理的 OpenGL 调用跟踪,以查看是否可以找出有问题的状态更改。我发现了一些差异,甚至是 OSG 在两者之间更改的一些全局状态(例如 glPixelStorei()),但是重置我发现的更改没有任何区别。如果我知道要寻找什么,那将有很大帮助。如果有人感到疯狂,我也有堆栈跟踪:
  • 带纹理的 OSG:http://pastie.org/4223182 (osg 纹理的东西是第 637~650 行)
  • 没有纹理的 OSG:http://pastie.org/4223197

  • 编辑 2:
    这是一个可能有用的差异。在相关行明显之前,您需要向下滚动。
    http://www.mergely.com/nUEePufa/

    编辑 3:
    哇!好的,那个差异帮助了我很多。 OSG 启用 VertexAttribArray 3 但不会禁用它。在 OSG 渲染其帧之后调用 glDisableVertexAttribArray(3) 似乎部分解决了问题;不再有 QML 矩形的拉伸(stretch)。 但是,在 OSG 项目之后绘制的矩形仍然不显示 .

    最佳答案

    在对跟踪日志着迷之后,我想我发现了两个需要重置的 OpenGL 东西,然后才能将控制权传回 Qt 以导致上述问题消失。我在编辑中提到了一个......我将在这个答案中总结两者。

    矩形/QML 项目失真

    QPainter 直接将顶点属性 3、4 和 5 用于看起来与这些矩形的几何形状相关的东西。这可以在跟踪中看到:

    [INFO] trace.call: glVertexAttrib3fv(3, 0x2d94a14 -> { 0.00195312, 0, 0 })
    [INFO] trace.call: glVertexAttrib3fv(4, 0x2d94a20 -> { 0, -0.00333333, 0 })
    [INFO] trace.call: glVertexAttrib3fv(5, 0x2d94a2c -> { 0.2, 0.4, 1 })
    

    禁用相应的顶点属性数组修复了可拉伸(stretch)矩形问题:
     glDisableVertexAttribArray(3);
     glDisableVertexAttribArray(4);
     glDisableVertexAttribArray(5);
    

    在 OSG 项目之后绘制的项目不呈现

    回想起来,这很容易,与纹理没有任何关系。不过,在尝试将纹理添加到我的场景之前,我没有注意到这一点,所以混合这两个问题是我的错。我还搞砸了我发布的痕迹和差异;在我发现它后,我从未更新它们以解决订购问题(对不起!)

    无论如何,QPainter 希望关闭深度测试。当您调用 beginNativePainting() 时,Qt 将关闭深度测试,并且当它开始绘制其项目时……但您应该在交回控制权时将其关闭:
  • QPainter 绘制东西(DEPTH_TEST = 关闭)
  • OSG 绘制东西 (DEPTH_TEST = on)
  • QPainter 绘制更多内容 [期望 DEPTH_TEST = off]

  • 正确的跟踪日志显示我没有这样做......所以修复是
    glDisable(GL_DEPTH_TEST)
    

    关于qt - 我怎样才能找到这些在我的场景中扭曲对象的 OpenGL 调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11388039/

    相关文章:

    ios - iPhone 6s/RoboVM (?) GLTexImage2D 渲染问题

    c++ - QML - Q_INVOKABLE 函数

    javascript - 从 QML 中的 ListModel 访问 Javascript 数组元素

    c++ - Qt:优化绘画事件

    c++ - 无法在 QML ListView 中调用 Qt C++ 方法

    iphone - iOS OpenGL ES 2.0 球体上的广告牌对象并随球体旋转

    javascript - 使用 qml 添加一个有条件的类

    c++ - 如何知道小部件是否只接受数字字符

    cocoa - Cocoa 上的 Qt 或 wxWidgets?

    android - 从位图转移到 OpenGL