Mega Code Archive

 
Categories / Android / 2D Graphics
 

Basic GLSurface View Activity

/*  * Copyright (C) 2011 The Android Open Source Project  *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *  *      http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License.  */ package app.test; import android.app.Activity; import android.os.Bundle; import android.view.WindowManager; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.opengl.GLES20; import android.opengl.GLSurfaceView; import android.opengl.GLUtils; import android.opengl.Matrix; import android.os.SystemClock; import android.util.Log; import android.content.Context; import android.opengl.GLSurfaceView; import android.opengl.GLES20; class BasicGLSurfaceView extends GLSurfaceView {     public BasicGLSurfaceView(Context context) {         super(context);         setEGLContextClientVersion(2);         setRenderer(new GLES20TriangleRenderer(context));     } } class GLES20TriangleRenderer implements GLSurfaceView.Renderer {     public GLES20TriangleRenderer(Context context) {         mContext = context;         mTriangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length                 * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();         mTriangleVertices.put(mTriangleVerticesData).position(0);     }     public void onDrawFrame(GL10 glUnused) {         // Ignore the passed-in GL10 interface, and use the GLES20         // class's static methods instead.         GLES20.glClearColor(0.0f, 0.0f, 1.0f, 1.0f);         GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);         GLES20.glUseProgram(mProgram);         checkGlError("glUseProgram");         GLES20.glActiveTexture(GLES20.GL_TEXTURE0);         GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID);         mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);         GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false,                 TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);         checkGlError("glVertexAttribPointer maPosition");         mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);         GLES20.glEnableVertexAttribArray(maPositionHandle);         checkGlError("glEnableVertexAttribArray maPositionHandle");         GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false,                 TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);         checkGlError("glVertexAttribPointer maTextureHandle");         GLES20.glEnableVertexAttribArray(maTextureHandle);         checkGlError("glEnableVertexAttribArray maTextureHandle");         long time = SystemClock.uptimeMillis() % 4000L;         float angle = 0.090f * ((int) time);         Matrix.setRotateM(mMMatrix, 0, angle, 0, 0, 1.0f);         Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);         Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);         GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);         GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);         checkGlError("glDrawArrays");     }     public void onSurfaceChanged(GL10 glUnused, int width, int height) {         // Ignore the passed-in GL10 interface, and use the GLES20         // class's static methods instead.         GLES20.glViewport(0, 0, width, height);         float ratio = (float) width / height;         Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);     }     public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {         // Ignore the passed-in GL10 interface, and use the GLES20         // class's static methods instead.         mProgram = createProgram(mVertexShader, mFragmentShader);         if (mProgram == 0) {             return;         }         maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");         checkGlError("glGetAttribLocation aPosition");         if (maPositionHandle == -1) {             throw new RuntimeException("Could not get attrib location for aPosition");         }         maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");         checkGlError("glGetAttribLocation aTextureCoord");         if (maTextureHandle == -1) {             throw new RuntimeException("Could not get attrib location for aTextureCoord");         }         muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");         checkGlError("glGetUniformLocation uMVPMatrix");         if (muMVPMatrixHandle == -1) {             throw new RuntimeException("Could not get attrib location for uMVPMatrix");         }         /*          * Create our texture. This has to be done each time the          * surface is created.          */         int[] textures = new int[1];         GLES20.glGenTextures(1, textures, 0);         mTextureID = textures[0];         GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID);         GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,                 GLES20.GL_NEAREST);         GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,                 GLES20.GL_TEXTURE_MAG_FILTER,                 GLES20.GL_LINEAR);         GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,                 GLES20.GL_REPEAT);         GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,                 GLES20.GL_REPEAT);         InputStream is = mContext.getResources().openRawResource(R.raw.robot);//robot.png file         Bitmap bitmap;         try {             bitmap = BitmapFactory.decodeStream(is);         } finally {             try {                 is.close();             } catch(IOException e) {                 // Ignore.             }         }         GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);         bitmap.recycle();         Matrix.setLookAtM(mVMatrix, 0, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);     }     private int loadShader(int shaderType, String source) {         int shader = GLES20.glCreateShader(shaderType);         if (shader != 0) {             GLES20.glShaderSource(shader, source);             GLES20.glCompileShader(shader);             int[] compiled = new int[1];             GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);             if (compiled[0] == 0) {                 Log.e(TAG, "Could not compile shader " + shaderType + ":");                 Log.e(TAG, GLES20.glGetShaderInfoLog(shader));                 GLES20.glDeleteShader(shader);                 shader = 0;             }         }         return shader;     }     private int createProgram(String vertexSource, String fragmentSource) {         int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);         if (vertexShader == 0) {             return 0;         }         int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);         if (pixelShader == 0) {             return 0;         }         int program = GLES20.glCreateProgram();         if (program != 0) {             GLES20.glAttachShader(program, vertexShader);             checkGlError("glAttachShader");             GLES20.glAttachShader(program, pixelShader);             checkGlError("glAttachShader");             GLES20.glLinkProgram(program);             int[] linkStatus = new int[1];             GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);             if (linkStatus[0] != GLES20.GL_TRUE) {                 Log.e(TAG, "Could not link program: ");                 Log.e(TAG, GLES20.glGetProgramInfoLog(program));                 GLES20.glDeleteProgram(program);                 program = 0;             }         }         return program;     }     private void checkGlError(String op) {         int error;         while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {             Log.e(TAG, op + ": glError " + error);             throw new RuntimeException(op + ": glError " + error);         }     }     private static final int FLOAT_SIZE_BYTES = 4;     private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES;     private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;     private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3;     private final float[] mTriangleVerticesData = {             // X, Y, Z, U, V             -1.0f, -0.5f, 0, -0.5f, 0.0f,             1.0f, -0.5f, 0, 1.5f, -0.0f,             0.0f,  1.11803399f, 0, 0.5f,  1.61803399f };     private FloatBuffer mTriangleVertices;     private final String mVertexShader =         "uniform mat4 uMVPMatrix;\n" +         "attribute vec4 aPosition;\n" +         "attribute vec2 aTextureCoord;\n" +         "varying vec2 vTextureCoord;\n" +         "void main() {\n" +         "  gl_Position = uMVPMatrix * aPosition;\n" +         "  vTextureCoord = aTextureCoord;\n" +         "}\n";     private final String mFragmentShader =         "precision mediump float;\n" +         "varying vec2 vTextureCoord;\n" +         "uniform sampler2D sTexture;\n" +         "void main() {\n" +         "  gl_FragColor = texture2D(sTexture, vTextureCoord);\n" +         "}\n";     private float[] mMVPMatrix = new float[16];     private float[] mProjMatrix = new float[16];     private float[] mMMatrix = new float[16];     private float[] mVMatrix = new float[16];     private int mProgram;     private int mTextureID;     private int muMVPMatrixHandle;     private int maPositionHandle;     private int maTextureHandle;     private Context mContext;     private static String TAG = "GLES20TriangleRenderer"; } public class Test extends Activity {     private BasicGLSurfaceView mView;     @Override     protected void onCreate(Bundle icicle) {         super.onCreate(icicle);         mView = new BasicGLSurfaceView(getApplication());         setContentView(mView);     }     @Override     protected void onPause() {         super.onPause();         mView.onPause();     }     @Override     protected void onResume() {         super.onResume();         mView.onResume();     } }