我怎样才能追捕这些在我的场景中扭曲对象的OpenGL调用?

我混合使用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(矩形)设置的其他项目会搞砸。

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

    之前 在这里输入图像描述

    在这里输入图像描述

    我对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矩形拉伸。 但是,在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 })
    

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

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

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

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

    无论如何,QPainter希望关闭深度测试。 当你调用beginNativePainting()时,Qt会关闭深度测试,并且当它开始绘制它的项目时......但是当你将控制权交还给控制系统时,你需要关闭它:

  • QPainter涂料(DEPTH_TEST =关闭)
  • OSG吸取东西(DEPTH_TEST = on)
  • QPainter绘制更多东西[期望DEPTH_TEST =关闭]
  • 正确的跟踪日志显示我没有这样做......所以解决方法是

    glDisable(GL_DEPTH_TEST)
    

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

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

    链接地址: http://www.djcxy.com/p/10957.html

    上一篇: How can I hunt down these OpenGL calls that are distorting objects in my scene?

    下一篇: how to use colors to visually accentuate the function the cursor is in?