1. 性能影响分析
1.1 setEGLConfigChooser
其参数对性能影响极大,下面的代码在同样的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");
}
}
1.2 android:theme对fps的影响
前提条件为: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>
2. Video+3D
背景层:Video
前景层:3D (其背景透明)
2.1 Cocos2dxActivity.java
其主要功能为:
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);
}
2.2 Demo2.java
其主要功能为:进行视频播放,其完整代码如下:
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;
}
}
}
}
2.3 CCDirector.cpp
在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
}