2012-07-28 98 views
1

我正在研究一個簡單的android遊戲。我認爲我想用多線程優化我的引擎。我在OpenGL ES工作,Android 2.2的Android多線程遊戲

現在UpdateGame()和RenderScene()單線程運行,並在onDrawFrame(GL10 GL)

我有了位置,旋轉,縮放一個渲染對象類執行和Color成員。所有RenderObjects都是在我開始遊戲時創建的,並存儲在RenderObject數組中。

在UpdateGame()函數中,我通過RenderObject數組中的RenderObjects並更新新的位置,旋轉,比例和顏色。

在RenderScene()函數中,我通過RenderObject數組中的RenderObjects並使用新的Position,Rotation,Scale和Color來渲染它們。

這在單線程中正常工作。

所以然後我試着爲UpdateGame()創建一個線程。

所以我的想法是:

更新主題:................渲染線程:

更新幀0

更新的第1幀................渲染幀0 ....並行更新和渲染工作

更新幀2 .............. ..Render Frame 1

更新幀3 ................渲染幀2

但是,首先我修改了RenderObject類,使它具有RenderPosition,RenderRotation,RenderScale和RenderColor成員。

這些成員會在渲染前一幀之前被複制。所以並行更新線程可以修改新的位置,旋轉,縮放,顏色。

Runnable pRunnable; 
Thread pThread; 
public int renderframe = 0; 
piblic int updateframe = 0; 

public void onSurfaceCreated(GL10 gl, EGLConfig config) 
{ 
    // I create a new thread in this function   
    pRunnable = new Runnable(){ 
     public void run(){ 
      while(true) 
      { 
       while(renderframe < updateframe) 
       { 
        // WAITING for render to finish so that data does not get corrupterd 
       } 
       // 
       // I update RenderObject Position, Rotation, Scale, Color members here 
       UpdateGame(); 
       updateframe++; 
      } 
     } 
    }; 

    pThread = new Thread(pRunnable); 
    pThread.start(); 
} 

public void onDrawFrame(GL10 gl) 
{ 
    while(renderframe == updateframe) 
    { 
     // Wait for update to finish 
    } 

    for(int a=0;a<MAX_RENDER_OBJECTS;a++) 
    { 
     RenderObject ro = aRenderObjects[a]; 
     // I do this in a function 
     ro.RenderPosition[0] = ro.Position[0]; 
     ro.RenderPosition[1] = ro.Position[1]; 
     ro.RenderPosition[2] = ro.Position[2]; 
     ro.RenderPosition[3] = ro.Position[3]; 
     // I do the same for Rotation, Scale, Color 

    } 

    renderframe++; 

    // When rendering scene I use RenderPosition, RenderRotation members when calling OpenGL API 
    RenderScene(); 

} 

但是當我運行我的遊戲。圖形不正確。它看起來好像數據不同步。

有關如何在Update和Render線程之間適當同步RenderObject數據的任何建議。

謝謝。

+0

在http://gamedev.stackexchange.com/上試試這個問題。 – Flynn81 2012-07-28 11:52:01

回答

0

此風格似乎通常效率低下(旋轉等待循環,將阻止兩個線程同時工作)和危險的(我不知道Android如何實現這一點,但Java內存模型並不保證來自一個線程的數據是另一個線程可見但不通過同步塊)。我的建議是這樣的:主線程是渲染線程(GL上下文是線程本地的,所以你不能從另一個線程使用它(儘管你可以在另一個線程上創建另一個上下文來執行一些數據共享) ),併產生更新線程。主線程繼續循環,每次迭代都等待互斥量。更新線程更新遊戲邏輯,並創建一個代表必須繪製的所有內容的新對象(例如繪圖命令列表)。然後將該對象放在隊列中,主線程被喚醒(使用notify())。主線程然後獲取繪圖數據並繪製它。

如果更新循環比渲染循環快得多,您可能會想要關閉較舊的數據集,但是這個總體思路應該讓您開始。

+0

在Android中,GL上下文位於其自己的線程中,主線程保留用於處理Android事件。我會用繪圖隊列跟蹤你的方法並通知,但是從Activity而不是Renderer啓動遊戲狀態線程。用戶輸入也需要以類似的方式從Activity傳遞到遊戲更新線程。 – eclark 2012-07-31 22:00:03