本節書摘來自華章出版社《opengl es應用開發實踐指南:android卷》一 書中的第1章,第1.4節,作者:(美)kevin brothaler ,更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。
現在要定義一個渲染器,以便我們開始清空螢幕。
讓我們快速浏覽一下渲染器接口定義的方法:
當surface被建立的時候,glsurfaceview會調用這個方法;這發生在應用程式第一次運作的時候,并且,當裝置被喚醒或者使用者從其他activity切換回來時,這個方法也可能會被調用。在實踐中,這意味着,當應用程式運作時,本方法可能會被調用多次。
在surface被建立以後,每次surface尺寸變化時,這個方法都會被glsurfaceview調用到。在橫屏、豎屏來回切換的時候,surface尺寸會發生變化。
當繪制一幀時,這個方法會被glsurfaceview調用。在這個方法中,我們一定要繪制一些東西,即使隻是清空螢幕;因為,在這個方法傳回後,渲染緩沖區會被交換并顯示在螢幕上,如果什麼都沒畫,可能會看到糟糕的閃爍效果。
怎麼會有一個未被使用的參數類型gl10呢?它是opengl es 1.0的api(應用程式程式設計接口)遺留下來的;如果要編寫使用opengl es 1.0的渲染器,就要使用這個參數;但是,對于opengl es 2.0,gles20類提供了靜态方法來存取。
在背景線程中渲染
glsurfaceview會在一個單獨的線程中調用渲染器的方法。預設情況下,glsurfaceview會以顯示裝置的重新整理頻率不斷地渲染,當然,它也可以配置為按請求渲染,隻需要用
glsurfaceview.rendermode_when_dirty作為參數調用glsurfaceview.setrendermode()即可。
既然android的glsurfaceview在背景線程中執行渲染,就必須要小心,隻能在這個渲染線程中調用opengl,在android主線程中使用ui(使用者界面)相關的調用;兩個線程之間的通信可以用如下方法:在主線程中的glsurfaceview執行個體可以調用queueevent()方法傳遞一個runnable給背景渲染線程,渲染線程可以調用activity的runonuithread()來傳遞事件(event)給主線程。
建立渲染器
在同一個包裡建立一個各為firstopenglprojectrender的新類,用來實作renderer接口;為了建立這個新類,在包浏覽器(package explorer)裡,滑鼠右鍵單擊“com.firstopenglproject.android”,接着選擇“new→class”;在彈出的“new java class”視窗中輸入“firstopenglprojectrenderer”作為名字,并單擊“finish”按鈕。
我們會以下面的代碼作為開始,并加入我們的第一個方法onsurfacecreated():

首先,在onsurfacecreated()中調用glclearcolor(1.0f, 0.0f, 0.0f, 0.0f)設定清空螢幕用的顔色;前三個參數分别對應紅色、綠色和藍色,最後的參數對應一個特殊的分量,稱為阿爾法(alpha),它經常用來表示半透明度或透明度。通過把第一個分量設為1,其餘設為0,我們把紅色設定為最大強度,當螢幕被清空時,它就會顯示紅色。2.6節會更詳細地讨論這個顔色模型。
下一步就是設定視口(viewport)尺寸了,讓我們加入如下代碼:
在onsurfacechanged()方法中,調用glviewport(0, 0, width, height)設定了視口尺寸,這就告訴了opengl可以用來渲染的surface的大小。
要用如下代碼完成這個渲染器類:
在ondrawfame()中調用glclear(gl_color_buffer_bit)清空螢幕;這會擦除螢幕上的所有顔色,并用之前glclearcolor()調用定義的顔色填充整個螢幕。
現在測試一下代碼,看看會發生什麼。按“ctrl+f11”鍵運作這個程式。你會看到一個空白的紅色螢幕,如圖1-4所示。
嘗試改變清空的顔色,然後再運作程式看看會發生什麼!你應該看到螢幕上的顔色與代碼的改動完全比對。
如果你使用的是模拟器,且程式不工作,而你也檢查過模拟器的配置選項“use host gpu”已經被勾選了,那就試試在glsurfaceview.setrenderer()調用之前加入glsurfaceview.seteglconfigchooser(8,8,8,8,16,0)的調用。