作为一个爱好,我正在尝试使用OpenGL并使用Qt + OpenGL编写自己的愚蠢引擎。最后的成功是构建实体系统框架,它可以使用附加的物理引擎(BulletPhysics)渲染具有阴影的场景(通过渲染到纹理到RenderBuffer)。
之后我更新到Qt 5.2并完全由Qml表达(之前没有尝试使用它)。我对2d qml图形进行了一些实验,并决定使用qml作为用户界面,但拒绝2d项目并返回3d。我创建了新的qml项目,尝试在qml下呈现一些内容,如Scene Graph - OpenGL Under QML示例中所示。之后,我将旧代码从3d项目移动到新项目,进行了一些小的重构(不应该影响任何东西)。
在这一刻我厌倦了一些奇怪的虫子。似乎第一帧是根据需要渲染的,但之后就出现了问题。
这是一个更少或更常规的框架(在任何移动之前)
在左上角我是输出深度缓冲区(阴影贴图)。在右上角我用qml制作一些自定义滚动条。我正在使用这个滚轮更改阴影贴图旋转和移动相机。当滚动条居中时,没有任何动作。当我改变某些东西时,场景变得难看,我不知道为什么。
这是一些阴影贴图旋转后的帧
我看到阴影贴图深度缓冲区未更改(为什么?o_0)并且场景中的阴影出错。但是,在将旧代码重构为qml项目后,不仅阴影失败了。当我移动相机时,错误变得更加奇怪。
这是向下移动相机后的帧(-Z)
使用以下命令在qml下呈现场景:
connect(window, &QQuickWindow::beforeRendering, this, &MyApp::renderScene, Qt::DirectConnection);
在renderScene中我:
做一些OpenGL传送带设置(以防止Qml Scene Graph的更改,可能会过量);
glViewport(0, 0, window->width(), window->height());
glClearColor(0, 0, 0, 1);
glClearDepth(1);
glDepthRange(0,1);
glDepthFunc(GL_LEQUAL);
调用BulletPhysics计算物理(在测试场景中 - 两个下落的立方体)
我很想去捕捉正在发生的事情。 glGetError没有显示任何内容。
通过XY轴再次移动相机。男人的角形轮廓仍然可见,并产生奇怪的效果
更多屏幕截图:
旧项目(不含qml)
旧项目(大截图)
在新项目中,窗口调整大小也被破坏
它有什么用?
环境:Qt Creator 3.0.0,Qt 5.2.0,Linux(Kubuntu 13.10)64位,HD 7750
OpenGL:在旧项目中我设置了3.3,新项目使用4.3(据我记得)
P.S。深度贴图失真,因为我在着色器中使用了一些额外的失真来改善场景中心的阴影。
答案 0 :(得分:4)
在一天没有回答和许多前几天之后,我得到了灵感!
我怀疑深度缓冲区出了问题,并尝试输出调试用于渲染到用于渲染到全屏四边形的纹理ID。我尝试关闭渲染到纹理缓冲区交换等等。但我甚至不认为真正的问题出在Qml那边。
glDepthMask(GL_TRUE); // 42!
这一行就像42
- 回答所有问题。似乎Qml在第一个渲染帧之前调用glDepthMask(GL_FALSE);
(但是在发出&QQuickWindow::beforeRendering
信号之后)。这个调用的结果是只有第一个我的帧真正渲染了写入深度缓冲区。为什么我认为glDepthMask(GL_FALSE);
只被调用一次?因为插入“42”后FPS明显减少,并且在我用于渲染场景的插槽末尾插入glDepthMask(GL_FALSE);
后增加了。
现在我可以自由旋转“太阳”(阴影)并在没有任何视觉错误的情况下移动相机。
yippee的!