2007年3月,Khronos完成了OpenGL ES 2.0規(guī)范的制定,OpenGL ES 2.0顯著增強(qiáng)了各種移動(dòng)設(shè)備的功能、靈活性及視覺(jué)體驗(yàn)。OpenGL ES 2.0設(shè)備將會(huì)包含兩款驅(qū)動(dòng),分別支持OpenGL ES 2.0及OpenGL ES 1.1。在Android中,目前軟件渲染僅支持OpenGL ES 1.1。如果底層芯片支持硬件渲染,則可以利用OpenGL ES 2.0來(lái)進(jìn)行硬件渲染。
2010年3月,Goolge推出的Android NDK r3提供了對(duì)于OpenGL ES 2.0直接調(diào)用的功能,這將更加有利于提高Android圖像處理的能力。
新的NDK版本為Android NDK r5b。允許開(kāi)發(fā)者直接接入事件、音頻、圖像、窗口管理、斷言、存儲(chǔ)等。通過(guò)NativeActivity還可以管理應(yīng)用程序的生命周期,進(jìn)一步增強(qiáng)了原生代碼開(kāi)發(fā)的能力。
在Android中,Open GL ES的實(shí)現(xiàn)被封裝在android.opengl中,主要的接口包括GLSurfaceView.EGLConfigChooser、GLSurfaceView.EGLContextFactory、GLSurfaceView.EGL WindowSurfaceFactory、GLSurfaceView.GLWrapper、GLSurfaceView.Renderer等。
主要的類(lèi)包括GLDebugHelper(調(diào)試OpenGL ES 應(yīng)用的助手函數(shù))、GLES10(OpenGL ES 1.0)、GLES10Ext(OpenGL ES 1.0擴(kuò)展)、GLES11(OpenGL ES 1.0)、GLES11Ext(OpenGL ES 1.1擴(kuò)展)、GLSurfaceView(專用于OpenGL ES渲染的視圖)、GLU(OpenGL ES的工具包)、GLUtils(橋接OpenGL ES和Android API的工具類(lèi))、Matrix(矩陣)、Visibility(一個(gè)計(jì)算三角形網(wǎng)格能見(jiàn)度的工具集)等。
OpenGL ES的原生方法接口的定義主要位于frameworks\base\core\jni目錄下,分布在android_opengl_GLES10.cpp、android_opengl_GLES10Ext.cpp、android_opengl_GLES11.cpp、android_opengl_GLES11Ext.cpp等。
由于3D和2D的渲染機(jī)制有所不同,所以Android通過(guò)對(duì)SurfaceView的繼承,創(chuàng)立了專用于3D渲染的GLSurfaceView。GLSurfaceView調(diào)用自定義的渲染器可以在特定的Surface上進(jìn)行OpenGL ES的渲染,同時(shí)GLSurfaceView還實(shí)現(xiàn)了SurfaceHolder.Callback接口,可以監(jiān)聽(tīng)到Surface狀態(tài)變化的消息。下圖顯示了GLSurfaceView的類(lèi)圖。

