2011-12-05 23 views
0

我遇到了一個問題,當我得到一個onResume時,我重新創建了EGL和GLES狀態,但它不會再繪製任何東西。重要的代碼在初始創建和簡歷代碼之間是相同的。我目前很難理解可能會導致這種情況的原因。事情與我的EGL表面的初始創建和顯示完美配合。只有當應用程序恢復時(按回家按鈕,然後返回到應用程序)它是否顯示任何內容失敗。我已經驗證了其他所有內容的行爲都是應該的,輸入被接收,並且Android回調正常發生(在dalvik或渲染線程中沒有阻塞或鎖定)。 EGL和GLES狀態在onPause和onResume之間完全銷燬並重新創建。使用GLES時onResume後的空白屏幕

+0

好吧,我已經找出了一半的問題,eglSwapBuffers失敗與壞表面。 eglCreateWindowSurface函數成功並且值與我傳遞給eglSwapBuffers的值相匹配,所以我有點困惑。 – Tomasu

+0

我不是100%確定的,但我認爲GL狀態應該被破壞並在onPause和onResume之間重新創建。我只是把所有的頂點數據,位圖等存儲在正常的內存中,並在我需要的時候加載東西(在紋理的情況下,我必須在onResume中重新加載它們) –

+0

感謝回覆,是的,狀態應該是完全重新創建,這正是我正在做的。我不認爲我可以偷看你在做什麼? GLSurfaceView類的代碼稍微沒有幫助,因爲它爲不需要對代碼進行大量混淆的功能做了很多工作。這可能是我的代碼中的一個錯誤,但就我昨天看到的,我完全重新創建了onPause和onResume之間的GL狀態。 – Tomasu

回答

2

我所做的是在應用程序啓動或需要時將所有3D模型頂點,紋理等載入內存(不是GL句柄)。

我有一個相對簡單的遊戲應用程序,用openGL-es 1.1編寫(沒有燈光,着色器,粒子等等,只是紋理模型)。我需要提前加載到openGL中的唯一東西是紋理,因爲它們需要很長時間才能加載。其他一切可以在運行時中渲染的方法的onDraw要做

所以我的代碼看起來有點像這樣:

@override 
public void onPause(){ 

    findViewById(R.id.loading_screen).setVisibility(View.VISIBLE); 

} 

@Override 
public void onResume(){ 
    super.onResume(); 

    findViewById(R.id.loading_screen).setVisibility(View.VISIBLE); 

    myRenderer.reLoadTextures(); 

    findViewById(R.id.loading_screen).setVisibility(View.GONE);  
} 

@Override 
public void onRestart(){ 
    super.onRestart(); 

    findViewById(R.id.loading_screen).setVisibility(View.VISIBLE); 

    myRenderer.reLoadTextures(); 

    findViewById(R.id.loading_screen).setVisibility(View.GONE); 
} 

class MyRenderer implements Renderer{ 

    private HashMap<String,Texture> textures; 
    private boolean reloadTextures = false; 

    // flag to the renderer that textures need to be reloaded 
    public void reLoadTextures(){ 
     reloadTextures = true; 
    } 

    public void onDraw(GL10 gl){ 

     if(reloadTextures){ 

      // loop through hashmap and reload textures 
      Iterator it = textures.entrySet().iterator(); 
      while(it.hasNext()){ 
       Entry set = it.next(); 
       set.getValue().loadTexture(gl, set.getKey(), context); 
      } 

      reloadTextures = false; 
     } 

     // draw models as normal 

    } 

} 

...我知道是不是你真正關注對於。這樣做意味着GL狀態被破壞並不重要。 Android會自動爲您提供全新的GL狀態,就像它首次啓動應用程序一樣。這也意味着你永遠不需要擴展SurfaceView,只需實現渲染器即可實現渲染器

這是簡化版本,一旦考慮到線程化,它會變得更加複雜。在Texture.loadTexture()中也有一些工作可以確保模型使用的引用以及從glGenTextures獲得的Id仍然匹配,以便繼續執行應用/活動。

此外,如果您的清單文件中有android:screenOrientation="landscape",請務必像我的手機一樣經常處理方向更改,主屏幕和鎖定屏幕始終處於縱向狀態,並且應用程序恢復,方向將是錯誤的。不重寫onConfigurationChange()可能會導致與GLSurfaceView問題(如一些紋理不顯示),即使你已經重新加載它們在onResume

+0

感謝您的回覆:)我沒有使用GLSurfaceView,因爲代碼實際上不適用於帶有onDraw位的GLSurfaceView的「模型」。基本上我的代碼所做的就是將一個帶有GLES的SurfaceView綁定到一些運行在獨立線程中的C代碼中,該代碼執行自己的輸入處理和渲染。此外,當前測試代碼正在渲染的唯一東西是白色背景,並且每個已識別的觸摸都有一個矩形。所以沒有什麼可以恢復的,除了EGL和GLES狀態本身。但即使這樣做,它不想恢復正常。 – Tomasu

+0

嗯,我明白了,幫不了你,抱歉 –

+0

感謝您的試用:)我現在的計劃,當我有時間的時候,就是寫一個簡單的SurfaceView + EGL演示程序,看看它是否有效。如果它(可能),我會嘗試添加更多的邏輯從當前的代碼,直到它打破。 – Tomasu