C++ 在Qml场景下使用OpenGL渲染时出现奇怪的错误
作为一种爱好,我正在试验OpenGL,并用Qt+OpenGL编写自己的愚蠢引擎。最后一个成功是构建实体系统框架,该框架可以使用附加的物理引擎(BulletPhysics)渲染带有阴影的场景(通过渲染到纹理到渲染缓冲) 在此之后,我更新到Qt5.2,并完全由Qml表示(以前没有尝试使用它)。我对2d qml图形进行了一些实验,决定将qml用于用户界面,但拒绝2d项目并返回3d。我创建了新的qml项目,尝试在qml下呈现一些东西,如示例所示。在那之后,我将我的旧代码从3d项目转移到了新项目,进行了一些小的重构(这应该不会影响任何事情) 在这一刻,我对一些奇怪的虫子感到厌倦。看起来第一帧是根据需要渲染的,但之后出现了一些问题 这是一个较正常的帧(在任何移动之前) 在左上角,我是输出深度缓冲区(阴影贴图)。在右上角,我用qml定制了一些滚动条。我用这个滚动条来改变阴影贴图旋转和移动相机。当滚动条居中时,任何东西都不会移动。当我改变一些东西时,场景变得丑陋,我不知道为什么 这是一些阴影贴图旋转后的帧 我看到阴影贴图深度缓冲区并没有改变(为什么?o_0),场景中的阴影出现了错误。但将我的旧代码重构到qml项目后,不仅shadow失败了。当我移动相机时,虫子变得更奇怪了 这是向下移动摄影机(-Z)后的帧 场景在qml下渲染,方法是使用:C++ 在Qml场景下使用OpenGL渲染时出现奇怪的错误,c++,qt,opengl,qml,C++,Qt,Opengl,Qml,作为一种爱好,我正在试验OpenGL,并用Qt+OpenGL编写自己的愚蠢引擎。最后一个成功是构建实体系统框架,该框架可以使用附加的物理引擎(BulletPhysics)渲染带有阴影的场景(通过渲染到纹理到渲染缓冲) 在此之后,我更新到Qt5.2,并完全由Qml表示(以前没有尝试使用它)。我对2d qml图形进行了一些实验,决定将qml用于用户界面,但拒绝2d项目并返回3d。我创建了新的qml项目,尝试在qml下呈现一些东西,如示例所示。在那之后,我将我的旧代码从3d项目转移到了新项目,进行了一
connect(window, &QQuickWindow::beforeRendering, this, &MyApp::renderScene, Qt::DirectConnection);
在渲染场景I中:
- 进行一些OpenGL传送带设置(防止Qml场景图的更改,可能会过多)
- 调用BulletPhysics计算物理(在测试场景中-两个下落的立方体)
- 渲染阴影贴图(仅深度)到渲染缓冲区(2048x2048纹理,GL_深度_组件24)
- 渲染场景到RenderBuffer(两个GL_RGBA8纹理用于颜色和法线,一个GL_DEPTH_组件24用于深度)
- 渲染两个2d四边形-全屏(使用从renderbuffer到使用阴影渲染的所有纹理进行场景渲染)和侧屏(从depthbuffer到左上角的纹理)
另外,深度贴图是扭曲的,因为我在着色器中使用了一些额外的扭曲来改善场景中心的阴影。在一天没有答案之后,以及之前的许多天,我得到了灵感 我怀疑深度缓冲区出了问题,并尝试输出调试用于渲染到和用于渲染到全屏的纹理ID。我尝试关闭渲染到纹理缓冲区交换等功能。但我甚至认为真正的问题不在Qml这边 glDepthMask(GL_TRUE);//42! 这一行就像是
42
——回答所有问题。似乎Qml正在调用glDepthMask(GL\u FALSE)代码>在第一个渲染帧之前(但在发射&QQuickWindow::preferrendering
信号之后)。这个调用的结果是,只有第一个帧真正使用写入深度缓冲区进行渲染。为什么我认为glDepthMask(GL\u FALSE)代码>只调用一次?因为在我插入“42”后FPS明显降低,在我插入glDepthMask(GL_FALSE)后FPS增加代码>位于用于渲染我的场景的插槽的末尾
现在我可以自由旋转“太阳”(阴影)并移动相机,而不会出现任何视觉缺陷
哎呀
这就是我的答案:D我使用glEnable(GL_DEPTH_TEST)没有结果,但使用glDepthMask(GL_TRUE)在QML中实现了这一点。当我与该错误斗争时,我尝试了glEnable和glDisable在我使用的所有状态下-深度测试、混合、剔除面。。。但没有任何实际结果。glDepthMask太不明显了,以至于无法被记住和怀疑……这是一个极好的答案——尽管遗憾的是,我不知道为什么会这样(这让我对未来充满了恐惧)我花了很长时间试图让OpenGL在肖恩·哈默(Sean Harmer)的博客之后在QML下工作——虽然它看起来不太对劲,并且认为它可能与深度缓冲区有关,但如果没有您的帮助,我是不会发现这一点的。Txs.StuReeks,我在(之前)QML层下渲染我的场景。当QML第一次渲染时,它会关闭深度缓冲区更改。来自太阳位置的阴影缓冲区在第一帧后停止刷新,这将冻结阴影。此外,在移动相机或调整窗口大小时,深度缓冲区没有重置。和阴影故障。有时,一些对象或部分不渲染,因为深度缓冲区阻止它们这样做。
glViewport(0, 0, window->width(), window->height());
glClearColor(0, 0, 0, 1);
glClearDepth(1);
glDepthRange(0,1);
glDepthFunc(GL_LEQUAL);