GLSurfaceView的類(lèi)圖
GLSurfaceView提供了如下的能力:
第一,GLSurfaceView管理著一個(gè)特定的Surface,可以將OpenGL ES整合進(jìn)Android的視圖系統(tǒng)。
第二,GLSurfaceView管理著一個(gè)EGL顯示(EGL Display),這使得OpenGL可以被渲染到Surface中。
第三,GLSurfaceView可以利用用戶定義的渲染器(Renderer)對(duì)象來(lái)執(zhí)行渲染。
第四,在GLSurfaceView中,為了提供渲染的性能,渲染工作會(huì)放在專有的線程中進(jìn)行,與UI線程是分離的。
第五,在GLSurfaceView中,渲染模式可以分為兩種:持續(xù)渲染模式(Continuous Rendering Mode)和需求渲染模式(On-demand Rendering Mode)。
第六,在GLSurfaceView中,提供了包裝、跟蹤、檢錯(cuò)機(jī)制,方便OpenGL調(diào)用調(diào)試。
需要注意的是,由于渲染需要依賴于用戶提供的渲染器進(jìn)行,在進(jìn)行初始化一個(gè)GLSurfaceView對(duì)象時(shí),必須調(diào)用GLSurfaceView::setRenderer()方法來(lái)設(shè)置所用的渲染器。在設(shè)置渲染器前,用戶可以根據(jù)自己的需求設(shè)置調(diào)試標(biāo)志位、配置信息、包裝器等。
下面是調(diào)用GLSurfaceView的一個(gè)實(shí)現(xiàn)過(guò)程:
mGLView=new GLSurfaceView(this);
mGLView.setEGLConfigChooser(false);
mGLView.setRenderer(new StaticTriangleRenderer(this));
setContentView(mGLView);
在目前的實(shí)現(xiàn)中,Android已經(jīng)提供了TriangleRenderer(三角板)、CubeRenderer(一對(duì)滾動(dòng)的立方)、StaticTriangleRenderer(靜態(tài)三角)、SpriteTextRenderer(文字精靈)、KubeRenderer、ClearRenderer、DemoRenderer等自定義渲染器的實(shí)例。
這里需要說(shuō)明的是,為了實(shí)現(xiàn)自定義的渲染器,必須實(shí)現(xiàn)GLSurfaceView.Renderer:: onSurfaceCreated()、GLSurfaceView.Renderer:: onSurfaceChanged()、GLSurfaceView.Renderer:: onDrawFrame()等3個(gè)方法。
下面以CubeRenderer為例來(lái)說(shuō)明這一過(guò)程:
代碼:自定義渲染器的一般過(guò)程
public class CubeRenderer implements GLSurfaceView.Renderer {
public CubeRenderer(boolean useTranslucentBackground) {
mTranslucentBackground=useTranslucentBackground;
mCube=new Cube(); //構(gòu)建立方體對(duì)象
}
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);//清空屏幕
//設(shè)置矩陣模式為視圖矩陣,其他兩種模式為投影矩陣、紋理矩陣,該方法需和gl.glLoadIdentity()配合使用。
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity(); //重置當(dāng)前指定的矩陣為單位矩陣
gl.glTranslatef(0, 0, -3.0f); //設(shè)置渲染的起始坐標(biāo)
gl.glRotatef(mAngle, 0, 1, 0); //進(jìn)行旋轉(zhuǎn)
gl.glRotatef(mAngle*0.25f, 1, 0, 0);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); // 激活選擇的數(shù)組
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
mCube.draw(gl); //執(zhí)行渲染
gl.glRotatef(mAngle*2.0f, 0, 1, 1);
gl.glTranslatef(0.5f, 0.5f, 0.5f);
mCube.draw(gl);
mAngle +=1.2f;
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
float ratio=(float) width/height;
gl.glMatrixMode(GL10.GL_PROJECTION); //設(shè)置矩陣模式為投影矩陣
gl.glLoadIdentity();
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); //創(chuàng)建投影矩陣
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glDisable(GL10.GL_DITHER);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);
if (mTranslucentBackground) {
gl.glClearColor(0,0,0,0);
}else{
gl.glClearColor(1,1,1,1);
}
gl.glEnable(GL10.GL_CULL_FACE) ;
//設(shè)置著色模型為平滑著色,另一種模式為平面著色
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glEnable(GL10.GL_DEPTH_TEST);
}
private boolean mTranslucentBackground;
private Cube mCube;
private float mAngle;
}
在自定義渲染器時(shí),需要注意gl.glMatrixMode()方法和gl.glLoadIdentity()方法必須配合使用,前者設(shè)置矩陣模式為視圖矩陣、投影矩陣、紋理矩陣中的一種,后者重置當(dāng)前指定的矩陣為單位矩陣。
另外在設(shè)置著色模型時(shí),需根據(jù)自身的需求設(shè)置著色模型是平滑著色還是平面著色。