2012-07-12 69 views
0

我目前正在研究多線程安全渲染系統,我想知道如何正確更新遊戲世界中的下一步,而前一場景是目前呈現。目前我正在使用LWJGL Opengl與Java綁定。這裏是僞代碼爲我的遊戲循環,因爲它是目前設置了(這也許只是一個基本的循環,大多數人都熟悉):在渲染前一幀時提前更新場景

//DrawingLayers are wrappers for in game entities and has an update 
//and render method 

game-loop: 
    addInputEventsToInputStack() 

    removeCompletedDrawingLayers() 

    foreach layer in DrawingLayerQueue : 
     layer.update(deltaTime) //update position/color/size for entity 
     layer.render() //performs OpenGL calls 
     if(layer.isCompleted): 
      addToCompletedDrawingLayersList() 


    swapBuffers() //blocks until scene is fully rendered 
goto game-loop 

我的問題就出在swapBuffers()方法,因爲它阻止,直到現場呈現這意味着我無法執行任何更新,而這是正在進行。我想如何解決這個問題是:

有一個所有DrawingLayers的副本,我用它來更新實體的狀態,並讓另一個副本作爲渲染線程的引用。在幀正在渲染時,在swapBuffers()之前啓動線程以更新未使用的副本。

我很擔心這種方法,因爲我相信在每一幀之前創建副本會降低系統比我想要的更多。

我的方法是否有意義,如果沒有,您是否有任何建議如何做到這一點?我願意進行徹底的重組。

更新時間:基於datenwolf的建議,我已經改變了我gameloop以下幾點:

//DrawingLayers are wrappers for in game entities and has an update 
//and render method 


//A future for the pre-processing task 
Future preProcess = null 

game-loop: 

    //Update: checks if we have a preprocessed update to wait for 
    //and waits for it to complete 
    if(preProcess != null): 
     preProcess.get() 
     preProcess = null 

    addInputEventsToInputStack() 

    removeCompletedDrawingLayers() 

    foreach layer in DrawingLayerQueue : 
     layer.render() //performs OpenGL calls 
     if(layer.isCompleted): 
      addToCompletedDrawingLayersList() 

    //UPDATE: the following just calls all the update methods for the layers 
    // in a new thread 
    preProcess = executorService.submit(new UpdateRunnable()) 

    swapBuffers() //blocks until scene is fully rendered 
goto game-loop 

所以用這個到目前爲止,我已經得到了在性能顯著的改善。可能有一些我不能看到的競爭條件問題,但總體來說我很滿意這種改進。

回答

1
在swapBuffers

()方法,因爲它阻止,直到場景渲染

緩衝交換的阻擋只有通過完成渲染部分。它通常也會因爲等待回溯而阻塞。然而,OpenGL保證,在任何繪圖命令返回後,可以安全地修改它所訪問的緩衝區,而不會影響任何掛起的渲染操作。該實現需要進行復制或寫時複製映射到所有數據。

或者簡而言之:只要修改緩衝區中的數據即可。只要繪圖調用(glDrawArrays,glDrawElements)返回它是安全的。

+0

我更新了我的原始問題,並根據您的評論進行了更改。 – heinz 2012-07-13 01:12:21