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 
     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      */
     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      */
    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