GL2JavaView.java revision 50d0b14689b0ae95ea7b66a8c2f7b955115812dd
150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich/* 250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich * Copyright (C) 2009 The Android Open Source Project 350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich * 450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich * Licensed under the Apache License, Version 2.0 (the "License"); 550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich * you may not use this file except in compliance with the License. 650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich * You may obtain a copy of the License at 750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich * 850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich * http://www.apache.org/licenses/LICENSE-2.0 950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich * 1050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich * Unless required by applicable law or agreed to in writing, software 1150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich * distributed under the License is distributed on an "AS IS" BASIS, 1250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich * See the License for the specific language governing permissions and 1450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich * limitations under the License. 1550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich */ 1650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 1750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevichpackage com.android.gl2java; 1850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 1950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevichimport android.content.Context; 2050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevichimport android.opengl.GLSurfaceView; 2150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevichimport android.util.AttributeSet; 2250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevichimport android.util.Log; 2350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevichimport android.view.KeyEvent; 2450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevichimport android.view.MotionEvent; 2550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 2650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevichimport java.nio.ByteBuffer; 2750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevichimport java.nio.ByteOrder; 2850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevichimport java.nio.FloatBuffer; 2950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 3050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevichimport javax.microedition.khronos.egl.EGL10; 3150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevichimport javax.microedition.khronos.egl.EGLConfig; 3250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevichimport javax.microedition.khronos.egl.EGLContext; 3350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevichimport javax.microedition.khronos.egl.EGLDisplay; 3450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevichimport javax.microedition.khronos.opengles.GL10; 3550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 3650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevichimport android.opengl.GLES20; 3750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 3850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich/** 3950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich * An implementation of SurfaceView that uses the dedicated surface for 4050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich * displaying an OpenGL animation. This allows the animation to run in a 4150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich * separate thread, without requiring that it be driven by the update mechanism 4250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich * of the view hierarchy. 4350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich * 4450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich * The application-specific rendering code is delegated to a GLView.Renderer 4550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich * instance. 4650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich */ 4750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevichclass GL2JavaView extends GLSurfaceView { 4850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private static String TAG = "GL2JavaView"; 4950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 5050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich public GL2JavaView(Context context) { 5150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich super(context); 5250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich init(false, 0, 0); 5350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 5450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 5550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich public GL2JavaView(Context context, boolean translucent, int depth, int stencil) { 5650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich super(context); 5750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich init(translucent, depth, stencil); 5850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 5950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 6050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private void init(boolean translucent, int depth, int stencil) { 6150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich setEGLContextFactory(new ContextFactory()); 6250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich setEGLConfigChooser( translucent ? 6350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich new ConfigChooser(8,8,8,8, depth, stencil) : 6450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich new ConfigChooser(5,6,5,0, depth, stencil)); 6550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich setRenderer(new Renderer()); 6650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 6750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 6850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private static class ContextFactory implements GLSurfaceView.EGLContextFactory { 6950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098; 7050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) { 7150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich Log.w(TAG, "creating OpenGL ES 2.0 context"); 7250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich checkEglError("Before eglCreateContext", egl); 7350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; 7450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list); 7550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich checkEglError("After eglCreateContext", egl); 7650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich return context; 7750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 7850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 7950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) { 8050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich egl.eglDestroyContext(display, context); 8150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 8250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 8350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 8450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private static void checkEglError(String prompt, EGL10 egl) { 8550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int error; 8650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) { 8750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error)); 8850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 8950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 9050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 9150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser { 9250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private static int EGL_OPENGL_ES2_BIT = 4; 9350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private static int[] s_configAttribs2 = 9450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich { 9550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_RED_SIZE, 4, 9650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_GREEN_SIZE, 4, 9750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_BLUE_SIZE, 4, 9850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 9950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_NONE 10050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich }; 10150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 10250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) { 10350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich mRedSize = r; 10450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich mGreenSize = g; 10550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich mBlueSize = b; 10650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich mAlphaSize = a; 10750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich mDepthSize = depth; 10850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich mStencilSize = stencil; 10950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 11050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 11150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { 11250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 11350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int[] num_config = new int[1]; 11450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config); 11550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 11650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int numConfigs = num_config[0]; 11750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 11850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (numConfigs <= 0) { 11950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich throw new IllegalArgumentException("No configs match configSpec"); 12050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 12150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGLConfig[] configs = new EGLConfig[numConfigs]; 12250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config); 12350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich // printConfigs(egl, display, configs); 12450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich return chooseConfig(egl, display, configs); 12550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 12650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 12750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, 12850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGLConfig[] configs) { 12950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGLConfig closestConfig = null; 13050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int closestDistance = 1000; 13150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich for(EGLConfig config : configs) { 13250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int d = findConfigAttrib(egl, display, config, 13350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_DEPTH_SIZE, 0); 13450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int s = findConfigAttrib(egl, display, config, 13550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_STENCIL_SIZE, 0); 13650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (d >= mDepthSize && s>= mStencilSize) { 13750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int r = findConfigAttrib(egl, display, config, 13850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_RED_SIZE, 0); 13950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int g = findConfigAttrib(egl, display, config, 14050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_GREEN_SIZE, 0); 14150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int b = findConfigAttrib(egl, display, config, 14250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_BLUE_SIZE, 0); 14350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int a = findConfigAttrib(egl, display, config, 14450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_ALPHA_SIZE, 0); 14550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int distance = Math.abs(r - mRedSize) 14650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich + Math.abs(g - mGreenSize) 14750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich + Math.abs(b - mBlueSize) 14850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich + Math.abs(a - mAlphaSize); 14950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (distance < closestDistance) { 15050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich closestDistance = distance; 15150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich closestConfig = config; 15250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 15350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 15450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 15550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich return closestConfig; 15650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 15750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 15850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private int findConfigAttrib(EGL10 egl, EGLDisplay display, 15950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGLConfig config, int attribute, int defaultValue) { 16050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 16150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) { 16250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich return mValue[0]; 16350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 16450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich return defaultValue; 16550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 16650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 16750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private void printConfigs(EGL10 egl, EGLDisplay display, 16850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGLConfig[] configs) { 16950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int numConfigs = configs.length; 17050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich Log.w(TAG, String.format("%d configurations", numConfigs)); 17150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich for (int i = 0; i < numConfigs; i++) { 17250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich Log.w(TAG, String.format("Configuration %d:\n", i)); 17350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich printConfig(egl, display, configs[i]); 17450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 17550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 17650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 17750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private void printConfig(EGL10 egl, EGLDisplay display, 17850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGLConfig config) { 17950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int[] attributes = { 18050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_BUFFER_SIZE, 18150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_ALPHA_SIZE, 18250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_BLUE_SIZE, 18350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_GREEN_SIZE, 18450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_RED_SIZE, 18550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_DEPTH_SIZE, 18650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_STENCIL_SIZE, 18750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_CONFIG_CAVEAT, 18850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_CONFIG_ID, 18950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_LEVEL, 19050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_MAX_PBUFFER_HEIGHT, 19150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_MAX_PBUFFER_PIXELS, 19250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_MAX_PBUFFER_WIDTH, 19350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_NATIVE_RENDERABLE, 19450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_NATIVE_VISUAL_ID, 19550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_NATIVE_VISUAL_TYPE, 19650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 0x3030, // EGL10.EGL_PRESERVED_RESOURCES, 19750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_SAMPLES, 19850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_SAMPLE_BUFFERS, 19950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_SURFACE_TYPE, 20050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_TRANSPARENT_TYPE, 20150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_TRANSPARENT_RED_VALUE, 20250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_TRANSPARENT_GREEN_VALUE, 20350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_TRANSPARENT_BLUE_VALUE, 20450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB, 20550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA, 20650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL, 20750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL, 20850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_LUMINANCE_SIZE, 20950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_ALPHA_MASK_SIZE, 21050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_COLOR_BUFFER_TYPE, 21150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich EGL10.EGL_RENDERABLE_TYPE, 21250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 0x3042 // EGL10.EGL_CONFORMANT 21350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich }; 21450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich String[] names = { 21550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_BUFFER_SIZE", 21650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_ALPHA_SIZE", 21750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_BLUE_SIZE", 21850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_GREEN_SIZE", 21950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_RED_SIZE", 22050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_DEPTH_SIZE", 22150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_STENCIL_SIZE", 22250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_CONFIG_CAVEAT", 22350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_CONFIG_ID", 22450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_LEVEL", 22550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_MAX_PBUFFER_HEIGHT", 22650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_MAX_PBUFFER_PIXELS", 22750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_MAX_PBUFFER_WIDTH", 22850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_NATIVE_RENDERABLE", 22950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_NATIVE_VISUAL_ID", 23050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_NATIVE_VISUAL_TYPE", 23150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_PRESERVED_RESOURCES", 23250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_SAMPLES", 23350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_SAMPLE_BUFFERS", 23450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_SURFACE_TYPE", 23550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_TRANSPARENT_TYPE", 23650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_TRANSPARENT_RED_VALUE", 23750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_TRANSPARENT_GREEN_VALUE", 23850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_TRANSPARENT_BLUE_VALUE", 23950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_BIND_TO_TEXTURE_RGB", 24050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_BIND_TO_TEXTURE_RGBA", 24150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_MIN_SWAP_INTERVAL", 24250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_MAX_SWAP_INTERVAL", 24350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_LUMINANCE_SIZE", 24450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_ALPHA_MASK_SIZE", 24550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_COLOR_BUFFER_TYPE", 24650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_RENDERABLE_TYPE", 24750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich "EGL_CONFORMANT" 24850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich }; 24950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int[] value = new int[1]; 25050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich for (int i = 0; i < attributes.length; i++) { 25150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int attribute = attributes[i]; 25250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich String name = names[i]; 25350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if ( egl.eglGetConfigAttrib(display, config, attribute, value)) { 25450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich Log.w(TAG, String.format(" %s: %d\n", name, value[0])); 25550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } else { 25650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich // Log.w(TAG, String.format(" %s: failed\n", name)); 25750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich while (egl.eglGetError() != EGL10.EGL_SUCCESS); 25850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 25950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 26050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 26150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 26250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich // Subclasses can adjust these values: 26350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich protected int mRedSize; 26450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich protected int mGreenSize; 26550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich protected int mBlueSize; 26650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich protected int mAlphaSize; 26750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich protected int mDepthSize; 26850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich protected int mStencilSize; 26950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private int[] mValue = new int[1]; 27050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 27150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 27250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private static class Renderer implements GLSurfaceView.Renderer { 27350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 27450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich public Renderer() { 27550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich mTriangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length * 4) 27650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich .order(ByteOrder.nativeOrder()).asFloatBuffer(); 27750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich mTriangleVertices.put(mTriangleVerticesData).position(0); 27850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 27950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 28050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich public void onDrawFrame(GL10 gl) { 28150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glClearColor(0.0f, 0.0f, 1.0f, 1.0f); 28250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); 28350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glUseProgram(mProgram); 28450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich checkGlError("glUseProgram"); 28550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 28650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glVertexAttribPointer(mvPositionHandle, 2, GLES20.GL_FLOAT, false, 0, mTriangleVertices); 28750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich checkGlError("glVertexAttribPointer"); 28850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glEnableVertexAttribArray(mvPositionHandle); 28950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich checkGlError("glEnableVertexAttribArray"); 29050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3); 29150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich checkGlError("glDrawArrays"); 29250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 29350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 29450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 29550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich public void onSurfaceChanged(GL10 gl, int width, int height) { 29650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glViewport(0, 0, width, height); 29750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 29850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 29950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich public void onSurfaceCreated(GL10 gl, EGLConfig config) { 30050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich mProgram = createProgram(mVertexShader, mFragmentShader); 30150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (mProgram == 0) { 30250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich return; 30350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 30450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich mvPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition"); 30550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich checkGlError("glGetAttribLocation"); 30650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (mvPositionHandle == -1) { 30750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich throw new RuntimeException("Could not get attrib location for vPosition"); 30850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 30950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 31050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 31150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private int loadShader(int shaderType, String source) { 31250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int shader = GLES20.glCreateShader(shaderType); 31350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (shader != 0) { 31450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glShaderSource(shader, source); 31550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glCompileShader(shader); 31650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int[] compiled = new int[1]; 31750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0); 31850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (compiled[0] == 0) { 31950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich Log.e(TAG, "Could not compile shader " + shaderType + ":"); 32050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich Log.e(TAG, GLES20.glGetShaderInfoLog(shader)); 32150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glDeleteShader(shader); 32250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich shader = 0; 32350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 32450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 32550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich return shader; 32650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 32750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 32850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private int createProgram(String vertexSource, String fragmentSource) { 32950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource); 33050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (vertexShader == 0) { 33150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich return 0; 33250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 33350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 33450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource); 33550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (pixelShader == 0) { 33650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich return 0; 33750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 33850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 33950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int program = GLES20.glCreateProgram(); 34050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (program != 0) { 34150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glAttachShader(program, vertexShader); 34250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich checkGlError("glAttachShader"); 34350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glAttachShader(program, pixelShader); 34450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich checkGlError("glAttachShader"); 34550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glLinkProgram(program); 34650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int[] linkStatus = new int[1]; 34750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0); 34850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (linkStatus[0] != GLES20.GL_TRUE) { 34950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich Log.e(TAG, "Could not link program: "); 35050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich Log.e(TAG, GLES20.glGetProgramInfoLog(program)); 35150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glDeleteProgram(program); 35250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich program = 0; 35350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 35450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 35550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich return program; 35650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 35750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 35850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private void checkGlError(String op) { 35950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int error; 36050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { 36150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich Log.e(TAG, op + ": glError " + error); 36250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich throw new RuntimeException(op + ": glError " + error); 36350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 36450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 36550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 36650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private final float[] mTriangleVerticesData = { 0.0f, 0.5f, -0.5f, -0.5f, 36750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 0.5f, -0.5f }; 36850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 36950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private FloatBuffer mTriangleVertices; 37050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 37150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private final String mVertexShader = "attribute vec4 vPosition;\n" 37250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich + "void main() {\n" 37350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich + " gl_Position = vPosition;\n" 37450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich + "}\n"; 37550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 37650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private final String mFragmentShader = "precision mediump float;\n" 37750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich + "void main() {\n" 37850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich + " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n" 37950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich + "}\n"; 38050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 38150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private int mProgram; 38250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private int mvPositionHandle; 38350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 38450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 38550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich} 38650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 387