Home | History | Annotate | Download | only in opengl
      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      */
     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      */
    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 }