首页 文章

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

提问于
浏览
7

我正在混合两个使用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(矩形)设置的其他项目搞砸了 .

Edit :澄清会发生什么:我用QML绘制的矩形都伸展到屏幕的右边缘 . 我还注意到如果我在QML中的OpenSceneGraph项之后绘制矩形,他们之前不会注意到这一点) . 我在以下屏幕截图中的OSG项目之后绘制紫色黑色矩形...请注意它会消失 . 可能会发生更多奇怪的事情,但这是我观察到的所有矩形播放 .

Before
enter image description here

After
enter image description here

我知道什么样的通话/状态设置会导致这样的事情发生 . I think that OpenSceneGraph makes some OpenGL state change that's messing up Qt's paint engine. I also know that this only occurs when OSG uses textures... if I don't apply textures in my OSG scene, this doesn't happen. 这就是我被困住的地方 .

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

Edit 2: 这里's a diff that might be helpful. You' ll需要在相关行显而易见之前向下滚动 . http://www.mergely.com/nUEePufa/

Edit 3: 哇!好吧,那差异对我有所帮助 . OSG启用了VertexAttribArray 3但不再延伸QML矩形 . However, rectangles drawn after the OSG item still don't show up .

2 回答

  • 2

    在仔细观察了跟踪日志之后,我想我发现了两个需要重置的OpenGL事情,然后再将控制权交还给Qt,导致上述问题消失 . 我在编辑中提到了一个......我将在这个答案中总结一下 .

    Rectangle/QML Item distortion

    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);
    

    Items drawn after the OSG Item don't render

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

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

    • QPainter涂料(DEPTH_TEST =关)

    • OSG绘制内容(DEPTH_TEST = on)

    • QPainter绘制更多东西[预计DEPTH_TEST = off]

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

    glDisable(GL_DEPTH_TEST)
    
  • 1

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

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

相关问题