diff --git a/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java b/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java index 808cba473c..c6280dd09b 100644 --- a/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java +++ b/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java @@ -49,6 +49,7 @@ import org.cocos2dx.lib.Cocos2dxHelper.Cocos2dxHelperListener; import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLDisplay; +import javax.microedition.khronos.egl.EGLContext; public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelperListener { // =========================================================== @@ -73,158 +74,6 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe public Cocos2dxGLSurfaceView getGLSurfaceView(){ return mGLSurfaceView; } - - public class Cocos2dxEGLConfigChooser implements GLSurfaceView.EGLConfigChooser - { - protected int[] configAttribs; - public Cocos2dxEGLConfigChooser(int redSize, int greenSize, int blueSize, int alphaSize, int depthSize, int stencilSize) - { - configAttribs = new int[] {redSize, greenSize, blueSize, alphaSize, depthSize, stencilSize}; - } - public Cocos2dxEGLConfigChooser(int[] attribs) - { - configAttribs = attribs; - } - - private int findConfigAttrib(EGL10 egl, EGLDisplay display, - EGLConfig config, int attribute, int defaultValue) { - int[] value = new int[1]; - if (egl.eglGetConfigAttrib(display, config, attribute, value)) { - return value[0]; - } - return defaultValue; - } - - class ConfigValue implements Comparable { - - public EGLConfig config = null; - public int[] configAttribs = null; - public int value = 0; - private void calcValue() { - // depth factor 29bit and [6,12)bit - if (configAttribs[4] > 0) { - value = value + (1 << 29) + ((configAttribs[4]%64) << 6); - } - // stencil factor 28bit and [0, 6)bit - if (configAttribs[5] > 0) { - value = value + (1 << 28) + ((configAttribs[5]%64)); - } - // alpha factor 30bit and [24, 28)bit - if (configAttribs[3] > 0) { - value = value + (1 << 30) + ((configAttribs[3]%16) << 24); - } - // green factor [20, 24)bit - if (configAttribs[1] > 0) { - value = value + ((configAttribs[1]%16) << 20); - } - // blue factor [16, 20)bit - if (configAttribs[2] > 0) { - value = value + ((configAttribs[2]%16) << 16); - } - // red factor [12, 16)bit - if (configAttribs[0] > 0) { - value = value + ((configAttribs[0]%16) << 12); - } - } - - public ConfigValue(int[] attribs) { - configAttribs = attribs; - calcValue(); - } - - public ConfigValue(EGL10 egl, EGLDisplay display, EGLConfig config) { - this.config = config; - configAttribs = new int[6]; - configAttribs[0] = findConfigAttrib(egl, display, config, EGL10.EGL_RED_SIZE, 0); - configAttribs[1] = findConfigAttrib(egl, display, config, EGL10.EGL_GREEN_SIZE, 0); - configAttribs[2] = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, 0); - configAttribs[3] = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, 0); - configAttribs[4] = findConfigAttrib(egl, display, config, EGL10.EGL_DEPTH_SIZE, 0); - configAttribs[5] = findConfigAttrib(egl, display, config, EGL10.EGL_STENCIL_SIZE, 0); - calcValue(); - } - - @Override - public int compareTo(ConfigValue another) { - if (value < another.value) { - return -1; - } else if (value > another.value) { - return 1; - } else { - return 0; - } - } - - @Override - public String toString() { - return "{ color: " + configAttribs[3] + configAttribs[2] + configAttribs[1] + configAttribs[0] + - "; depth: " + configAttribs[4] + "; stencil: " + configAttribs[5] + ";}"; - } - } - - @Override - public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) - { - int[] EGLattribs = { - EGL10.EGL_RED_SIZE, configAttribs[0], - EGL10.EGL_GREEN_SIZE, configAttribs[1], - EGL10.EGL_BLUE_SIZE, configAttribs[2], - EGL10.EGL_ALPHA_SIZE, configAttribs[3], - EGL10.EGL_DEPTH_SIZE, configAttribs[4], - EGL10.EGL_STENCIL_SIZE,configAttribs[5], - EGL10.EGL_RENDERABLE_TYPE, 4, //EGL_OPENGL_ES2_BIT - EGL10.EGL_NONE - }; - EGLConfig[] configs = new EGLConfig[1]; - int[] numConfigs = new int[1]; - boolean eglChooseResult = egl.eglChooseConfig(display, EGLattribs, configs, 1, numConfigs); - if (eglChooseResult && numConfigs[0] > 0) - { - return configs[0]; - } - - // there's no config match the specific configAttribs, we should choose a closest one - int[] EGLV2attribs = { - EGL10.EGL_RENDERABLE_TYPE, 4, //EGL_OPENGL_ES2_BIT - EGL10.EGL_NONE - }; - eglChooseResult = egl.eglChooseConfig(display, EGLV2attribs, null, 0, numConfigs); - if(eglChooseResult && numConfigs[0] > 0) { - int num = numConfigs[0]; - ConfigValue[] cfgVals = new ConfigValue[num]; - - // convert all config to ConfigValue - configs = new EGLConfig[num]; - egl.eglChooseConfig(display, EGLV2attribs, configs, num, numConfigs); - for (int i = 0; i < num; ++i) { - cfgVals[i] = new ConfigValue(egl, display, configs[i]); - } - - ConfigValue e = new ConfigValue(configAttribs); - // bin search - int lo = 0; - int hi = num; - int mi; - while (lo < hi - 1) { - mi = (lo + hi) / 2; - if (e.compareTo(cfgVals[mi]) < 0) { - hi = mi; - } else { - lo = mi; - } - } - if (lo != num - 1) { - lo = lo + 1; - } - Log.w("cocos2d", "Can't find EGLConfig match: " + e + ", instead of closest one:" + cfgVals[lo]); - return cfgVals[lo].config; - } - - Log.e(DEVICE_POLICY_SERVICE, "Can not select an EGLConfig for rendering."); - return null; - } - - } public static Context getContext() { return sContext; @@ -410,8 +259,10 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe //this line is need on some device if we specify an alpha bits if(this.mGLContextAttrs[3] > 0) glSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT); + // use custom EGLConfigureChooser and EGLContextFactory Cocos2dxEGLConfigChooser chooser = new Cocos2dxEGLConfigChooser(this.mGLContextAttrs); glSurfaceView.setEGLConfigChooser(chooser); + glSurfaceView.setEGLContextFactory(new ContextFactory()); return glSurfaceView; } @@ -448,7 +299,7 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe } } - private final static boolean isAndroidEmulator() { + private static boolean isAndroidEmulator() { String model = Build.MODEL; Log.d(TAG, "model=" + model); String product = Build.PRODUCT; @@ -464,4 +315,107 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe // =========================================================== // Inner and Anonymous Classes // =========================================================== + + private class Cocos2dxEGLConfigChooser implements GLSurfaceView.EGLConfigChooser + { + private int[] mConfigAttributes; + private final int EGL_OPENGL_ES2_BIT = 0x04; + private final int EGL_OPENGL_ES3_BIT = 0x40; + public Cocos2dxEGLConfigChooser(int redSize, int greenSize, int blueSize, int alphaSize, int depthSize, int stencilSize) + { + mConfigAttributes = new int[] {redSize, greenSize, blueSize, alphaSize, depthSize, stencilSize}; + } + public Cocos2dxEGLConfigChooser(int[] attributes) + { + mConfigAttributes = attributes; + } + + @Override + public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) + { + int[][] EGLAttributes = { + { + // GL ES 3 with user set + EGL10.EGL_RED_SIZE, mConfigAttributes[0], + EGL10.EGL_GREEN_SIZE, mConfigAttributes[1], + EGL10.EGL_BLUE_SIZE, mConfigAttributes[2], + EGL10.EGL_ALPHA_SIZE, mConfigAttributes[3], + EGL10.EGL_DEPTH_SIZE, mConfigAttributes[4], + EGL10.EGL_STENCIL_SIZE,mConfigAttributes[5], + EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT, + EGL10.EGL_NONE + }, + { + // GL ES 3 by default + EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT, + EGL10.EGL_NONE + }, + { + // GL ES 2 with user set + EGL10.EGL_RED_SIZE, mConfigAttributes[0], + EGL10.EGL_GREEN_SIZE, mConfigAttributes[1], + EGL10.EGL_BLUE_SIZE, mConfigAttributes[2], + EGL10.EGL_ALPHA_SIZE, mConfigAttributes[3], + EGL10.EGL_DEPTH_SIZE, mConfigAttributes[4], + EGL10.EGL_STENCIL_SIZE, mConfigAttributes[5], + EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL10.EGL_NONE + }, + { + // GL ES 2 by default + EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL10.EGL_NONE + } + }; + + EGLConfig result = null; + for (int[] eglAtribute : EGLAttributes) { + result = this.doChooseConfig(egl, display, eglAtribute); + if (result != null) + return result; + } + + Log.e(DEVICE_POLICY_SERVICE, "Can not select an EGLConfig for rendering."); + return null; + } + + private EGLConfig doChooseConfig(EGL10 egl, EGLDisplay display, int[] attributes) { + EGLConfig[] configs = new EGLConfig[1]; + int[] matchedConfigNum = new int[1]; + boolean result = egl.eglChooseConfig(display, attributes, configs, 1, matchedConfigNum); + if (result && matchedConfigNum[0] > 0) { + return configs[0]; + } + return null; + } + } + + private static class ContextFactory implements GLSurfaceView.EGLContextFactory { + + private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098; + + public EGLContext createContext( + EGL10 egl, EGLDisplay display, EGLConfig eglConfig) { + + // create GL ES 3 context first, + // if failed, then try to create GL ES 2 context + + int[] attributes = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE }; + // attempt to create a OpenGL ES 3.0 context + EGLContext context = egl.eglCreateContext( + display, eglConfig, EGL10.EGL_NO_CONTEXT, attributes); + + if (context == null) { + attributes = new int[] {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; + context = egl.eglCreateContext( + display, eglConfig, EGL10.EGL_NO_CONTEXT, attributes); + } + + return context; + } + + public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) { + egl.eglDestroyContext(display, context); + } + } } diff --git a/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxGLSurfaceView.java b/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxGLSurfaceView.java index 7238ba4c1d..bd43418426 100644 --- a/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxGLSurfaceView.java +++ b/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxGLSurfaceView.java @@ -94,7 +94,6 @@ public class Cocos2dxGLSurfaceView extends GLSurfaceView { } protected void initView() { - this.setEGLContextClientVersion(2); this.setFocusableInTouchMode(true); Cocos2dxGLSurfaceView.mCocos2dxGLSurfaceView = this; diff --git a/cocos/platform/ios/CCES2Renderer-ios.m b/cocos/platform/ios/CCES2Renderer-ios.m index 4e621359f1..8d2010d234 100644 --- a/cocos/platform/ios/CCES2Renderer-ios.m +++ b/cocos/platform/ios/CCES2Renderer-ios.m @@ -51,13 +51,20 @@ // Create an OpenGL ES 2.0 context - (id) initWithDepthFormat:(unsigned int)depthFormat withPixelFormat:(unsigned int)pixelFormat withSharegroup:(EAGLSharegroup*)sharegroup withMultiSampling:(BOOL) multiSampling withNumberOfSamples:(unsigned int) requestedSamples { - self = [super init]; - if (self) + if (self = [super init]) { - if( ! sharegroup ) - context_ = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + if (! sharegroup) + { + context_ = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]; + if (! context_) + context_ = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; + } else - context_ = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:sharegroup]; + { + context_ = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3 sharegroup:sharegroup]; + if (!context_) + context_ = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:sharegroup]; + } if (!context_ || ![EAGLContext setCurrentContext:context_] ) {