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