2014-02-19 53 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