我正在混合两个使用OpenGL的库:Qt和OpenSceneGraph . 我的目标是OpenGL ES 2,所以一切都是通过着色器和ES 2兼容调用完成的 .
我通过尝试将OSG绘制到QDeclarativeItem上来专门使用OSG和QtDeclarative . 我按照Qt文档中建议的方式执行此操作:在beginNativePainting()/ endNativePainting()之间包装所有OpenGL调用 .
这工作正常,直到我在OpenSceneGraph场景中使用纹理 . 当我这样做时,由于缺少更好的单词,我的QML窗口变得“混乱” . 为了使其尽可能简单,我的OSG场景包含一个应用了纹理的平面 . 我使用基本的OpenGL调用重新创建了场景,不再出现问题 . 这里的问题总结为一堆图片:
- QtDeclarative引擎使用OpenGL绘制内容 . 我设置了一个简单的QML页面:
- 我直接使用OpenGL创建一个简单的场景 . 它是一个涂有纹理的平面 .
- 现在我尝试在OSG中设置相同的场景......相同的着色器等 .
你可以看到最后一个截图发生了奇怪的事情 . 不要担心原始OpenGL场景透明的黑色背景,这只是使用黑色清晰颜色的OSG . 问题是用QML(矩形)设置的其他项目搞砸了 .
Edit :澄清会发生什么:我用QML绘制的矩形都伸展到屏幕的右边缘 . 我还注意到如果我在QML中的OpenSceneGraph项之后绘制矩形,他们之前不会注意到这一点) . 我在以下屏幕截图中的OSG项目之后绘制紫色黑色矩形...请注意它会消失 . 可能会发生更多奇怪的事情,但这是我观察到的所有矩形播放 .
Before
After
我知道什么样的通话/状态设置会导致这样的事情发生 . 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())两者之间,但重置我发现的变化没有区别 . 如果我知道要寻找什么,这将有很大帮助 . 如果有人感到疯狂,我也有堆栈痕迹:
-
OSG与纹理:http://pastie.org/4223182(osg纹理的东西是637~650行)
-
OSG没有纹理:http://pastie.org/4223197
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 回答
在仔细观察了跟踪日志之后,我想我发现了两个需要重置的OpenGL事情,然后再将控制权交还给Qt,导致上述问题消失 . 我在编辑中提到了一个......我将在这个答案中总结一下 .
Rectangle/QML Item distortion
QPainter直接使用顶点属性3,4和5来表示与这些矩形的几何相关的东西 . 这可以在跟踪中看到:
禁用相应的顶点属性数组可修复弹性矩形问题:
Items drawn after the OSG Item don't render
回想起来,这很简单,与纹理没有任何关系 . 在尝试为我的场景添加纹理之前我没有注意到这一点,所以混合这两个问题是我的错 . 我也搞砸了我发布的痕迹和差异;我发现它后,我从未更新它们以解释订购问题(对不起!)
无论如何,QPainter希望关闭深度测试 . 当你调用beginNativePainting()时,Qt会关闭深度测试,当它开始绘制它的项目时......但是当你把控制权交还给你时,你应该把它关掉:
QPainter涂料(DEPTH_TEST =关)
OSG绘制内容(DEPTH_TEST = on)
QPainter绘制更多东西[预计DEPTH_TEST = off]
正确的跟踪日志显示我没有这样做...所以修复是
也许你只需要重新启用GL_TEXTURE_2D?我在您的示例中注意到OSG启用的纹理,并随后禁用GL_TEXTURE_2D . 因此,你的两个案例(纹理与没有)之间的差异是使用纹理的情况完成纹理禁用,而没有纹理的那个使GL_TEXTURE_2D处于初始状态 .
如果Qt需要/期望启用纹理来绘制四边形,则可能不会显示任何内容 .