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 }