Cocos2d Android移植手记(一) - Opengl ES创建流程

jopen 13年前
     <p>前一阵子,一直在忙公司的iPhone的项目HourglassTimer,顺便了解下iPhone 平台上的2D引擎cocos2d-iphone库的使用。由于一直没有发现android上的基于Opengl ES 2D/3D引擎库(网上只发现了一个java monkey engine项目,pc平台上的游戏引擎。如果有人知道其他的开源项目,非常欢迎告诉我 ),所以自己准备将cocos2d移植到android平台上。 最近做了些初步研究,这里逐步写下来,给自己留个笔记,也希望和大家一起讨论。闲言少叙,直接进入正题。</p>    <p>在android 1.0rc2 sdk中,提供了以下包支持Opengl ES 编程:</p>    <p>一、openglES包</p>    <table border="1" cellspacing="0" cellpadding="0">     <tbody>      <tr>       <td>android.opengl</td>      </tr>      <tr>       <td>Class:</td>       <td><br /> </td>      </tr>      <tr>       <td><br /> </td>       <td>GLDebugHelper:用于调试OpenGL ES程序的帮助类</td>      </tr>      <tr>       <td><br /> </td>       <td>GLU:提供GL 公共工具功能的类</td>      </tr>      <tr>       <td><br /> </td>       <td>GLUtils:连接OpenGL ES和Android API的工具类,其中提供了纹理图片的操作。</td>      </tr>      <tr>       <td><br /> </td>       <td>Matrix:矩阵运算工具类</td>      </tr>      <tr>       <td>Exception:</td>       <td><br /> </td>      </tr>      <tr>       <td><br /> </td>       <td>GLException:OpenGL异常类</td>      </tr>     </tbody>    </table>    <table border="1" cellspacing="0" cellpadding="0">     <tbody>      <tr>       <td>javax.microedition.khronos.egl</td>      </tr>      <tr>       <td>Interface:</td>       <td><br /> </td>      </tr>      <tr>       <td><br /> </td>       <td>EGL:GL的配置接口</td>      </tr>      <tr>       <td><br /> </td>       <td>EGL10:GL1.0的配置接口</td>      </tr>      <tr>       <td><br /> </td>       <td>EGL11:GL1.1的配置接口</td>      </tr>      <tr>       <td>Classes:</td>       <td><br /> </td>      </tr>      <tr>       <td><br /> </td>       <td>EGLConfig:GL配置的类</td>      </tr>      <tr>       <td><br /> </td>       <td>EGLContext:GL运行环境的类</td>      </tr>      <tr>       <td><br /> </td>       <td>EGLDisplay:GL显示窗口的类</td>      </tr>      <tr>       <td><br /> </td>       <td>EGLSurface:可渲染GL的视图类</td>      </tr>      <tr>       <td><br /> </td>       <td><br /> </td>      </tr>     </tbody>    </table>    <table border="1" cellspacing="0" cellpadding="0">     <tbody>      <tr>       <td>javax.microedition.khronos.opengles</td>      </tr>      <tr>       <td>Interfaces:</td>       <td><br /> </td>      </tr>      <tr>       <td><br /> </td>       <td>GL:Opengles的接口</td>      </tr>      <tr>       <td><br /> </td>       <td>GL10:Opengles1.0的接口</td>      </tr>      <tr>       <td><br /> </td>       <td>GL10Ext:Opengles1.0的扩展接口</td>      </tr>      <tr>       <td><br /> </td>       <td>GL11:Opengles1.1的接口</td>      </tr>      <tr>       <td><br /> </td>       <td>GL11Ext:Opengles1.1的扩展接口</td>      </tr>      <tr>       <td><br /> </td>       <td>GLExtentsionPack:Opengles的扩展接口</td>      </tr>      <tr>       <td><br /> </td>       <td>EGLDisplay:GL显示窗口的类</td>      </tr>      <tr>       <td><br /> </td>       <td>EGLSurface:可渲染GL的视图类</td>      </tr>     </tbody>    </table>    <p>二、通常创建流程:</p>    <p>a)创建一个EGL实例</p>    <p>EGL10 mEgl = (EGL10) EGLContext.<em>getEGL</em>();</p>    <p>b)创建一个EGLDisplay实例</p>    <p>EGLDisplay mEglDisplay = mEgl.eglGetDisplay(EGL10.<em>EGL_DEFAULT_DISPLAY</em>);</p>    <p>c)初始化EGLDisplay</p>    <p>mEgl.eglInitialize(mEglDisplay, version);</p>    <p>d)选择Config</p>    <p>mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, num_config);</p>    <p>EGLConfig mEglConfig = configs[0];</p>    <p>e)创建opengl运行环境</p>    <p>EGLContext mEglContext = mEgl.eglCreateContext(       mEglDisplay,</p>    <p>mEglConfig,</p>    <p>EGL10.<em>EGL_NO_CONTEXT</em>,</p>    <p><strong>null</strong>);</p>    <p>f) 创建新surface</p>    <p>mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay,</p>    <p>mEglConfig, holder, <strong>null</strong>);</p>    <p>g) 将opengles环境设置为当前</p>    <p>mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,</p>    <p>mEglContext);</p>    <p>h) 获取当前opengles画布</p>    <p>GL gl = mEglContext.getGL();</p>    <p>i) 显示绘制结果到屏幕上</p>    <p>mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);</p>    <p>三、示例Cube分析</p>    <p>这里简要分析下 google提供的示例代码APIDemos中的Cube的运行结构,具体代码就不详细列出了。</p>    <p>静态类关系图:</p>    <p><a href="https://simg.open-open.com/show/97816a18816e9b32c095a3a90a1c5ed5.jpg" target="_blank"><img style="width:664px;height:271px;cursor:pointer;" title="classes" alt="Cocos2d Android移植手记(一) - Opengl ES创建流程" src="https://simg.open-open.com/show/97816a18816e9b32c095a3a90a1c5ed5.jpg" /></a></p>    <p>对象协作图:</p>    <p><a href="https://simg.open-open.com/show/24fcfeaa3ba05613dc79f8a9980d32f6.jpg" target="_blank"><img style="cursor:pointer;" title="assist" alt="Cocos2d Android移植手记(一) - Opengl ES创建流程" src="https://simg.open-open.com/show/24fcfeaa3ba05613dc79f8a9980d32f6.jpg" width="396" height="504" /></a></p>    <p>首先,由GLSurfaceViewActivity的实例在onCreate函数中,创建一个GLSurfaceView实例用于显示绘制OpenglES;</p>    <p>其次,创建一个CubeRenderer的实例,用于渲染Cube对象;</p>    <p>然后,使用GLSurfaceView的setRenderer方法,创建一个GLThread实例。CLThread实例创建一个EglHelper实例初始化opengle环境,并且在run函数中循环运行CubeRender的drawFrame方法;</p>    <p>最后,使用setContentView方法,将GLSurfaceView的实例添加到显示窗口。</p>    <p>特别需要注意多线程同步问题,由于绘制是由绘制线程处理的,所以当主进程在调用surfaceCreated,surfaceDestroyed,onPause,onResume,onWindowFocusChanged,</p>    <p>onWindowResize,requestExitAndWait,queueEvent,getEvent时,</p>    <p>都会访问绘制线程,所以这些方法需要使用同步关键字<strong>synchronized</strong>锁定绘制线程,主线程必需要等待绘制线程执行完相应的方法后,在继续执行。</p>    <p>文章出处:<a href="/misc/goto?guid=4959500827244287168" rel="nofollow">http://www.moandroid.com/?p=712</a></p>