简体   繁体   English

在Qml场景下使用OpenGL渲染时出现奇怪的错误

[英]Strange bugs while rendering with OpenGL under Qml Scene

As a hobby, I am experimenting with OpenGL and write my own silly engine with Qt+OpenGL. 作为一个爱好,我正在尝试使用OpenGL并使用Qt + OpenGL编写自己的愚蠢引擎。 Last success was building Entity System Framework which could render scene with shadows (by render-to-texture to RenderBuffer) with attached physics engine (BulletPhysics). 最后的成功是建立实体系统框架,它可以使用附加的物理引擎(BulletPhysics)渲染具有阴影的场景(通过渲染到纹理到RenderBuffer)。

After that I updated to Qt 5.2 and was totally expressed by Qml (not trying to use it before). 之后我更新到Qt 5.2并完全由Qml表达(之前没有尝试使用它)。 I'm experimented about 2d qml graphics a bit, and decide to use qml for user interface, but reject 2d project and return to 3d. 我对2d qml图形进行了一些实验,并决定使用qml作为用户界面,但拒绝2d项目并返回3d。 I created new qml project, try to render some stuff under qml as in Scene Graph - OpenGL Under QML example. 我创建了新的qml项目,尝试在qml下渲染一些东西,如在Scene Graph - OpenGL Under QML示例中。 After that I moved my old code from 3d project to new project, with some small refactoring (which should not affect anything). 之后我将旧代码从3d项目移动到新项目,进行了一些小的重构(不应该影响任何东西)。

In this moment I get tired with some strange bug. 在这一刻,我厌倦了一些奇怪的错误。 It seems like first frame is rendered as needed, but after that something goes wrong. 似乎第一帧是根据需要渲染的,但在那之后出现问题。

场景视图 This is a some less or more normally frame (before any moving) 这是一个更少或更正常的框架(在任何移动之前)

In the left top corner I am output depth buffer (shadow map). 在左上角我是输出深度缓冲区(阴影贴图)。 In the right top corner I make some custom scrollers with qml. 在右上角我用qml制作一些自定义滚动条。 I am using this scrollers for changing shadow map rotating and moving camera. 我正在使用这个滚轮更改阴影贴图旋转和移动相机。 When scrollers are centered, nothing moves. 当滚动条居中时,没有任何动作。 When I change something, scene became ugly and I can't wonder why. 当我改变一些东西时,场景变得丑陋,我不知道为什么。

一些阴影贴图旋转后的场景视图 This is the frame after some shadow map rotating 这是一些阴影贴图旋转后的帧

I see that shadow map depth buffer not changed (why? o_0) and shadow in scene goes wrong. 我看到阴影贴图深度缓冲没有改变(为什么?o_0)和场景中的阴影出错了。 But not only shadow is failed after refactoring my old code to qml project. 但是,在将旧代码重构为qml项目后,不仅阴影失败了。 When I move camera, bugs became more strange. 当我移动相机时,错误变得更加奇怪。

移动相机后的场景(-Z) This is the frame after moving camera down (-Z) 这是移动相机后的框架(-Z)

Scene is rendered under qml by using: 使用以下命令在qml下呈现场景:

connect(window, &QQuickWindow::beforeRendering, this, &MyApp::renderScene, Qt::DirectConnection);

