Home | History | Annotate | Download | only in gl2java
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.gl2java;
     18 
     19 import android.content.Context;
     20 import android.opengl.GLSurfaceView;
     21 import android.util.AttributeSet;
     22 import android.util.Log;
     23 import android.view.KeyEvent;
     24 import android.view.MotionEvent;
     25 
     26 import java.nio.ByteBuffer;
     27 import java.nio.ByteOrder;
     28 import java.nio.FloatBuffer;
     29 
     30 import javax.microedition.khronos.egl.EGL10;
     31 import javax.microedition.khronos.egl.EGLConfig;
     32 import javax.microedition.khronos.egl.EGLContext;
     33 import javax.microedition.khronos.egl.EGLDisplay;
     34 import javax.microedition.khronos.opengles.GL10;
     35 
     36 import android.opengl.GLES20;
     37 
     38 /**
     39  * An implementation of SurfaceView that uses the dedicated surface for
     40  * displaying an OpenGL animation.  This allows the animation to run in a
     41  * separate thread, without requiring that it be driven by the update mechanism
     42  * of the view hierarchy.
     43  *
     44  * The application-specific rendering code is delegated to a GLView.Renderer
     45  * instance.
     46  */
     47 class GL2JavaView extends GLSurfaceView {
     48     private static String TAG = "GL2JavaView";
     49 
     50     public GL2JavaView(Context context) {
     51         super(context);
     52         setEGLContextClientVersion(2);
     53         setRenderer(new Renderer());
     54     }
     55 
     56     private static class Renderer implements GLSurfaceView.Renderer {
     57 
     58         public Renderer() {
     59             mTriangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length * 4)
     60                 .order(ByteOrder.nativeOrder()).asFloatBuffer();
     61             mTriangleVertices.put(mTriangleVerticesData).position(0);
     62         }
     63 
     64         public void onDrawFrame(GL10 gl) {
     65             GLES20.glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
     66             GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
     67             GLES20.glUseProgram(mProgram);
     68             checkGlError("glUseProgram");
     69 
     70             GLES20.glVertexAttribPointer(mvPositionHandle, 2, GLES20.GL_FLOAT, false, 0, mTriangleVertices);
     71             checkGlError("glVertexAttribPointer");
     72             GLES20.glEnableVertexAttribArray(mvPositionHandle);
     73             checkGlError("glEnableVertexAttribArray");
     74             GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
     75             checkGlError("glDrawArrays");
     76 
     77         }
     78 
     79         public void onSurfaceChanged(GL10 gl, int width, int height) {
     80             GLES20.glViewport(0, 0, width, height);
     81         }
     82 
     83         public void onSurfaceCreated(GL10 gl, EGLConfig config) {
     84             mProgram = createProgram(mVertexShader, mFragmentShader);
     85             if (mProgram == 0) {
     86                 return;
     87             }
     88             mvPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
     89             checkGlError("glGetAttribLocation");
     90             if (mvPositionHandle == -1) {
     91                 throw new RuntimeException("Could not get attrib location for vPosition");
     92             }
     93         }
     94 
     95         private int loadShader(int shaderType, String source) {
     96             int shader = GLES20.glCreateShader(shaderType);
     97             if (shader != 0) {
     98                 GLES20.glShaderSource(shader, source);
     99                 GLES20.glCompileShader(shader);
    100                 int[] compiled = new int[1];
    101                 GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
    102                 if (compiled[0] == 0) {
    103                     Log.e(TAG, "Could not compile shader " + shaderType + ":");
    104                     Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
    105                     GLES20.glDeleteShader(shader);
    106                     shader = 0;
    107                 }
    108             }
    109             return shader;
    110         }
    111 
    112         private int createProgram(String vertexSource, String fragmentSource) {
    113             int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
    114             if (vertexShader == 0) {
    115                 return 0;
    116             }
    117 
    118             int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
    119             if (pixelShader == 0) {
    120                 return 0;
    121             }
    122 
    123             int program = GLES20.glCreateProgram();
    124             if (program != 0) {
    125                 GLES20.glAttachShader(program, vertexShader);
    126                 checkGlError("glAttachShader");
    127                 GLES20.glAttachShader(program, pixelShader);
    128                 checkGlError("glAttachShader");
    129                 GLES20.glLinkProgram(program);
    130                 int[] linkStatus = new int[1];
    131                 GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
    132                 if (linkStatus[0] != GLES20.GL_TRUE) {
    133                     Log.e(TAG, "Could not link program: ");
    134                     Log.e(TAG, GLES20.glGetProgramInfoLog(program));
    135                     GLES20.glDeleteProgram(program);
    136                     program = 0;
    137                 }
    138             }
    139             return program;
    140         }
    141 
    142         private void checkGlError(String op) {
    143             int error;
    144             while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
    145                 Log.e(TAG, op + ": glError " + error);
    146                 throw new RuntimeException(op + ": glError " + error);
    147             }
    148         }
    149 
    150         private final float[] mTriangleVerticesData = { 0.0f, 0.5f, -0.5f, -0.5f,
    151                 0.5f, -0.5f };
    152 
    153         private FloatBuffer mTriangleVertices;
    154 
    155         private final String mVertexShader = "attribute vec4 vPosition;\n"
    156             + "void main() {\n"
    157             + "  gl_Position = vPosition;\n"
    158             + "}\n";
    159 
    160         private final String mFragmentShader = "precision mediump float;\n"
    161             + "void main() {\n"
    162             + "  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
    163             + "}\n";
    164 
    165         private int mProgram;
    166         private int mvPositionHandle;
    167 
    168     }
    169 }
    170 
    171