其参数对性能影响极大,下面的代码在同样的Android设备上运行,其fps变化相当大。
注:FrameBuffer Resolution为1080P。
public class Demo2 extends Cocos2dxActivity{ protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); } public Cocos2dxGLSurfaceView onCreateView() { Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this); // Demo2 should create stencil buffer //glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8); // fps: 56 glSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0); // fps: 41 return glSurfaceView; } static { System.loadLibrary("cocos2dcpp"); } }
前提条件为:glSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
Theme.Translucent: FPS(12.6)
Theme.NoTitleBar.Fullscreen: FPS(41)
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.test.game2" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="8"/> <uses-feature android:glEsVersion="0x00020000" /> <application android:label="@string/app_name" android:icon="@drawable/icon"> <activity android:name=".Demo2" android:label="@string/app_name" android:screenOrientation="landscape" ###android:theme="@android:style/Theme.Translucent" ###fps:12.6 android:theme="@android:style/Theme.NoTitleBar.Fullscreen" ###fps:41 android:configChanges="orientation"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <supports-screens android:largeScreens="true" android:smallScreens="true" android:anyDensity="true" android:normalScreens="true"/> <uses-permission android:name="android.permission.INTERNET"/> </manifest>
背景层:Video
前景层:3D (其背景透明)
其主要功能为:
1) 增加一个SurfaceView用于显示Video,其代码如下:
public SurfaceView mediaPlayView; //成员变量,可供其子类访问
mediaPlayView = new SurfaceView(this);
framelayout.addView(mediaPlayView);
2) 使GLSurfaceView背景透明并置于前景,其代码如下:
this.mGLSurfaceView.setEGLConfigChooser(8 , 8, 8, 8, 16, 0);
this.mGLSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
this.mGLSurfaceView.setZOrderOnTop(true);
相关关键代码如下:
import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.graphics.PixelFormat; public void init() { // FrameLayout ViewGroup.LayoutParams framelayout_params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT); FrameLayout framelayout = new FrameLayout(this); framelayout.setLayoutParams(framelayout_params); // Cocos2dxEditText layout ViewGroup.LayoutParams edittext_layout_params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); Cocos2dxEditText edittext = new Cocos2dxEditText(this); edittext.setLayoutParams(edittext_layout_params); // ...add to FrameLayout framelayout.addView(edittext); // Added by Luoxx for video player on 2014-2-25 mediaPlayView = new SurfaceView(this); framelayout.addView(mediaPlayView); // Cocos2dxGLSurfaceView this.mGLSurfaceView = this.onCreateView(); // ...add to FrameLayout framelayout.addView(this.mGLSurfaceView); // Switch to supported OpenGL (ARGB888) mode on emulator if (isAndroidEmulator()) this.mGLSurfaceView.setEGLConfigChooser(8 , 8, 8, 8, 16, 0); // Added by Luoxx on 2014-2-25 this.mGLSurfaceView.setEGLConfigChooser(8 , 8, 8, 8, 16, 0); this.mGLSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT); this.mGLSurfaceView.setZOrderOnTop(true); this.mGLSurfaceView.setCocos2dxRenderer(new Cocos2dxRenderer()); this.mGLSurfaceView.setCocos2dxEditText(edittext); // Set framelayout as the content view setContentView(framelayout); }
其主要功能为:进行视频播放,其完整代码如下:
package com.test.game2; import org.cocos2dx.lib.Cocos2dxActivity; import org.cocos2dx.lib.Cocos2dxGLSurfaceView; import android.os.Bundle; // Added by Luoxx for video player import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.media.MediaPlayer; import android.util.Log; import java.io.IOException; public class Demo2 extends Cocos2dxActivity{ private static final String TAG="MyMP"; private SurfaceHolder mediaSurfaceHolder = null; private MediaPlayer mediaPlayer; private boolean isMediaPlay = false; protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); initVideo(); } public Cocos2dxGLSurfaceView onCreateView() { Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this); // Demo2 should create stencil buffer glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8); return glSurfaceView; } static { System.loadLibrary("cocos2dcpp"); } private void initVideo(){ mediaSurfaceHolder = mediaPlayView.getHolder(); mediaSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); mediaSurfaceHolder.addCallback(new MediaSurfaceHolderCallBack()); } MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { Log.d(TAG,"onPrepared..."); int mVideoWidth = 0; int mVideoHeight = 0; mVideoWidth = mp.getVideoWidth(); mVideoHeight = mp.getVideoHeight(); mediaSurfaceHolder.setFixedSize(mVideoWidth, mVideoHeight); mp.start(); isMediaPlay = true; // test /* try{ // startup Get Pos Thread mPosThread = new GetPosThread(); mPosThread.start(); } catch (Exception e) { e.printStackTrace(); }*/ } }; private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() { public void onCompletion(MediaPlayer mp) { Log.d(TAG,"onCompletion..."); //isMediaPlay = false; mp.seekTo(0); mp.start(); } }; private class MediaSurfaceHolderCallBack implements SurfaceHolder.Callback{ @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Log.d(TAG,"surfaceChanged...,width="+width+", height="+height); } @Override public void surfaceCreated(SurfaceHolder holder) { Log.d(TAG,"surfaceCreated..."); mediaPlayer = new MediaPlayer(); mediaPlayer.setOnPreparedListener(mPreparedListener); mediaPlayer.setOnCompletionListener(mCompletionListener); try { mediaPlayer.setDataSource("/sdcard/NativeMedia.ts"); //mediaPlayer.setDataSource("/sdcard/video/aoa.mp4"); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } mediaPlayer.setDisplay(mediaSurfaceHolder); try { mediaPlayer.prepareAsync(); } catch (IllegalStateException e) { e.printStackTrace(); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { if( mediaPlayer.isPlaying() ){ mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer = null; } if( mediaSurfaceHolder != null ){ mediaSurfaceHolder = null; } } } }
在render每一帧之前,调用glClearColor(0.0f,0.0f,0.0f,0.0f); 以使3D层透明,其详细代码如下:
// Draw the Scene void CCDirector::drawScene(void) { // calculate "global" dt calculateDeltaTime(); //tick before glClear: issue #533 if (! m_bPaused) { m_pScheduler->update(m_fDeltaTime); } glClearColor(0.0f,0.0f,0.0f,0.0f); // add it to make 3D transparent glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* to avoid flickr, nextScene MUST be here: after tick and before draw. XXX: Which bug is this one. It seems that it can't be reproduced with v0.9 */ if (m_pNextScene) { setNextScene(); } kmGLPushMatrix(); // draw the scene if (m_pRunningScene) { m_pRunningScene->visit(); } // draw the notifications node if (m_pNotificationNode) { m_pNotificationNode->visit(); } if (m_bDisplayStats) { showStats(); } kmGLPopMatrix(); m_uTotalFrames++; // swap buffers if (m_pobOpenGLView) { m_pobOpenGLView->swapBuffers(); } if (m_bDisplayStats) { calculateMPF(); } }
或如下代码:
void CCDirector::setGLDefaultValues(void) { // This method SHOULD be called only after openGLView_ was initialized CCAssert(m_pobOpenGLView, "opengl view should not be null"); setAlphaBlending(true); // XXX: Fix me, should enable/disable depth test according the depth format as cocos2d-iphone did // [self setDepthTest: view_.depthFormat]; setDepthTest(false); setProjection(m_eProjection); // set other opengl default values //glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // to make 3D Layer transparent }