2014-02-19 58 views
4

作为一种爱好,我正在尝试使用OpenGL并使用Qt + OpenGL编写自己的傻引擎。最后的成功是构建实体系统框架,该实体系统框架可以通过附加的物理引擎(BulletPhysics)渲染具有阴影的场景(通过渲染到纹理渲染到渲染缓冲区)。在Qml场景下使用OpenGL进行渲染时出现奇怪的错误

之后,我更新到Qt 5.2并完全由Qml表示(不尝试使用它之前)。我尝试了一下2d qml图形,并决定使用qml作为用户界面,但拒绝2d项目并返回到3d。我创建了新的qml项目,尝试在qml下渲染一些内容,如Scene Graph - OpenGL Under QML示例。之后,我将旧代码从3d项目移至新项目,并进行了一些小的重构(这不应该影响任何内容)。

在这一刻我厌倦了一些奇怪的错误。看起来第一帧是根据需要渲染的,但之后出现了一些问题。

Scene view 这是一些更少或更多的正常帧(任何移动之前)

在左上角我输出深度缓冲器(阴影图)。在右上角,我使用qml制作了一些自定义滚动条。我正在使用此滚动条来更改阴影贴图旋转和移动摄像头。当卷轴居中时,没有任何动作。当我改变某些东西时,场景变得丑陋,我不知道为什么。

Scene view after some shadow map rotate 这是经过一番阴影贴图旋转

我看到阴影贴图深度缓冲没有改变(为什么?O_0)在现场和阴影出错的框架。但是不仅影子在将我的旧代码重构为qml项目后失败了。当我移动相机时,错误变得更加奇怪。

Scene after moving camera down (-Z) 这是通过使用移动式摄像机向下(-Z)

场景下QML渲染后的帧:

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

在renderScene I:

  • 做一些OpenGL传送带设置(防止Qml场景图更改,可能会过多);

    glViewport(0, 0, window->width(), window->height()); 
    
    glClearColor(0, 0, 0, 1); 
    glClearDepth(1); 
    glDepthRange(0,1); 
    glDepthFunc(GL_LEQUAL); 
    
  • 呼叫BulletPhysics计算物理(测试场景 - 两个下降立方体)

  • 渲染阴影贴图(深度)要渲染(2048x2048的纹理,GL_DEPTH_COMPONENT24)
  • 渲染场景渲染(两个用于颜色和法线的GL_RGBA8纹理以及一个用于深度的GL_DEPTH_COMPONENT24)
  • 渲染两个二维方格 - 全屏(场景渲染,渲染缓冲区中的所有纹理用阴影渲染)和侧屏幕(深度缓冲区的左上角纹理)

我很累寻找正在发生的事情。 glGetError不显示任何内容。

Scene with camera moved 通过XY轴再次移动相机。男人的喇叭轮廓仍清晰可见,并有奇效

一些更多的截图:

Old project 老项目(不包括QML)

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

Broken resize On new proj ECT,窗口大小调整太

打破它可以是什么?

环境:Qt Creator的3.0.0,5.2.0的Qt,Linux操作系统(Kubuntu的13.10)64位,HD 7750

OpenGL的:在旧的项目,我设置了3.3,新项目中使用4.3(据我记得)

PS由于我在着色器中使用了一些额外的变形来改善场景中心中的阴影,所以深度贴图失真。

回答

4

的灵感一天后,临到我没有答案和以前的许多天!

我一直怀疑的东西是错误的深度缓存,并试图输出到用于呈现并用于呈现全屏四调试质感的ID。我尝试关闭渲染到纹理缓冲区交换等等。但我甚至不认为真正的问题在Qml方面。

glDepthMask(GL_TRUE); // 42!

一条线就像42 - 回答所有问题。似乎Qml在第一个渲染帧之前调用了glDepthMask(GL_FALSE);(但是在发出&QQuickWindow::beforeRendering信号之后)。这次调用的结果是,只有首先我的帧真正写入深度缓冲区。为什么我认为glDepthMask(GL_FALSE);只被调用一次?由于插入我的“42”后FPS明显减少,并且在插入glDepthMask(GL_FALSE);后用于渲染场景的插槽末尾,FPS明显减少。

现在,我可以自由旋转“太阳报”(影子)和移动相机而无需任何视觉错误。

Yippee!

Result in new project

+1

这是对我的答案:d我使用glEnable(GL_DEPTH_TEST)没有结果,但使用glDepthMask(GL_TRUE)确实在QML的伎俩。 –

+1

当我与那个bug战斗时,我尝试glEnable和glDisable与我使用的所有状态 - 深度测试,混合,剔除面部...但没有任何实际结果。 glDepthMask是太多不明显的记住和怀疑... – user2271079

+0

优秀的答案 - 虽然可悲我不知道为什么它的情况下(这填补了我对未来一些恐惧)我花了很多年试图让OpenGL工作在Sean Harmer的博客下的QML下 - 虽然看起来不正确,但认为这可能与深度缓冲区有关,但如果没有您的帮助,我就不会找到它.Txs。 – StuReeks