我怎样才能找到扭曲场景中对象的OpenGL调用?

时间:2012-07-09 01:07:10

标签: 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绘制的矩形都伸展到屏幕的右边缘。我还注意到,如果我在QML中的 OpenSceneGraph项目之后绘制矩形,它们就不会出现(之前我没有注意到)。我在以下屏幕截图中的OSG项目之后画出紫黑色矩形...请注意它会消失。可能会发生更多奇怪的事情,但这是我观察到的用矩形进行的所有事情。

之前 enter image description here

enter image description here

我是OpenGL的新手,所以我不知道什么样的调用/状态设置会导致这样的事情发生。 我认为OpenSceneGraph会使一些OpenGL状态发生变化,这会搞砸Qt的绘图引擎。我也知道这只会在OSG使用纹理时发生...如果我在OSG场景中不应用纹理,则不会发生这种情况。这就是我被困住的地方。

此外,我尝试使用BuGLe在OSG中启用和不启用纹理的OpenGL调用跟踪,以查看是否可以找出有问题的状态更改。我发现了一些差异,甚至一些全局状态OSG改变了(例如glPixelStorei())两者之间,但重置我发现的变化没有区别。如果我知道要寻找什么,这将有很大帮助。如果有人感到疯狂,我也有堆栈痕迹:

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

编辑3: 哇!好吧,那差异对我有所帮助。 OSG启用VertexAttribArray 3但不禁用它。在OSG渲染其帧之后调用glDisableVertexAttribArray(3)似乎可以部分解决问题;没有更多的QML矩形拉伸。 但是,在OSG项目之后绘制的矩形仍未显示

2 个答案:

答案 0 :(得分:2)

在仔细观察了跟踪日志之后,我想我发现了两个需要重置的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 })

禁用相应的顶点属性数组可修复弹性矩形问题:

 glDisableVertexAttribArray(3);
 glDisableVertexAttribArray(4);
 glDisableVertexAttribArray(5);

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

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

无论如何,QPainter希望关闭深度测试。当你调用beginNativePainting()时,Qt会关闭深度测试,当它开始绘制它的项目时......但是每当你把控制权交还给你时,你都会把它关掉:

  1. QPainter描绘东西(DEPTH_TEST =关闭)
  2. OSG绘制内容(DEPTH_TEST = on)
  3. QPainter绘制更多东西[预计DEPTH_TEST =关]
  4. 正确的跟踪日志显示我没有这样做......所以修复是

    glDisable(GL_DEPTH_TEST)
    

答案 1 :(得分:1)

也许你只需要重新启用GL_TEXTURE_2D?我在您的示例中注意到OSG启用的纹理,并随后禁用GL_TEXTURE_2D。因此,你的两个案例(纹理与没有)之间的区别在于,使用纹理的情况在禁用纹理的情况下完成,而没有纹理的情况则使GL_TEXTURE_2D处于初始状态。

如果Qt需要/期望启用纹理来绘制四边形,则可能无法显示任何内容。