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);
526ae4da75422bbb31c3e0a09f616cdaee1d465946Jack Palevich        setEGLContextClientVersion(2);
53560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        setRenderer(new Renderer());
54560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich    }
55560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
56560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich    private static class Renderer implements GLSurfaceView.Renderer {
57560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
58560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        public Renderer() {
59560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            mTriangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length * 4)
60560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                .order(ByteOrder.nativeOrder()).asFloatBuffer();
61560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            mTriangleVertices.put(mTriangleVerticesData).position(0);
62560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
63560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
64560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        public void onDrawFrame(GL10 gl) {
65560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            GLES20.glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
66560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
67560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            GLES20.glUseProgram(mProgram);
68560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            checkGlError("glUseProgram");
69560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
70560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            GLES20.glVertexAttribPointer(mvPositionHandle, 2, GLES20.GL_FLOAT, false, 0, mTriangleVertices);
71560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            checkGlError("glVertexAttribPointer");
72560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            GLES20.glEnableVertexAttribArray(mvPositionHandle);
73560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            checkGlError("glEnableVertexAttribArray");
74560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
75560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            checkGlError("glDrawArrays");
76560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
77560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
78560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
79560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        public void onSurfaceChanged(GL10 gl, int width, int height) {
80560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            GLES20.glViewport(0, 0, width, height);
81560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
82560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
83560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
84560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            mProgram = createProgram(mVertexShader, mFragmentShader);
85560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            if (mProgram == 0) {
86560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                return;
87560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            }
88560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            mvPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
89560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            checkGlError("glGetAttribLocation");
90560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            if (mvPositionHandle == -1) {
91560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                throw new RuntimeException("Could not get attrib location for vPosition");
92560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            }
93560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
94560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
95560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private int loadShader(int shaderType, String source) {
96560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            int shader = GLES20.glCreateShader(shaderType);
97560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            if (shader != 0) {
98560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                GLES20.glShaderSource(shader, source);
99560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                GLES20.glCompileShader(shader);
100560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                int[] compiled = new int[1];
101560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
102560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                if (compiled[0] == 0) {
103560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    Log.e(TAG, "Could not compile shader " + shaderType + ":");
104560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
105560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    GLES20.glDeleteShader(shader);
106560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    shader = 0;
107560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                }
108560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            }
109560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            return shader;
110560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
111560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
112560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private int createProgram(String vertexSource, String fragmentSource) {
113560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
114560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            if (vertexShader == 0) {
115560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                return 0;
116560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            }
117560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
118560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
119560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            if (pixelShader == 0) {
120560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                return 0;
121560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            }
122560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
123560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            int program = GLES20.glCreateProgram();
124560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            if (program != 0) {
125560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                GLES20.glAttachShader(program, vertexShader);
126560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                checkGlError("glAttachShader");
127560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                GLES20.glAttachShader(program, pixelShader);
128560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                checkGlError("glAttachShader");
129560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                GLES20.glLinkProgram(program);
130560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                int[] linkStatus = new int[1];
131560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
132560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                if (linkStatus[0] != GLES20.GL_TRUE) {
133560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    Log.e(TAG, "Could not link program: ");
134560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    Log.e(TAG, GLES20.glGetProgramInfoLog(program));
135560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    GLES20.glDeleteProgram(program);
136560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                    program = 0;
137560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                }
138560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            }
139560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            return program;
140560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
141560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
142560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private void checkGlError(String op) {
143560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            int error;
144560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
145560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                Log.e(TAG, op + ": glError " + error);
146560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                throw new RuntimeException(op + ": glError " + error);
147560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            }
148560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        }
149560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
150560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private final float[] mTriangleVerticesData = { 0.0f, 0.5f, -0.5f, -0.5f,
151560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich                0.5f, -0.5f };
152560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
153560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private FloatBuffer mTriangleVertices;
154560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
155560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private final String mVertexShader = "attribute vec4 vPosition;\n"
156560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            + "void main() {\n"
157560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            + "  gl_Position = vPosition;\n"
158560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            + "}\n";
159560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
160560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private final String mFragmentShader = "precision mediump float;\n"
161560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            + "void main() {\n"
162560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            + "  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
163560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich            + "}\n";
164560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
165560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private int mProgram;
166560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich        private int mvPositionHandle;
167560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
168560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich    }
169560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich}
170560814f6b11abe83ff0c4ed18cac015c276b3181Jack Palevich
171