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 java.nio.ByteBuffer; 19 import java.nio.ByteOrder; 20 import java.nio.FloatBuffer; 21 import java.nio.ShortBuffer; 22 23 import android.opengl.GLES20; 24 25 /** 26 * A two-dimensional square for use as a drawn object in OpenGL ES 2.0. 27 */ 28 public class Square { 29 30 private final String vertexShaderCode = 31 // This matrix member variable provides a hook to manipulate 32 // the coordinates of the objects that use this vertex shader 33 "uniform mat4 uMVPMatrix;" + 34 "attribute vec4 vPosition;" + 35 "void main() {" + 36 // The matrix must be included as a modifier of gl_Position. 37 // Note that the uMVPMatrix factor *must be first* in order 38 // for the matrix multiplication product to be correct. 39 " gl_Position = uMVPMatrix * vPosition;" + 40 "}"; 41 42 private final String fragmentShaderCode = 43 "precision mediump float;" + 44 "uniform vec4 vColor;" + 45 "void main() {" + 46 " gl_FragColor = vColor;" + 47 "}"; 48 49 private final FloatBuffer vertexBuffer; 50 private final ShortBuffer drawListBuffer; 51 private final int mProgram; 52 private int mPositionHandle; 53 private int mColorHandle; 54 private int mMVPMatrixHandle; 55 56 // number of coordinates per vertex in this array 57 static final int COORDS_PER_VERTEX = 3; 58 static float squareCoords[] = { 59 -0.5f, 0.5f, 0.0f, // top left 60 -0.5f, -0.5f, 0.0f, // bottom left 61 0.5f, -0.5f, 0.0f, // bottom right 62 0.5f, 0.5f, 0.0f }; // top right 63 64 private final short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices 65 66 private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex 67 68 float color[] = { 0.2f, 0.709803922f, 0.898039216f, 1.0f }; 69 70 /** 71 * Sets up the drawing object data for use in an OpenGL ES context. 72 */ Square()73 public Square() { 74 // initialize vertex byte buffer for shape coordinates 75 ByteBuffer bb = ByteBuffer.allocateDirect( 76 // (# of coordinate values * 4 bytes per float) 77 squareCoords.length * 4); 78 bb.order(ByteOrder.nativeOrder()); 79 vertexBuffer = bb.asFloatBuffer(); 80 vertexBuffer.put(squareCoords); 81 vertexBuffer.position(0); 82 83 // initialize byte buffer for the draw list 84 ByteBuffer dlb = ByteBuffer.allocateDirect( 85 // (# of coordinate values * 2 bytes per short) 86 drawOrder.length * 2); 87 dlb.order(ByteOrder.nativeOrder()); 88 drawListBuffer = dlb.asShortBuffer(); 89 drawListBuffer.put(drawOrder); 90 drawListBuffer.position(0); 91 92 // prepare shaders and OpenGL program 93 int vertexShader = MyGLRenderer.loadShader( 94 GLES20.GL_VERTEX_SHADER, 95 vertexShaderCode); 96 int fragmentShader = MyGLRenderer.loadShader( 97 GLES20.GL_FRAGMENT_SHADER, 98 fragmentShaderCode); 99 100 mProgram = GLES20.glCreateProgram(); // create empty OpenGL Program 101 GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program 102 GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program 103 GLES20.glLinkProgram(mProgram); // create OpenGL program executables 104 } 105 106 /** 107 * Encapsulates the OpenGL ES instructions for drawing this shape. 108 * 109 * @param mvpMatrix - The Model View Project matrix in which to draw 110 * this shape. 111 */ draw(float[] mvpMatrix)112 public void draw(float[] mvpMatrix) { 113 // Add program to OpenGL environment 114 GLES20.glUseProgram(mProgram); 115 116 // get handle to vertex shader's vPosition member 117 mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition"); 118 119 // Enable a handle to the triangle vertices 120 GLES20.glEnableVertexAttribArray(mPositionHandle); 121 122 // Prepare the triangle coordinate data 123 GLES20.glVertexAttribPointer( 124 mPositionHandle, COORDS_PER_VERTEX, 125 GLES20.GL_FLOAT, false, 126 vertexStride, vertexBuffer); 127 128 // get handle to fragment shader's vColor member 129 mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor"); 130 131 // Set color for drawing the triangle 132 GLES20.glUniform4fv(mColorHandle, 1, color, 0); 133 134 // get handle to shape's transformation matrix 135 mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); 136 MyGLRenderer.checkGlError("glGetUniformLocation"); 137 138 // Apply the projection and view transformation 139 GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0); 140 MyGLRenderer.checkGlError("glUniformMatrix4fv"); 141 142 // Draw the square 143 GLES20.glDrawElements( 144 GLES20.GL_TRIANGLES, drawOrder.length, 145 GLES20.GL_UNSIGNED_SHORT, drawListBuffer); 146 147 // Disable vertex array 148 GLES20.glDisableVertexAttribArray(mPositionHandle); 149 } 150 151 }