1 /* 2 * Copyright (C) 2011 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 package com.example.android.opengl; 17 18 import javax.microedition.khronos.egl.EGLConfig; 19 import javax.microedition.khronos.opengles.GL10; 20 21 import android.opengl.GLES20; 22 import android.opengl.GLSurfaceView; 23 import android.opengl.Matrix; 24 import android.util.Log; 25 26 /** 27 * Provides drawing instructions for a GLSurfaceView object. This class 28 * must override the OpenGL ES drawing lifecycle methods: 29 * <ul> 30 * <li>{@link android.opengl.GLSurfaceView.Renderer#onSurfaceCreated}</li> 31 * <li>{@link android.opengl.GLSurfaceView.Renderer#onDrawFrame}</li> 32 * <li>{@link android.opengl.GLSurfaceView.Renderer#onSurfaceChanged}</li> 33 * </ul> 34 */ 35 public class MyGLRenderer implements GLSurfaceView.Renderer { 36 37 private static final String TAG = "MyGLRenderer"; 38 private Triangle mTriangle; 39 private Square mSquare; 40 41 // mMVPMatrix is an abbreviation for "Model View Projection Matrix" 42 private final float[] mMVPMatrix = new float[16]; 43 private final float[] mProjectionMatrix = new float[16]; 44 private final float[] mViewMatrix = new float[16]; 45 private final float[] mRotationMatrix = new float[16]; 46 47 private float mAngle; 48 49 @Override onSurfaceCreated(GL10 unused, EGLConfig config)50 public void onSurfaceCreated(GL10 unused, EGLConfig config) { 51 52 // Set the background frame color 53 GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 54 55 mTriangle = new Triangle(); 56 mSquare = new Square(); 57 } 58 59 @Override onDrawFrame(GL10 unused)60 public void onDrawFrame(GL10 unused) { 61 float[] scratch = new float[16]; 62 63 // Draw background color 64 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 65 66 // Set the camera position (View matrix) 67 Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f); 68 69 // Calculate the projection and view transformation 70 Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0); 71 72 // Draw square 73 mSquare.draw(mMVPMatrix); 74 75 // Create a rotation for the triangle 76 77 // Use the following code to generate constant rotation. 78 // Leave this code out when using TouchEvents. 79 // long time = SystemClock.uptimeMillis() % 4000L; 80 // float angle = 0.090f * ((int) time); 81 82 Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0, 1.0f); 83 84 // Combine the rotation matrix with the projection and camera view 85 // Note that the mMVPMatrix factor *must be first* in order 86 // for the matrix multiplication product to be correct. 87 Matrix.multiplyMM(scratch, 0, mMVPMatrix, 0, mRotationMatrix, 0); 88 89 // Draw triangle 90 mTriangle.draw(scratch); 91 } 92 93 @Override onSurfaceChanged(GL10 unused, int width, int height)94 public void onSurfaceChanged(GL10 unused, int width, int height) { 95 // Adjust the viewport based on geometry changes, 96 // such as screen rotation 97 GLES20.glViewport(0, 0, width, height); 98 99 float ratio = (float) width / height; 100 101 // this projection matrix is applied to object coordinates 102 // in the onDrawFrame() method 103 Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7); 104 105 } 106 107 /** 108 * Utility method for compiling a OpenGL shader. 109 * 110 * <p><strong>Note:</strong> When developing shaders, use the checkGlError() 111 * method to debug shader coding errors.</p> 112 * 113 * @param type - Vertex or fragment shader type. 114 * @param shaderCode - String containing the shader code. 115 * @return - Returns an id for the shader. 116 */ loadShader(int type, String shaderCode)117 public static int loadShader(int type, String shaderCode){ 118 119 // create a vertex shader type (GLES20.GL_VERTEX_SHADER) 120 // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER) 121 int shader = GLES20.glCreateShader(type); 122 123 // add the source code to the shader and compile it 124 GLES20.glShaderSource(shader, shaderCode); 125 GLES20.glCompileShader(shader); 126 127 return shader; 128 } 129 130 /** 131 * Utility method for debugging OpenGL calls. Provide the name of the call 132 * just after making it: 133 * 134 * <pre> 135 * mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor"); 136 * MyGLRenderer.checkGlError("glGetUniformLocation");</pre> 137 * 138 * If the operation is not successful, the check throws an error. 139 * 140 * @param glOperation - Name of the OpenGL call to check. 141 */ checkGlError(String glOperation)142 public static void checkGlError(String glOperation) { 143 int error; 144 while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { 145 Log.e(TAG, glOperation + ": glError " + error); 146 throw new RuntimeException(glOperation + ": glError " + error); 147 } 148 } 149 150 /** 151 * Returns the rotation angle of the triangle shape (mTriangle). 152 * 153 * @return - A float representing the rotation angle. 154 */ getAngle()155 public float getAngle() { 156 return mAngle; 157 } 158 159 /** 160 * Sets the rotation angle of the triangle shape (mTriangle). 161 */ setAngle(float angle)162 public void setAngle(float angle) { 163 mAngle = angle; 164 } 165 166 }