diff options
author | David 'Digit' Turner <digit@google.com> | 2010-02-19 17:59:50 -0800 |
---|---|---|
committer | David 'Digit' Turner <digit@google.com> | 2010-02-21 12:23:51 -0800 |
commit | f4efa044a061bf159cd6d7b634371b0cde8cb0b7 (patch) | |
tree | e114164afdea77eab4af3aa34a4b600623e303ae /ndk | |
parent | 92210fe14b79481c2f087e24ed6e7a2627cc80f3 (diff) | |
download | android_development-f4efa044a061bf159cd6d7b634371b0cde8cb0b7.tar.gz android_development-f4efa044a061bf159cd6d7b634371b0cde8cb0b7.tar.bz2 android_development-f4efa044a061bf159cd6d7b634371b0cde8cb0b7.zip |
Update hello-gl2 sample to properly implement EGL Config selection.
Also add some comments to explicit what is being done here.
+ add <uses-feature android:glEsVersion="0x00020000"/> to AndroidManifest.xml
Diffstat (limited to 'ndk')
-rw-r--r-- | ndk/apps/hello-gl2/project/AndroidManifest.xml | 1 | ||||
-rw-r--r-- | ndk/apps/hello-gl2/project/src/com/android/gl2jni/GL2JNIView.java | 123 |
2 files changed, 84 insertions, 40 deletions
diff --git a/ndk/apps/hello-gl2/project/AndroidManifest.xml b/ndk/apps/hello-gl2/project/AndroidManifest.xml index 0ef6fb0db..5a4d5f277 100644 --- a/ndk/apps/hello-gl2/project/AndroidManifest.xml +++ b/ndk/apps/hello-gl2/project/AndroidManifest.xml @@ -32,5 +32,6 @@ </intent-filter> </activity> </application> + <uses-feature android:glEsVersion="0x00020000"/> <uses-sdk android:minSdkVersion="5"/> </manifest> diff --git a/ndk/apps/hello-gl2/project/src/com/android/gl2jni/GL2JNIView.java b/ndk/apps/hello-gl2/project/src/com/android/gl2jni/GL2JNIView.java index 72b1dfb9b..060290a76 100644 --- a/ndk/apps/hello-gl2/project/src/com/android/gl2jni/GL2JNIView.java +++ b/ndk/apps/hello-gl2/project/src/com/android/gl2jni/GL2JNIView.java @@ -33,6 +33,7 @@ package com.android.gl2jni; import android.content.Context; +import android.graphics.PixelFormat; import android.opengl.GLSurfaceView; import android.util.AttributeSet; import android.util.Log; @@ -46,16 +47,26 @@ import javax.microedition.khronos.egl.EGLDisplay; import javax.microedition.khronos.opengles.GL10; /** - * An implementation of SurfaceView that uses the dedicated surface for - * displaying an OpenGL animation. This allows the animation to run in a - * separate thread, without requiring that it be driven by the update mechanism - * of the view hierarchy. + * A simple GLSurfaceView sub-class that demonstrate how to perform + * OpenGL ES 2.0 rendering into a GL Surface. Note the following important + * details: * - * The application-specific rendering code is delegated to a GLView.Renderer - * instance. + * - The class must use a custom context factory to enable 2.0 rendering. + * See ContextFactory class definition below. + * + * - The class must use a custom EGLConfigChooser to be able to select + * an EGLConfig that supports 2.0. This is done by providing a config + * specification to eglChooseConfig() that has the attribute + * EGL10.ELG_RENDERABLE_TYPE containing the EGL_OPENGL_ES2_BIT flag + * set. See ConfigChooser class definition below. + * + * - The class must select the surface's format, then choose an EGLConfig + * that matches it exactly (with regards to red/green/blue/alpha channels + * bit depths). Failure to do so would result in an EGL_BAD_MATCH error. */ class GL2JNIView extends GLSurfaceView { private static String TAG = "GL2JNIView"; + private static final boolean DEBUG = false; public GL2JNIView(Context context) { super(context); @@ -68,10 +79,31 @@ class GL2JNIView extends GLSurfaceView { } private void init(boolean translucent, int depth, int stencil) { + + /* By default, GLSurfaceView() creates a RGB_565 opaque surface. + * If we want a translucent one, we should change the surface's + * format here, using PixelFormat.TRANSLUCENT for GL Surfaces + * is interpreted as any 32-bit surface with alpha by SurfaceFlinger. + */ + if (translucent) { + this.getHolder().setFormat(PixelFormat.TRANSLUCENT); + } + + /* Setup the context factory for 2.0 rendering. + * See ContextFactory class definition below + */ setEGLContextFactory(new ContextFactory()); + + /* We need to choose an EGLConfig that matches the format of + * our surface exactly. This is going to be done in our + * custom config chooser. See ConfigChooser class definition + * below. + */ setEGLConfigChooser( translucent ? - new ConfigChooser(8,8,8,8, depth, stencil) : - new ConfigChooser(5,6,5,0, depth, stencil)); + new ConfigChooser(8, 8, 8, 8, depth, stencil) : + new ConfigChooser(5, 6, 5, 0, depth, stencil) ); + + /* Set the renderer responsible for frame rendering */ setRenderer(new Renderer()); } @@ -99,15 +131,6 @@ class GL2JNIView extends GLSurfaceView { } private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser { - private static int EGL_OPENGL_ES2_BIT = 4; - private static int[] s_configAttribs2 = - { - EGL10.EGL_RED_SIZE, 4, - EGL10.EGL_GREEN_SIZE, 4, - EGL10.EGL_BLUE_SIZE, 4, - EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL10.EGL_NONE - }; public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) { mRedSize = r; @@ -118,8 +141,24 @@ class GL2JNIView extends GLSurfaceView { mStencilSize = stencil; } + /* This EGL config specification is used to specify 2.0 rendering. + * We use a minimum size of 4 bits for red/green/blue, but will + * perform actual matching in chooseConfig() below. + */ + private static int EGL_OPENGL_ES2_BIT = 4; + private static int[] s_configAttribs2 = + { + EGL10.EGL_RED_SIZE, 4, + EGL10.EGL_GREEN_SIZE, 4, + EGL10.EGL_BLUE_SIZE, 4, + EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL10.EGL_NONE + }; + public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { + /* Get the number of minimally matching EGL configurations + */ int[] num_config = new int[1]; egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config); @@ -128,41 +167,46 @@ class GL2JNIView extends GLSurfaceView { if (numConfigs <= 0) { throw new IllegalArgumentException("No configs match configSpec"); } + + /* Allocate then read the array of minimally matching EGL configs + */ EGLConfig[] configs = new EGLConfig[numConfigs]; egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config); - // printConfigs(egl, display, configs); + + if (DEBUG) { + printConfigs(egl, display, configs); + } + /* Now return the "best" one + */ return chooseConfig(egl, display, configs); } public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, EGLConfig[] configs) { - EGLConfig closestConfig = null; - int closestDistance = 1000; for(EGLConfig config : configs) { int d = findConfigAttrib(egl, display, config, EGL10.EGL_DEPTH_SIZE, 0); int s = findConfigAttrib(egl, display, config, EGL10.EGL_STENCIL_SIZE, 0); - if (d >= mDepthSize && s>= mStencilSize) { - int r = findConfigAttrib(egl, display, config, - EGL10.EGL_RED_SIZE, 0); - int g = findConfigAttrib(egl, display, config, - EGL10.EGL_GREEN_SIZE, 0); - int b = findConfigAttrib(egl, display, config, - EGL10.EGL_BLUE_SIZE, 0); - int a = findConfigAttrib(egl, display, config, - EGL10.EGL_ALPHA_SIZE, 0); - int distance = Math.abs(r - mRedSize) - + Math.abs(g - mGreenSize) - + Math.abs(b - mBlueSize) - + Math.abs(a - mAlphaSize); - if (distance < closestDistance) { - closestDistance = distance; - closestConfig = config; - } - } + + // We need at least mDepthSize and mStencilSize bits + if (d < mDepthSize || s < mStencilSize) + continue; + + // We want an *exact* match for red/green/blue/alpha + int r = findConfigAttrib(egl, display, config, + EGL10.EGL_RED_SIZE, 0); + int g = findConfigAttrib(egl, display, config, + EGL10.EGL_GREEN_SIZE, 0); + int b = findConfigAttrib(egl, display, config, + EGL10.EGL_BLUE_SIZE, 0); + int a = findConfigAttrib(egl, display, config, + EGL10.EGL_ALPHA_SIZE, 0); + + if (r == mRedSize && g == mGreenSize && b == mBlueSize && a == mAlphaSize) + return config; } - return closestConfig; + return null; } private int findConfigAttrib(EGL10 egl, EGLDisplay display, @@ -293,4 +337,3 @@ class GL2JNIView extends GLSurfaceView { } } } - |