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); 52378112ebed362a85471bd2acb307aa0ddb539d17Jack Palevich setEGLContextClientVersion(2); 5350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich setRenderer(new Renderer()); 5450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 5550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 5650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private static class Renderer implements GLSurfaceView.Renderer { 5750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 5850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich public Renderer() { 5950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich mTriangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length * 4) 6050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich .order(ByteOrder.nativeOrder()).asFloatBuffer(); 6150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich mTriangleVertices.put(mTriangleVerticesData).position(0); 6250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 6350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 6450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich public void onDrawFrame(GL10 gl) { 6550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glClearColor(0.0f, 0.0f, 1.0f, 1.0f); 6650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); 6750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glUseProgram(mProgram); 6850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich checkGlError("glUseProgram"); 6950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 7050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glVertexAttribPointer(mvPositionHandle, 2, GLES20.GL_FLOAT, false, 0, mTriangleVertices); 7150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich checkGlError("glVertexAttribPointer"); 7250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glEnableVertexAttribArray(mvPositionHandle); 7350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich checkGlError("glEnableVertexAttribArray"); 7450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3); 7550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich checkGlError("glDrawArrays"); 7650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 7750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 7850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 7950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich public void onSurfaceChanged(GL10 gl, int width, int height) { 8050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glViewport(0, 0, width, height); 8150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 8250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 8350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich public void onSurfaceCreated(GL10 gl, EGLConfig config) { 8450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich mProgram = createProgram(mVertexShader, mFragmentShader); 8550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (mProgram == 0) { 8650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich return; 8750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 8850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich mvPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition"); 8950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich checkGlError("glGetAttribLocation"); 9050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (mvPositionHandle == -1) { 9150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich throw new RuntimeException("Could not get attrib location for vPosition"); 9250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 9350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 9450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 9550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private int loadShader(int shaderType, String source) { 9650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int shader = GLES20.glCreateShader(shaderType); 9750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (shader != 0) { 9850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glShaderSource(shader, source); 9950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glCompileShader(shader); 10050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int[] compiled = new int[1]; 10150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0); 10250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (compiled[0] == 0) { 10350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich Log.e(TAG, "Could not compile shader " + shaderType + ":"); 10450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich Log.e(TAG, GLES20.glGetShaderInfoLog(shader)); 10550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glDeleteShader(shader); 10650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich shader = 0; 10750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 10850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 10950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich return shader; 11050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 11150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 11250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private int createProgram(String vertexSource, String fragmentSource) { 11350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource); 11450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (vertexShader == 0) { 11550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich return 0; 11650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 11750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 11850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource); 11950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (pixelShader == 0) { 12050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich return 0; 12150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 12250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 12350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int program = GLES20.glCreateProgram(); 12450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (program != 0) { 12550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glAttachShader(program, vertexShader); 12650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich checkGlError("glAttachShader"); 12750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glAttachShader(program, pixelShader); 12850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich checkGlError("glAttachShader"); 12950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glLinkProgram(program); 13050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int[] linkStatus = new int[1]; 13150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0); 13250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich if (linkStatus[0] != GLES20.GL_TRUE) { 13350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich Log.e(TAG, "Could not link program: "); 13450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich Log.e(TAG, GLES20.glGetProgramInfoLog(program)); 13550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich GLES20.glDeleteProgram(program); 13650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich program = 0; 13750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 13850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 13950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich return program; 14050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 14150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 14250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private void checkGlError(String op) { 14350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich int error; 14450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { 14550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich Log.e(TAG, op + ": glError " + error); 14650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich throw new RuntimeException(op + ": glError " + error); 14750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 14850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 14950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 15050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private final float[] mTriangleVerticesData = { 0.0f, 0.5f, -0.5f, -0.5f, 15150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 0.5f, -0.5f }; 15250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 15350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private FloatBuffer mTriangleVertices; 15450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 15550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private final String mVertexShader = "attribute vec4 vPosition;\n" 15650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich + "void main() {\n" 15750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich + " gl_Position = vPosition;\n" 15850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich + "}\n"; 15950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 16050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private final String mFragmentShader = "precision mediump float;\n" 16150d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich + "void main() {\n" 16250d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich + " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n" 16350d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich + "}\n"; 16450d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 16550d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private int mProgram; 16650d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich private int mvPositionHandle; 16750d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 16850d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich } 16950d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich} 17050d0b14689b0ae95ea7b66a8c2f7b955115812ddJack Palevich 171