2017-05-29 79 views
0

發展teris的遊戲,我來,使用通常的MVC模式可能會弄亂我的代碼,以及,因爲OpenGL是如何GLEW下工作進行了總結,使其實質上難以建立在。相反,我想出了這個整齊的修改,也依賴於觀察者模式,這將使有點更有意義,至少在短期內(圖像不完全反映分類):
makeshift architecture如何解決這個設計缺陷?

爲了解釋:
-Every框是一類,Engine保存Entities的實例,Game保存Figure的實例。
- Figure繼承Entity
- Engine觀察Game,和Game由觀察員用Figures耦合。

如何它應該工作:
理想情況下,我應該實例Engine將設置GLEW和GLFW與其他一切將彌補窗口,然後創建一個Game對象,其中,在新的線程,將創建一個沿圖中,並通知引擎啓動繪圖循環,並且當設置該圖形時,通過Observer將對象指針傳遞給Engine
這做工精美,我將能夠通過繼承Entity添加各種各樣的人物,人物不會從屏幕上掉下,因爲每個座標更新將經歷Game,我可以,也許,讓每個人物的唯一着色器,如果這是必要的。

如何它的實際工作:
引擎被初始化,遊戲被初始化,數字是在另一個線程呼籲,並拋出

atioglxx.dll: 0xC0000005: Access violation reading location 0x00000728. 

當被問及訪問任何的OpenGL函數。
我懷疑這種情況是因爲Figure不知道,所有的配套功能,在Engine啓動。我不能再在Figure中再做一次。我可以將與View相關的所有內容移動到Engine,但是我無法設置單獨的着色器,並且我必須爲Engine內的每個數字構建VAO(頂點數組對象)。
那麼如何讓錯誤消失,同時儘可能少地引入變化?

+0

這可能是一個有趣的問題,但也可能是題外話這裏。 – Walter

+0

@Walter,我考慮將它放在gamedev.stack上,但它似乎並沒有像建築問題那麼多地處理 –

回答

0

簡短的回答是,所有OpenGL調用給定環境下需要在同一個線程。較長的答案是在路上...


首先,Entities需要能夠與GL調用汲取自己。您不能將繪圖代碼從一個線程與另一個線程混合使用,OpenGL客戶端狀態將不正確。 (將OpenGL視爲'C'狀態機)。

其次,你需要通過幀緩衝實體狀態。當您在Game線程中開始下一幀時,Engine可能會或可能不會完成提交繪製調用。所以你需要一些同步的方式來提交一個幀的所有Entity狀態。這有點棘手,因爲你想避免同步原語(例如互斥體),這可能會拖延你的管道或導致阻塞。

您可以閱讀Doom III source code,它使用雙緩衝管道將提取調用請求提交給Engine後端。訣竅是Doom在主線程中執行了大部分任務,然後拆分爲在後端執行Draw Calls(Engine)線程並提交Game主線程下一幀的繪製狀態(Entities)。然後它等待Engine線程完成並交換緩衝區。

閱讀Metal和Vulkan多線程。這些非常相似。

資源需要在Engine被加載,併爲您的實體引用返回的句柄(着色,紋理,靜態Geomety,等..)