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