目的是什麼:
我是比較新的線程。我一直在試圖讓Quad-Tree渲染出能夠快速高效渲染的地形。目前渲染的地形數量將大大滯後於用戶,如果這些數據全部是最詳細的。這就是爲什麼我使用QuadTree來渲染它。該引擎還支持輸入和物理因此我決定使用渲染線程。這造成了很多問題。
問題(s): 當我沒有線程時,由於引擎中的其他系統有點滯後。造成滯後的主要原因是QuadTree中地形的加載和刪除(我甚至不確定這是否是最佳方式)。現在,渲染髮生得非常快,而且似乎沒有滯後。當相機靜止時,遊戲運行良好。我離開遊戲運行了一個小時,沒有發現崩潰。
加載地形時,它使用渲染代碼使用的幾個變量。即,結合緩衝區 -
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(glm::vec2), &uvs[0], GL_STATIC_DRAW);
這個變量,我相信正在同時與其他線程訪問。導致崩潰。如何解決這個問題?我曾嘗試使用Mutexes,但這似乎不起作用。我會在哪裏鎖定和解鎖互斥鎖來解決這個問題?
另一個似乎會導致相同錯誤的變量是「IsLeaf」。
另一個崩潰(STD :: badAlloc)加載了大量的地形後引起的。即使它正在清理。我認爲這是由於我的刪除代碼,但我不知道什麼是錯的。
我目前添加和刪除瓷磚的方式是我檢查的範圍從相機中刪除/創建瓷磚。我想渲染我和其周圍的瓷磚。但是,從4個主要瓷磚中的一個轉換時,這不起作用。使用範圍創建不起作用,因爲它是大瓦片中心的範圍,而不是較小的範圍。我也嘗試每隔幾秒刪除整個地圖,這似乎也工作,但有更多的滯後。有沒有更好的方式來做創造和銷燬?
不同分辨率之間存在差距。無論如何減少這些?目前我呈現的瓷磚比他們需要的大一點,但是這對主要的分辨率變化沒有幫助。
如果你有任何想法如何修復這些錯誤,那也就可以大加讚賞之一。
的代碼(太多這裏上傳)
除此之外:從多個線程發送繪圖命令以在相同的幀緩衝區上操作實際上會減慢速度。幀緩衝區是一個互斥的資源。當多個線程正在繪製它時,驅動程序和GPU將花費大量時間在上下文之間切換。但是更糟糕的是引入了很多隱式同步點,這些同步點會刷新管道,從而導致吞吐量下降。 *簡而言之* **不要多線程渲染代碼!** * GPU將內部並行處理到片段級別。在這方面沒有什麼可以做的手動* – datenwolf
絕對同意@datenwolf。所有的渲染調用應該在一個線程上。將紋理/模型數據加載到線程A中的系統內存中並沒有什麼壞處,然後渲染線程(線程B)通過gl調用將其實際傳遞給驅動程序。 –
您可以在OpenGL線程中映射VBO/PBO(glMapBuffer ),並讓I/O線程直接將有效載荷數據讀入OpenGL內存,避免一個額外的副本。 – datenwolf