In renderScene I: 在renderScene中我:

  • Do some OpenGL conveyor setup (to prevent changes by Qml Scene Graph, may be excess); 做一些OpenGL传送带设置(以防止Qml Scene Graph的更改,可能是多余的);

     glViewport(0, 0, window->width(), window->height()); glClearColor(0, 0, 0, 1); glClearDepth(1); glDepthRange(0,1); glDepthFunc(GL_LEQUAL); 
  • Call BulletPhysics to calculate physics (in test scene - two falling cubes) 调用BulletPhysics来计算物理(在测试场景中 - 两个下降的立方体)

  • Render shadow map (depth-only) to RenderBuffer (2048x2048 texture, GL_DEPTH_COMPONENT24) 渲染阴影贴图(仅限深度)到RenderBuffer(2048x2048纹理,GL_DEPTH_COMPONENT24)
  • Render scene to RenderBuffer (two GL_RGBA8 textures for color and normals and one GL_DEPTH_COMPONENT24 for depth) 将场景渲染为RenderBuffer(两个GL_RGBA8纹理用于颜色和法线,一个GL_DEPTH_COMPONENT24用于深度)
  • Render two 2d quads - fullscreen (scene render with all textures from renderbuffer to render with shadows) and side screen (top left corner's texture from depthbuffer) 渲染两个2d四边形 - 全屏(场景渲染,所有纹理从渲染缓冲区渲染到阴影渲染)和侧面屏幕(左上角的纹理来自深度缓冲区)

I am tired to hunt what is going on. 我很想去捕捉正在发生的事情。 glGetError shows nothing. glGetError没有显示任何内容。

移动相机的场景 Moved camera one more time by XY-axes. 通过XY轴再次移动相机。 Man's horn silhouette is still visible and make strange effect 男人的角形轮廓仍然可见,并产生奇怪的效果

Some more screenshots: 更多截图:

老项目 Old project (without qml) 旧项目(没有qml)

老项目 - 大截图 Old project (big screenshot) 旧项目(大截图)

破碎调整大小 On new project, window resizing is broken too 在新项目中,窗口大小调整也被打破

What can it be? 它能是什么?

Environment: Qt Creator 3.0.0, Qt 5.2.0, Linux (Kubuntu 13.10) 64-bit, HD 7750 环境:Qt Creator 3.0.0,Qt 5.2.0,Linux(Kubuntu 13.10)64位,HD 7750

OpenGL: in old project I set up 3.3, new project use 4.3 (as far as I remember) OpenGL:在旧项目中我设置了3.3,新项目使用4.3(据我记得)

PS Depth map is distorted because I use some additional distortion in shaders to improve shadows in scene center. PS深度贴图失真,因为我在着色器中使用了一些额外的失真来改善场景中心的阴影。

An inspiration came upon me after a day without an answer and many previous days! 经过一天没有答案和许多前几天,我得到了灵感!

I have suspected that something was wrong with the depth buffer and tried to output to debug texture ids that used to render to and used to render to fullscreen quad. 我怀疑深度缓冲区出了问题,并试图输出调试用于渲染和用于渲染到全屏四边形的纹理ID。 I tried switch off render-to-texture buffer swapping and much more. 我尝试关闭渲染到纹理缓冲区交换等等。 But I can't even think that real problem is at Qml's side. 但我甚至不认为真正的问题出在Qml方面。

glDepthMask(GL_TRUE); glDepthMask(GL_TRUE); // 42! // 42!

One this line is like 42 - answer to all questions. 这一行就像42 - 回答所有问题。 It's seems that Qml is calling glDepthMask(GL_FALSE); 似乎Qml正在调用glDepthMask(GL_FALSE); before first render frame (but after emit &QQuickWindow::beforeRendering signal). 在第一次渲染帧之前(但在发射&QQuickWindow::beforeRendering信号之后)。 Result of this call was that only first my frame really rendered with writing to depth buffer. 这个调用的结果是只有第一个我的帧真正渲染了写入深度缓冲区。 Why I think that glDepthMask(GL_FALSE); 为什么我认为glDepthMask(GL_FALSE); is called only once? 只被召唤一次? Because FPS is noticeably decreased after I inserted my "42", and increased after I inserted glDepthMask(GL_FALSE); 因为我插入“42”后FPS显着下降,并且在插入glDepthMask(GL_FALSE);后增加glDepthMask(GL_FALSE); in the end of slot that used to render my scene. 在用于渲染场景的插槽末尾。

Now I can freely rotate "Sun" (shadow) and move camera without any visual bugs. 现在我可以自由旋转“太阳”(阴影)并移动相机,没有任何视觉错误。

Yippee! yippee的!

结果是新项目

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM