Cocos2d Android移植手記(一) - Opengl ES創建流程
前一陣子,一直在忙公司的iPhone的項目HourglassTimer,順便了解下iPhone 平臺上的2D引擎cocos2d-iphone庫的使用。由于一直沒有發現android上的基于Opengl ES 2D/3D引擎庫(網上只發現了一個java monkey engine項目,pc平臺上的游戲引擎。如果有人知道其他的開源項目,非常歡迎告訴我 ),所以自己準備將cocos2d移植到android平臺上。 最近做了些初步研究,這里逐步寫下來,給自己留個筆記,也希望和大家一起討論。閑言少敘,直接進入正題。
在android 1.0rc2 sdk中,提供了以下包支持Opengl ES 編程:
一、openglES包
android.opengl | |
Class: | |
GLDebugHelper:用于調試OpenGL ES程序的幫助類 | |
GLU:提供GL 公共工具功能的類 | |
GLUtils:連接OpenGL ES和Android API的工具類,其中提供了紋理圖片的操作。 | |
Matrix:矩陣運算工具類 | |
Exception: | |
GLException:OpenGL異常類 |
javax.microedition.khronos.egl | |
Interface: | |
EGL:GL的配置接口 | |
EGL10:GL1.0的配置接口 | |
EGL11:GL1.1的配置接口 | |
Classes: | |
EGLConfig:GL配置的類 | |
EGLContext:GL運行環境的類 | |
EGLDisplay:GL顯示窗口的類 | |
EGLSurface:可渲染GL的視圖類 | |
javax.microedition.khronos.opengles | |
Interfaces: | |
GL:Opengles的接口 | |
GL10:Opengles1.0的接口 | |
GL10Ext:Opengles1.0的擴展接口 | |
GL11:Opengles1.1的接口 | |
GL11Ext:Opengles1.1的擴展接口 | |
GLExtentsionPack:Opengles的擴展接口 | |
EGLDisplay:GL顯示窗口的類 | |
EGLSurface:可渲染GL的視圖類 |
二、通常創建流程:
a)創建一個EGL實例
EGL10 mEgl = (EGL10) EGLContext.getEGL();
b)創建一個EGLDisplay實例
EGLDisplay mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
c)初始化EGLDisplay
mEgl.eglInitialize(mEglDisplay, version);
d)選擇Config
mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, num_config);
EGLConfig mEglConfig = configs[0];
e)創建opengl運行環境
EGLContext mEglContext = mEgl.eglCreateContext( mEglDisplay,
mEglConfig,
EGL10.EGL_NO_CONTEXT,
null);
f) 創建新surface
mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay,
mEglConfig, holder, null);
g) 將opengles環境設置為當前
mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
mEglContext);
h) 獲取當前opengles畫布
GL gl = mEglContext.getGL();
i) 顯示繪制結果到屏幕上
mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
三、示例Cube分析
這里簡要分析下 google提供的示例代碼APIDemos中的Cube的運行結構,具體代碼就不詳細列出了。
靜態類關系圖:
對象協作圖:
首先,由GLSurfaceViewActivity的實例在onCreate函數中,創建一個GLSurfaceView實例用于顯示繪制OpenglES;
其次,創建一個CubeRenderer的實例,用于渲染Cube對象;
然后,使用GLSurfaceView的setRenderer方法,創建一個GLThread實例。CLThread實例創建一個EglHelper實例初始化opengle環境,并且在run函數中循環運行CubeRender的drawFrame方法;
最后,使用setContentView方法,將GLSurfaceView的實例添加到顯示窗口。
特別需要注意多線程同步問題,由于繪制是由繪制線程處理的,所以當主進程在調用surfaceCreated,surfaceDestroyed,onPause,onResume,onWindowFocusChanged,
onWindowResize,requestExitAndWait,queueEvent,getEvent時,
都會訪問繪制線程,所以這些方法需要使用同步關鍵字synchronized鎖定繪制線程,主線程必需要等待繪制線程執行完相應的方法后,在繼續執行。