00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 package com.android.gl2jni;
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 import android.content.Context;
00036 import android.graphics.PixelFormat;
00037 import android.opengl.GLSurfaceView;
00038 import android.util.AttributeSet;
00039 import android.util.Log;
00040 import android.view.KeyEvent;
00041 import android.view.MotionEvent;
00042
00043 import java.util.Date;
00044
00045 import javax.microedition.khronos.egl.EGL10;
00046 import javax.microedition.khronos.egl.EGLConfig;
00047 import javax.microedition.khronos.egl.EGLContext;
00048 import javax.microedition.khronos.egl.EGLDisplay;
00049 import javax.microedition.khronos.opengles.GL10;
00050
00069 class GL2JNIView extends GLSurfaceView {
00070 private static String TAG = "GL2JNIView";
00071 private static final boolean DEBUG = false;
00072
00073 public GL2JNIView(Context context) {
00074 super(context);
00075 init(false, 0, 0);
00076 }
00077
00078 public GL2JNIView(Context context, boolean translucent, int depth, int stencil) {
00079 super(context);
00080 init(translucent, depth, stencil);
00081 }
00082
00083 private void init(boolean translucent, int depth, int stencil) {
00084
00085
00086
00087
00088
00089
00090 if (translucent) {
00091 this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
00092 }
00093
00094
00095
00096
00097 setEGLContextFactory(new ContextFactory());
00098
00099
00100
00101
00102
00103
00104 setEGLConfigChooser( translucent ?
00105 new ConfigChooser(8, 8, 8, 8, depth, stencil) :
00106 new ConfigChooser(5, 6, 5, 0, depth, stencil) );
00107
00108
00109 setRenderer(new Renderer());
00110 }
00111
00112 private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
00113 private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
00114 public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
00115 Log.w(TAG, "creating OpenGL ES 2.0 context");
00116 checkEglError("Before eglCreateContext", egl);
00117 int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
00118 EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
00119 checkEglError("After eglCreateContext", egl);
00120 return context;
00121 }
00122
00123 public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
00124 egl.eglDestroyContext(display, context);
00125 }
00126 }
00127
00128 private static void checkEglError(String prompt, EGL10 egl) {
00129 int error;
00130 while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
00131 Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));
00132 }
00133 }
00134
00135 private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser {
00136
00137 public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) {
00138 mRedSize = r;
00139 mGreenSize = g;
00140 mBlueSize = b;
00141 mAlphaSize = a;
00142 mDepthSize = depth;
00143 mStencilSize = stencil;
00144 }
00145
00146
00147
00148
00149
00150 private static int EGL_OPENGL_ES2_BIT = 4;
00151 private static int[] s_configAttribs2 =
00152 {
00153 EGL10.EGL_RED_SIZE, 4,
00154 EGL10.EGL_GREEN_SIZE, 4,
00155 EGL10.EGL_BLUE_SIZE, 4,
00156 EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
00157 EGL10.EGL_NONE
00158 };
00159
00160 public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
00161
00162
00163
00164 int[] num_config = new int[1];
00165 egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config);
00166
00167 int numConfigs = num_config[0];
00168
00169 if (numConfigs <= 0) {
00170 throw new IllegalArgumentException("No configs match configSpec");
00171 }
00172
00173
00174
00175 EGLConfig[] configs = new EGLConfig[numConfigs];
00176 egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config);
00177
00178 if (DEBUG) {
00179 printConfigs(egl, display, configs);
00180 }
00181
00182
00183 return chooseConfig(egl, display, configs);
00184 }
00185
00186 public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
00187 EGLConfig[] configs) {
00188 for(EGLConfig config : configs) {
00189 int d = findConfigAttrib(egl, display, config,
00190 EGL10.EGL_DEPTH_SIZE, 0);
00191 int s = findConfigAttrib(egl, display, config,
00192 EGL10.EGL_STENCIL_SIZE, 0);
00193
00194
00195 if (d < mDepthSize || s < mStencilSize)
00196 continue;
00197
00198
00199 int r = findConfigAttrib(egl, display, config,
00200 EGL10.EGL_RED_SIZE, 0);
00201 int g = findConfigAttrib(egl, display, config,
00202 EGL10.EGL_GREEN_SIZE, 0);
00203 int b = findConfigAttrib(egl, display, config,
00204 EGL10.EGL_BLUE_SIZE, 0);
00205 int a = findConfigAttrib(egl, display, config,
00206 EGL10.EGL_ALPHA_SIZE, 0);
00207
00208 if (r == mRedSize && g == mGreenSize && b == mBlueSize && a == mAlphaSize)
00209 return config;
00210 }
00211 return null;
00212 }
00213
00214 private int findConfigAttrib(EGL10 egl, EGLDisplay display,
00215 EGLConfig config, int attribute, int defaultValue) {
00216
00217 if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
00218 return mValue[0];
00219 }
00220 return defaultValue;
00221 }
00222
00223 private void printConfigs(EGL10 egl, EGLDisplay display,
00224 EGLConfig[] configs) {
00225 int numConfigs = configs.length;
00226 Log.w(TAG, String.format("%d configurations", numConfigs));
00227 for (int i = 0; i < numConfigs; i++) {
00228 Log.w(TAG, String.format("Configuration %d:\n", i));
00229 printConfig(egl, display, configs[i]);
00230 }
00231 }
00232
00233 private void printConfig(EGL10 egl, EGLDisplay display,
00234 EGLConfig config) {
00235 int[] attributes = {
00236 EGL10.EGL_BUFFER_SIZE,
00237 EGL10.EGL_ALPHA_SIZE,
00238 EGL10.EGL_BLUE_SIZE,
00239 EGL10.EGL_GREEN_SIZE,
00240 EGL10.EGL_RED_SIZE,
00241 EGL10.EGL_DEPTH_SIZE,
00242 EGL10.EGL_STENCIL_SIZE,
00243 EGL10.EGL_CONFIG_CAVEAT,
00244 EGL10.EGL_CONFIG_ID,
00245 EGL10.EGL_LEVEL,
00246 EGL10.EGL_MAX_PBUFFER_HEIGHT,
00247 EGL10.EGL_MAX_PBUFFER_PIXELS,
00248 EGL10.EGL_MAX_PBUFFER_WIDTH,
00249 EGL10.EGL_NATIVE_RENDERABLE,
00250 EGL10.EGL_NATIVE_VISUAL_ID,
00251 EGL10.EGL_NATIVE_VISUAL_TYPE,
00252 0x3030,
00253 EGL10.EGL_SAMPLES,
00254 EGL10.EGL_SAMPLE_BUFFERS,
00255 EGL10.EGL_SURFACE_TYPE,
00256 EGL10.EGL_TRANSPARENT_TYPE,
00257 EGL10.EGL_TRANSPARENT_RED_VALUE,
00258 EGL10.EGL_TRANSPARENT_GREEN_VALUE,
00259 EGL10.EGL_TRANSPARENT_BLUE_VALUE,
00260 0x3039,
00261 0x303A,
00262 0x303B,
00263 0x303C,
00264 EGL10.EGL_LUMINANCE_SIZE,
00265 EGL10.EGL_ALPHA_MASK_SIZE,
00266 EGL10.EGL_COLOR_BUFFER_TYPE,
00267 EGL10.EGL_RENDERABLE_TYPE,
00268 0x3042
00269 };
00270 String[] names = {
00271 "EGL_BUFFER_SIZE",
00272 "EGL_ALPHA_SIZE",
00273 "EGL_BLUE_SIZE",
00274 "EGL_GREEN_SIZE",
00275 "EGL_RED_SIZE",
00276 "EGL_DEPTH_SIZE",
00277 "EGL_STENCIL_SIZE",
00278 "EGL_CONFIG_CAVEAT",
00279 "EGL_CONFIG_ID",
00280 "EGL_LEVEL",
00281 "EGL_MAX_PBUFFER_HEIGHT",
00282 "EGL_MAX_PBUFFER_PIXELS",
00283 "EGL_MAX_PBUFFER_WIDTH",
00284 "EGL_NATIVE_RENDERABLE",
00285 "EGL_NATIVE_VISUAL_ID",
00286 "EGL_NATIVE_VISUAL_TYPE",
00287 "EGL_PRESERVED_RESOURCES",
00288 "EGL_SAMPLES",
00289 "EGL_SAMPLE_BUFFERS",
00290 "EGL_SURFACE_TYPE",
00291 "EGL_TRANSPARENT_TYPE",
00292 "EGL_TRANSPARENT_RED_VALUE",
00293 "EGL_TRANSPARENT_GREEN_VALUE",
00294 "EGL_TRANSPARENT_BLUE_VALUE",
00295 "EGL_BIND_TO_TEXTURE_RGB",
00296 "EGL_BIND_TO_TEXTURE_RGBA",
00297 "EGL_MIN_SWAP_INTERVAL",
00298 "EGL_MAX_SWAP_INTERVAL",
00299 "EGL_LUMINANCE_SIZE",
00300 "EGL_ALPHA_MASK_SIZE",
00301 "EGL_COLOR_BUFFER_TYPE",
00302 "EGL_RENDERABLE_TYPE",
00303 "EGL_CONFORMANT"
00304 };
00305 int[] value = new int[1];
00306 for (int i = 0; i < attributes.length; i++) {
00307 int attribute = attributes[i];
00308 String name = names[i];
00309 if ( egl.eglGetConfigAttrib(display, config, attribute, value)) {
00310 Log.w(TAG, String.format(" %s: %d\n", name, value[0]));
00311 } else {
00312
00313 while (egl.eglGetError() != EGL10.EGL_SUCCESS);
00314 }
00315 }
00316 }
00317
00318
00319 protected int mRedSize;
00320 protected int mGreenSize;
00321 protected int mBlueSize;
00322 protected int mAlphaSize;
00323 protected int mDepthSize;
00324 protected int mStencilSize;
00325 private int[] mValue = new int[1];
00326 }
00327
00328 private static class Renderer implements GLSurfaceView.Renderer {
00329 private Date start = new Date();
00330 private int fcount = 0;
00331 public void onDrawFrame(GL10 gl) {
00332
00333 GL2JNILib.step();
00334
00335 fcount++;
00336 if (fcount % 100 == 0) {
00337 double ms = (new Date()).getTime() - start.getTime();
00338 Log.i("GL2JNIVIEW", "fps:" + fcount / (ms / 1000.0));
00339 start = new Date();
00340 fcount = 0;
00341 }
00342
00343 }
00344
00345 public void onSurfaceChanged(GL10 gl, int width, int height) {
00346 GL2JNILib.init(width, height);
00347 }
00348
00349 public void onSurfaceCreated(GL10 gl, EGLConfig config) {
00350
00351 }
00352 }
00353 }