GL2JavaView.java revision 560814f6b11abe83ff0c4ed18cac015c276b3181
1560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich/*
2560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich * Copyright (C) 2009 The Android Open Source Project
3560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich *
4560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich * Licensed under the Apache License, Version 2.0 (the "License");
5560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich * you may not use this file except in compliance with the License.
6560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich * You may obtain a copy of the License at
7560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich *
8560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich *      http://www.apache.org/licenses/LICENSE-2.0
9560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich *
10560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich * Unless required by applicable law or agreed to in writing, software
11560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich * distributed under the License is distributed on an "AS IS" BASIS,
12560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich * See the License for the specific language governing permissions and
14560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich * limitations under the License.
15560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich */
16560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
17560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevichpackage com.android.gl2java;
18560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
19560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevichimport android.content.Context;
20560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevichimport android.opengl.GLSurfaceView;
21560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevichimport android.util.AttributeSet;
22560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevichimport android.util.Log;
23560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevichimport android.view.KeyEvent;
24560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevichimport android.view.MotionEvent;
25560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
26560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevichimport java.nio.ByteBuffer;
27560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevichimport java.nio.ByteOrder;
28560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevichimport java.nio.FloatBuffer;
29560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
30560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevichimport javax.microedition.khronos.egl.EGL10;
31560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevichimport javax.microedition.khronos.egl.EGLConfig;
32560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevichimport javax.microedition.khronos.egl.EGLContext;
33560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevichimport javax.microedition.khronos.egl.EGLDisplay;
34560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevichimport javax.microedition.khronos.opengles.GL10;
35560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
36560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevichimport android.opengl.GLES20;
37560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
38560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich/**
39560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich * An implementation of SurfaceView that uses the dedicated surface for
40560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich * displaying an OpenGL animation.  This allows the animation to run in a
41560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich * separate thread, without requiring that it be driven by the update mechanism
42560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich * of the view hierarchy.
43560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich *
44560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich * The application-specific rendering code is delegated to a GLView.Renderer
45560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich * instance.
46560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich */
47560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevichclass GL2JavaView extends GLSurfaceView {
48560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich    private static String TAG = "GL2JavaView";
49560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
50560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich    public GL2JavaView(Context context) {
51560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        super(context);
52560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        init(false, 0, 0);
53560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich    }
54560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
55560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich    public GL2JavaView(Context context, boolean translucent, int depth, int stencil) {
56560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        super(context);
57560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        init(translucent, depth, stencil);
58560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich    }
59560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
60560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich    private void init(boolean translucent, int depth, int stencil) {
61560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        setEGLContextFactory(new ContextFactory());
62560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        setEGLConfigChooser( translucent ?
63560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich              new ConfigChooser(8,8,8,8, depth, stencil) :
64560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich              new ConfigChooser(5,6,5,0, depth, stencil));
65560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        setRenderer(new Renderer());
66560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich    }
67560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
68560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich    private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
69560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
70560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
71560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            Log.w(TAG, "creating OpenGL ES 2.0 context");
72560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            checkEglError("Before eglCreateContext", egl);
73560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
74560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
75560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            checkEglError("After eglCreateContext", egl);
76560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            return context;
77560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
78560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
79560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
80560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            egl.eglDestroyContext(display, context);
81560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
82560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich    }
83560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
84560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich    private static void checkEglError(String prompt, EGL10 egl) {
85560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        int error;
86560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
87560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));
88560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
89560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich    }
90560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
91560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich    private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser {
92560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private static int EGL_OPENGL_ES2_BIT = 4;
93560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private static int[] s_configAttribs2 =
94560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        {
95560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            EGL10.EGL_RED_SIZE, 4,
96560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            EGL10.EGL_GREEN_SIZE, 4,
97560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            EGL10.EGL_BLUE_SIZE, 4,
98560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
99560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            EGL10.EGL_NONE
100560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        };
101560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
102560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) {
103560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            mRedSize = r;
104560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            mGreenSize = g;
105560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            mBlueSize = b;
106560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            mAlphaSize = a;
107560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            mDepthSize = depth;
108560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            mStencilSize = stencil;
109560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
110560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
111560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
112560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
113560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            int[] num_config = new int[1];
114560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config);
115560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
116560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            int numConfigs = num_config[0];
117560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
118560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            if (numConfigs <= 0) {
119560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                throw new IllegalArgumentException("No configs match configSpec");
120560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            }
121560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            EGLConfig[] configs = new EGLConfig[numConfigs];
122560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config);
123560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            // printConfigs(egl, display, configs);
124560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            return chooseConfig(egl, display, configs);
125560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
126560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
127560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
128560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                EGLConfig[] configs) {
129560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            EGLConfig closestConfig = null;
130560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            int closestDistance = 1000;
131560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            for(EGLConfig config : configs) {
132560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                int d = findConfigAttrib(egl, display, config,
133560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                        EGL10.EGL_DEPTH_SIZE, 0);
134560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                int s = findConfigAttrib(egl, display, config,
135560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                        EGL10.EGL_STENCIL_SIZE, 0);
136560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                if (d >= mDepthSize && s>= mStencilSize) {
137560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    int r = findConfigAttrib(egl, display, config,
138560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                            EGL10.EGL_RED_SIZE, 0);
139560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    int g = findConfigAttrib(egl, display, config,
140560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                             EGL10.EGL_GREEN_SIZE, 0);
141560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    int b = findConfigAttrib(egl, display, config,
142560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                              EGL10.EGL_BLUE_SIZE, 0);
143560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    int a = findConfigAttrib(egl, display, config,
144560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                            EGL10.EGL_ALPHA_SIZE, 0);
145560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    int distance = Math.abs(r - mRedSize)
146560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                                + Math.abs(g - mGreenSize)
147560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                                + Math.abs(b - mBlueSize)
148560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                                + Math.abs(a - mAlphaSize);
149560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    if (distance < closestDistance) {
150560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                        closestDistance = distance;
151560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                        closestConfig = config;
152560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    }
153560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                }
154560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            }
155560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            return closestConfig;
156560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
157560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
158560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private int findConfigAttrib(EGL10 egl, EGLDisplay display,
159560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                EGLConfig config, int attribute, int defaultValue) {
160560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
161560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
162560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                return mValue[0];
163560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            }
164560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            return defaultValue;
165560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
166560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
167560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private void printConfigs(EGL10 egl, EGLDisplay display,
168560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            EGLConfig[] configs) {
169560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            int numConfigs = configs.length;
170560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            Log.w(TAG, String.format("%d configurations", numConfigs));
171560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            for (int i = 0; i < numConfigs; i++) {
172560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                Log.w(TAG, String.format("Configuration %d:\n", i));
173560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                printConfig(egl, display, configs[i]);
174560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            }
175560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
176560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
177560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private void printConfig(EGL10 egl, EGLDisplay display,
178560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                EGLConfig config) {
179560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            int[] attributes = {
180560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_BUFFER_SIZE,
181560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_ALPHA_SIZE,
182560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_BLUE_SIZE,
183560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_GREEN_SIZE,
184560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_RED_SIZE,
185560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_DEPTH_SIZE,
186560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_STENCIL_SIZE,
187560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_CONFIG_CAVEAT,
188560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_CONFIG_ID,
189560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_LEVEL,
190560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_MAX_PBUFFER_HEIGHT,
191560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_MAX_PBUFFER_PIXELS,
192560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_MAX_PBUFFER_WIDTH,
193560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_NATIVE_RENDERABLE,
194560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_NATIVE_VISUAL_ID,
195560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_NATIVE_VISUAL_TYPE,
196560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    0x3030, // EGL10.EGL_PRESERVED_RESOURCES,
197560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_SAMPLES,
198560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_SAMPLE_BUFFERS,
199560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_SURFACE_TYPE,
200560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_TRANSPARENT_TYPE,
201560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_TRANSPARENT_RED_VALUE,
202560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_TRANSPARENT_GREEN_VALUE,
203560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_TRANSPARENT_BLUE_VALUE,
204560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB,
205560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA,
206560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL,
207560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL,
208560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_LUMINANCE_SIZE,
209560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_ALPHA_MASK_SIZE,
210560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_COLOR_BUFFER_TYPE,
211560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    EGL10.EGL_RENDERABLE_TYPE,
212560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    0x3042 // EGL10.EGL_CONFORMANT
213560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            };
214560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            String[] names = {
215560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_BUFFER_SIZE",
216560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_ALPHA_SIZE",
217560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_BLUE_SIZE",
218560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_GREEN_SIZE",
219560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_RED_SIZE",
220560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_DEPTH_SIZE",
221560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_STENCIL_SIZE",
222560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_CONFIG_CAVEAT",
223560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_CONFIG_ID",
224560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_LEVEL",
225560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_MAX_PBUFFER_HEIGHT",
226560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_MAX_PBUFFER_PIXELS",
227560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_MAX_PBUFFER_WIDTH",
228560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_NATIVE_RENDERABLE",
229560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_NATIVE_VISUAL_ID",
230560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_NATIVE_VISUAL_TYPE",
231560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_PRESERVED_RESOURCES",
232560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_SAMPLES",
233560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_SAMPLE_BUFFERS",
234560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_SURFACE_TYPE",
235560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_TRANSPARENT_TYPE",
236560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_TRANSPARENT_RED_VALUE",
237560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_TRANSPARENT_GREEN_VALUE",
238560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_TRANSPARENT_BLUE_VALUE",
239560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_BIND_TO_TEXTURE_RGB",
240560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_BIND_TO_TEXTURE_RGBA",
241560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_MIN_SWAP_INTERVAL",
242560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_MAX_SWAP_INTERVAL",
243560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_LUMINANCE_SIZE",
244560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_ALPHA_MASK_SIZE",
245560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_COLOR_BUFFER_TYPE",
246560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_RENDERABLE_TYPE",
247560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    "EGL_CONFORMANT"
248560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            };
249560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            int[] value = new int[1];
250560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            for (int i = 0; i < attributes.length; i++) {
251560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                int attribute = attributes[i];
252560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                String name = names[i];
253560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                if ( egl.eglGetConfigAttrib(display, config, attribute, value)) {
254560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    Log.w(TAG, String.format("  %s: %d\n", name, value[0]));
255560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                } else {
256560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    // Log.w(TAG, String.format("  %s: failed\n", name));
257560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    while (egl.eglGetError() != EGL10.EGL_SUCCESS);
258560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                }
259560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            }
260560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
261560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
262560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        // Subclasses can adjust these values:
263560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        protected int mRedSize;
264560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        protected int mGreenSize;
265560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        protected int mBlueSize;
266560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        protected int mAlphaSize;
267560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        protected int mDepthSize;
268560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        protected int mStencilSize;
269560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private int[] mValue = new int[1];
270560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich    }
271560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
272560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich    private static class Renderer implements GLSurfaceView.Renderer {
273560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
274560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        public Renderer() {
275560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            mTriangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length * 4)
276560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                .order(ByteOrder.nativeOrder()).asFloatBuffer();
277560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            mTriangleVertices.put(mTriangleVerticesData).position(0);
278560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
279560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
280560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        public void onDrawFrame(GL10 gl) {
281560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            GLES20.glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
282560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
283560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            GLES20.glUseProgram(mProgram);
284560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            checkGlError("glUseProgram");
285560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
286560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            GLES20.glVertexAttribPointer(mvPositionHandle, 2, GLES20.GL_FLOAT, false, 0, mTriangleVertices);
287560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            checkGlError("glVertexAttribPointer");
288560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            GLES20.glEnableVertexAttribArray(mvPositionHandle);
289560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            checkGlError("glEnableVertexAttribArray");
290560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
291560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            checkGlError("glDrawArrays");
292560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
293560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
294560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
295560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        public void onSurfaceChanged(GL10 gl, int width, int height) {
296560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            GLES20.glViewport(0, 0, width, height);
297560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
298560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
299560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
300560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            mProgram = createProgram(mVertexShader, mFragmentShader);
301560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            if (mProgram == 0) {
302560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                return;
303560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            }
304560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            mvPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
305560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            checkGlError("glGetAttribLocation");
306560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            if (mvPositionHandle == -1) {
307560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                throw new RuntimeException("Could not get attrib location for vPosition");
308560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            }
309560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
310560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
311560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private int loadShader(int shaderType, String source) {
312560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            int shader = GLES20.glCreateShader(shaderType);
313560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            if (shader != 0) {
314560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                GLES20.glShaderSource(shader, source);
315560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                GLES20.glCompileShader(shader);
316560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                int[] compiled = new int[1];
317560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
318560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                if (compiled[0] == 0) {
319560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    Log.e(TAG, "Could not compile shader " + shaderType + ":");
320560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
321560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    GLES20.glDeleteShader(shader);
322560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    shader = 0;
323560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                }
324560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            }
325560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            return shader;
326560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
327560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
328560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private int createProgram(String vertexSource, String fragmentSource) {
329560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
330560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            if (vertexShader == 0) {
331560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                return 0;
332560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            }
333560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
334560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
335560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            if (pixelShader == 0) {
336560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                return 0;
337560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            }
338560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
339560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            int program = GLES20.glCreateProgram();
340560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            if (program != 0) {
341560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                GLES20.glAttachShader(program, vertexShader);
342560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                checkGlError("glAttachShader");
343560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                GLES20.glAttachShader(program, pixelShader);
344560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                checkGlError("glAttachShader");
345560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                GLES20.glLinkProgram(program);
346560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                int[] linkStatus = new int[1];
347560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
348560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                if (linkStatus[0] != GLES20.GL_TRUE) {
349560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    Log.e(TAG, "Could not link program: ");
350560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    Log.e(TAG, GLES20.glGetProgramInfoLog(program));
351560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    GLES20.glDeleteProgram(program);
352560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    program = 0;
353560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                }
354560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            }
355560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            return program;
356560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
357560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
358560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private void checkGlError(String op) {
359560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            int error;
360560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
361560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                Log.e(TAG, op + ": glError " + error);
362560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                throw new RuntimeException(op + ": glError " + error);
363560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            }
364560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
365560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
366560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private final float[] mTriangleVerticesData = { 0.0f, 0.5f, -0.5f, -0.5f,
367560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                0.5f, -0.5f };
368560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
369560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private FloatBuffer mTriangleVertices;
370560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
371560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private final String mVertexShader = "attribute vec4 vPosition;\n"
372560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            + "void main() {\n"
373560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            + "  gl_Position = vPosition;\n"
374560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            + "}\n";
375560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
376560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private final String mFragmentShader = "precision mediump float;\n"
377560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            + "void main() {\n"
378560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            + "  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
379560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            + "}\n";
380560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
381560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private int mProgram;
382560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private int mvPositionHandle;
383560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
384560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich    }
385560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich}
386560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
387