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