OpenGL ES應用開發實踐指南(android 卷)筆記 第一章
阿新 • • 發佈:2019-02-09
public class FirstOpenGLActivity extends Activity { private GLSurfaceView glSurfaceView; //用於記住GLSurfaceView是否處於有效狀態 private boolean rendererSet = false; /** * GLSurfaceView會在一個單獨的執行緒中呼叫渲染器的方法。 * 預設情況下,GLSurfaceView會以顯示裝置的重新整理頻率不斷地渲染, * 當然,它也可以配置為按請求渲染,只需要用GlSurfaceView.RENDERMODE_WHEN_DIRTY作為引數呼叫GLSurfaceView.setRenderMode()即可* * 既然Android的GLSurfaceView在後臺執行緒中執行渲染,就必須要小心, * 只能在這個渲染執行緒中呼叫OpenGL,在Android主執行緒中使用UI(使用者介面)相關的呼叫; * 兩個執行緒直接的通訊可以用如下方法: * 在主執行緒中的GLSurfaceView例項可以呼叫queueEvent()方法傳遞一個Runnable給後臺渲染執行緒, * 渲染執行緒可以呼叫Activity的runOnUIThread()來傳遞事件(event)給主執行緒 * @param savedInstanceState*/ @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); glSurfaceView = new GLSurfaceView(this); final ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();final boolean supportsEs2 = configurationInfo.reqGlEsVersion >= 0x20000 || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1 && (Build.FINGERPRINT.startsWith("generic") || Build.FINGERPRINT.startsWith("unknown") || Build.MODEL.contains("google_sdk") || Build.MODEL.contains("Emulator") || Build.MODEL.contains("Android SDK built for x86"))); if(supportsEs2){ glSurfaceView.setEGLContextClientVersion(2); glSurfaceView.setRenderer(new FirstOpenGLRenderer()); rendererSet = true; } else { Toast.makeText(this, "This device does not support OpenGL ES 2.0",Toast.LENGTH_SHORT).show(); return; } setContentView(glSurfaceView); } @Override protected void onPause() { super.onPause(); if(rendererSet){ glSurfaceView.onPause(); } } @Override protected void onResume() { super.onResume(); if(rendererSet){ glSurfaceView.onResume(); } } }
public class FirstOpenGLRenderer implements GLSurfaceView.Renderer{ /** * 當Surface被建立的時候,GLSurfaceView會呼叫這個方法; * 這發生在應用程式第一次執行的時候,並且,當裝置被喚醒或者使用者從其他activity切換回來時,這個方法也可能會被呼叫。 * 在實踐中,這意味著,當應用程式執行時,本方法可能會被呼叫多次。 * @param gl10 * @param eglConfig */ @Override public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) { //紅綠藍透明度,渲染後結果為紅色 gl10.glClearColor(1.0f,0.0f,0.0f,0.0f); } /** * 在Surface被建立以後,每次Surface尺寸變化時,這個方法都會被GLSurfaceView呼叫到。在橫屏、豎屏來回切換的時候,Surface尺寸會發生變化 * @param gl10 * @param width * @param height */ @Override public void onSurfaceChanged(GL10 gl10, int width, int height) { gl10.glViewport(0, 0, width, height); } /** * 當繪製一幀時,這個方法會被GLSurfaceView呼叫。 * 在這個方法中,我們一定要繪製一些東西,即使只是清空螢幕; * 因為,在這個方法返回後,渲染緩衝區會被交換並顯示在螢幕上,如果什麼都沒畫,可能會看到糟糕的閃爍效果 * @param gl10 */ @Override public void onDrawFrame(GL10 gl10) { gl10.glClear(GL10.GL_COLOR_BUFFER_BIT); } }