寫幾篇文章記錄一下我學習OpenGL的過程,這是第一篇。本片文章經過實現一個清屏操做,先了解一些基本知識。java
1.建立一個activity,做爲展現頁面:android
/** * 視圖展現頁面,只實現了清屏的操做<br/> * 1.建立GLSurfaceView<br/> * 2.調用GLSurfaceView的setRenderer方法,設置Renderer<br/> * 3.實現Renderer<br/> * 4.處理Activity的生命週期事件<br/> */ public class FirstOpenGLActivity extends AppCompatActivity { private static final String TAG = FirstOpenGLActivity.class.getSimpleName(); private GLSurfaceView mGLSurfaceView; /** * is render seted */ private boolean isRendererSet = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mGLSurfaceView = new GLSurfaceView(this); //檢察系統是否支持OpenGL ES 2.0 ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo(); boolean isSupportsEs2 = configurationInfo.reqGlEsVersion >= 0x20000; Log.d(TAG, "isSupportsEs2 =" + isSupportsEs2); if (isSupportsEs2) { //Request an OpenGL ES 2.0 compatible context mGLSurfaceView.setEGLContextClientVersion(2); //Assign our renderer //當surface建立或者發生變化的時候,以及要繪製一副新幀時,渲染器都會被GLSurfaceView調用 mGLSurfaceView.setRenderer(new FirstOpenGLRenderer()); isRendererSet = true; } else { Toast.makeText(this, "this device dose not support OpenGL ES 2.0", Toast.LENGTH_SHORT); } setContentView(mGLSurfaceView); } //頁面恢復,繼續後臺渲染線程,續用OpenGL上下文 @Override protected void onResume() { super.onResume(); if (isRendererSet) { mGLSurfaceView.onResume(); } } //頁面不可見,暫停後臺渲染線程,釋放OpenGL上下文 @Override protected void onPause() { super.onPause(); if (isRendererSet) { mGLSurfaceView.onPause(); } } }
2.建立一個渲染器類實現Renderer接口:ide
/** * 渲染器類 實現了Renderer接口 * Created by hsji on 16/1/10. */ public class FirstOpenGLRenderer implements GLSurfaceView.Renderer { /** * 當surface被建立的時候,GLSurfaceView會調用這個方法; * 這發生在應用程序第一次運行的時候,而且,當設備被喚醒或者用戶從其餘activity切換回來的時,這個方法也可能會被調用。 * 在實踐中,這意味着當程序運行時這個方法可能會被調用屢次。 * * @param gl10 * @param eglConfig */ @Override public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) { //設置清空屏幕所使用的顏色RGBA GLES20.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) { //set the OpenGL viewport to to fill the entire surface GLES20.glViewport(0, 0, width, height); } /** * 當繪製一幀時,這個方法會被GLSurfaceView調用。 * 在這個方法中咱們必定要繪製一些東西,即便只是清空屏幕; * 由於,在這個方法返回以後,渲染緩衝區會被交換並顯示在屏幕上, * 若是什麼都沒畫,可能會看到閃爍效果 * * @param gl10 */ @Override public void onDrawFrame(GL10 gl10) { //clear the rendering surface //清空屏幕,擦出屏幕上的全部顏色,並調用以前glClearColor()定義的顏色填充整個屏幕 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); } }
一點解釋:怎麼會有一個未被使用的參數類型GL10呢?學習
* 他是OpenGL ES 1.0的API遺留下來的;
* 若是要編寫使用OpenGL ES 1.0的渲染器,就要使用這個參數,
* 可是對於OpenGL ES 2.0,GLES20類提供了靜態方法來存取。
3.渲染線程和主線程之間的交互(以後還會詳細涉及,這裏只是一個概要)this
GLSurfaceView會在一個單獨的線程中調用渲染器的方法。默認狀況下,GLSurfaceView會以顯示設備的刷新頻率不斷的渲染,固然,它也能夠配置爲按請求渲染,只須要用GLSurfaceView.RENDERMODE_WHEN_DIRTY做爲參數調用GLSurfaceView.setRenderMode()便可。
既然android的GLSurfaceView在後臺縣城中執行渲染,就必需要當心,只能在這個渲染線程中調用OpenGL,在android主線程中使用UI相關的調用;兩個線程之間的通訊可使用以下方法:在主線程中的GLSurfaceView實例能夠調用queueEvent()方法傳遞一個Runnable給後臺渲染線程,渲染線程就能夠調用Activity的runOnUIThread()來傳遞事件(event)給主線程。
4.運行程序便可看到一個純紅色的屏幕。spa