andEngine结构:
双线程:业务线程、渲染线程,使用ReentrantLock实现两个线程的交替执行。
渲染线程:使用GLSurfaceView提供的渲染功能,内置渲染绘图线程。
第一步:RenderSurfaceView为继承于GLSurfaceView的GL渲染视图,BaseGameActivity作为继承于Activity的活动,通过setContentView(RenderSurfaceView)将视图加入活动中。
BaseGameActivity中主要方法:
@Override protected void onCreate(final Bundle pSavedInstanceState) { if(BuildConfig.DEBUG) { Debug.d(this.getClass().getSimpleName() + ".onCreate" + " @(Thread: '" + Thread.currentThread().getName() + "')"); } super.onCreate(pSavedInstanceState); //先处于暂停状态 this.mGamePaused = true; //通过EngineOption定义,创建Engine this.mEngine = this.onCreateEngine(this.onCreateEngineOptions()); //应用EngineOption定义到Activity this.applyEngineOptions(); //添加RenderSurfaceView到Activity this.onSetContentView(); } protected void onSetContentView() { this.mRenderSurfaceView = new RenderSurfaceView(this); this.mRenderSurfaceView.setRenderer(this.mEngine, this); this.setContentView(this.mRenderSurfaceView, BaseGameActivity.createSurfaceViewLayoutParams()); }
第二步:将渲染器EngineRenderer的加入RenderSurfaceView中,BaseGameActivity实现IRendererListener接口监听EngineRenderer。
EngineRenderer中的主要方法:
@Override public void onSurfaceCreated(final GL10 pGL, final EGLConfig pEGLConfig) { synchronized(GLState.class) { final RenderOptions renderOptions = this.mEngine.getEngineOptions().getRenderOptions(); this.mGLState.reset(renderOptions, this.mConfigChooser, pEGLConfig); // TODO Check if available and make available through EngineOptions-RenderOptions // GLES20.glEnable(GLES20.GL_POLYGON_SMOOTH); // GLES20.glHint(GLES20.GL_POLYGON_SMOOTH_HINT, GLES20.GL_NICEST); // GLES20.glEnable(GLES20.GL_LINE_SMOOTH); // GLES20.glHint(GLES20.GL_LINE_SMOOTH_HINT, GLES20.GL_NICEST); // GLES20.glEnable(GLES20.GL_POINT_SMOOTH); // GLES20.glHint(GLES20.GL_POINT_SMOOTH_HINT, GLES20.GL_NICEST); //2D不需要深度 this.mGLState.disableDepthTest(); this.mGLState.enableBlend(); this.mGLState.setDitherEnabled(renderOptions.isDithering()); /* Enabling culling doesn't really make sense, because triangles are never drawn 'backwards' on purpose. */ // this.mGLState.enableCulling(); // GLES20.glFrontFace(GLES20.GL_CCW); // GLES20.glCullFace(GLES20.GL_BACK); //回调BaseGameActivity中onSurfaceCreated if(this.mRendererListener != null) { this.mRendererListener.onSurfaceCreated(this.mGLState); } } } @Override public void onSurfaceChanged(final GL10 pGL, final int pWidth, final int pHeight) { //确定因为和GL的显示区域大小 this.mEngine.setSurfaceSize(pWidth, pHeight); GLES20.glViewport(0, 0, pWidth, pHeight); this.mGLState.loadProjectionGLMatrixIdentity(); //回调BaseGameActivity中onSurfaceChanged if(this.mRendererListener != null) { this.mRendererListener.onSurfaceChanged(this.mGLState, pWidth, pHeight); } } @Override public void onDrawFrame(final GL10 pGL) { synchronized(GLState.class) { if (this.mMultiSampling && this.mConfigChooser.isCoverageMultiSampling()) { final int GL_COVERAGE_BUFFER_BIT_NV = 0x8000; GLES20.glClear(GL_COVERAGE_BUFFER_BIT_NV); } try { //调用引擎中的方法 this.mEngine.onDrawFrame(this.mGLState); } catch (final InterruptedException e) { Debug.e("GLThread interrupted!", e); } } }
Engine中的主要方法:
public void onDrawFrame(final GLState pGLState) throws InterruptedException { final EngineLock engineLock = this.mEngineLock; //绘制过程中为引擎加锁,等待绘制完成 engineLock.lock(); try { engineLock.waitUntilCanDraw(); //更新顶点缓存,去除Unloaded的缓存 this.mVertexBufferObjectManager.updateVertexBufferObjects(pGLState); //更新纹理,加载纹理到硬件 this.mTextureManager.updateTextures(pGLState); //更新字体,绘制所有文字 this.mFontManager.updateFonts(pGLState); //调用mDrawHandlers中注册的所有需要绘制的IDrawHandler的onDraw方法 this.onUpdateDrawHandlers(pGLState, this.mCamera); //逐层调用Scene中IEntity的onDraw方法 this.onDrawScene(pGLState, this.mCamera); engineLock.notifyCanUpdate(); } finally { engineLock.unlock(); } }
业务线程:Engine的初始化函数中启动业务执行线程UpdateThread,为注册到引擎中、或注册到引擎包含的实体中的IUpdateHandler接口执行onUpdate()方法,完成业务的更新操作。
UpdateThread中主要方法:
@Override public void run() { android.os.Process.setThreadPriority(this.mEngine.getEngineOptions().getUpdateThreadPriority()); try { while(true) { this.mRunnableHandler.onUpdate(0); this.mEngine.onTickUpdate(); } } catch (final InterruptedException e) { if(BuildConfig.DEBUG) { Debug.d(this.getClass().getSimpleName() + " interrupted. Don't worry - this " + e.getClass().getSimpleName() + " is most likely expected!", e); } this.interrupt(); } }
Engine中的主要方法:
void onTickUpdate() throws InterruptedException { //如果引擎正在运行,更新所有IUpdateHandler,否则Thread.sleep(16);什么也不做 if(this.mRunning) { //从上传更新已经度过的时间(毫秒) final long secondsElapsed = this.getNanosecondsElapsed(); this.mEngineLock.lock(); try { //如果引擎已经被摧毁,抛出EngineDestroyedException异常 this.throwOnDestroyed(); //更新业务 this.onUpdate(secondsElapsed); //如果引擎已经被摧毁,抛出EngineDestroyedException异常 this.throwOnDestroyed(); this.mEngineLock.notifyCanDraw(); this.mEngineLock.waitUntilCanUpdate(); } finally { this.mEngineLock.unlock(); } } else { this.mEngineLock.lock(); try { this.throwOnDestroyed(); this.mEngineLock.notifyCanDraw(); this.mEngineLock.waitUntilCanUpdate(); } finally { this.mEngineLock.unlock(); } Thread.sleep(16); } } public void onUpdate(final long pNanosecondsElapsed) throws InterruptedException { final float pSecondsElapsed = pNanosecondsElapsed * TimeConstants.SECONDS_PER_NANOSECOND; this.mSecondsElapsedTotal += pSecondsElapsed; this.mLastTick += pNanosecondsElapsed; //更新触摸事件控制 this.mTouchController.onUpdate(pSecondsElapsed); //更新注册的IUpdateHandler this.onUpdateUpdateHandlers(pSecondsElapsed); //更新屏幕 this.onUpdateScene(pSecondsElapsed); }
Entity中的主要方法:
@Override public final void onUpdate(final float pSecondsElapsed) { if(!this.mIgnoreUpdate) { this.onManagedUpdate(pSecondsElapsed); } } /** * 对实体的onUpdate方法的实际处理函数 * * @param pSecondsElapsed 间隔秒数 */ protected void onManagedUpdate(final float pSecondsElapsed) { //本身注册的实体修改器的onUpdate if(this.mEntityModifiers != null) { this.mEntityModifiers.onUpdate(pSecondsElapsed); } //本身注册IUpdateHandler对象的onUpdate if(this.mUpdateHandlers != null) { this.mUpdateHandlers.onUpdate(pSecondsElapsed); } //调用子实体的onUpdate方法 if((this.mChildren != null) && !this.mChildrenIgnoreUpdate) { final SmartList<IEntity> entities = this.mChildren; final int entityCount = entities.size(); for(int i = 0; i < entityCount; i++) { entities.get(i).onUpdate(pSecondsElapsed); } } }
andEngine继承关系: