Home | History | Annotate | Download | only in Simple_VertexShader
      1 //
      2 // Book:      OpenGL(R) ES 2.0 Programming Guide
      3 // Authors:   Aaftab Munshi, Dan Ginsburg, Dave Shreiner
      4 // ISBN-10:   0321502795
      5 // ISBN-13:   9780321502797
      6 // Publisher: Addison-Wesley Professional
      7 // URLs:      http://safari.informit.com/9780321563835
      8 //            http://www.opengles-book.com
      9 //
     10 
     11 // Simple_VertexShader.c
     12 //
     13 //    This is a simple example that draws a rotating cube in perspective
     14 //    using a vertex shader to transform the object
     15 //
     16 #include <stdlib.h>
     17 #include "esUtil.h"
     18 
     19 typedef struct
     20 {
     21    // Handle to a program object
     22    GLuint programObject;
     23 
     24    // Attribute locations
     25    GLint  positionLoc;
     26 
     27    // Uniform locations
     28    GLint  mvpLoc;
     29 
     30    // Vertex daata
     31    GLfloat  *vertices;
     32    GLushort   *indices;
     33    int       numIndices;
     34 
     35    // Rotation angle
     36    GLfloat   angle;
     37 
     38    // MVP matrix
     39    ESMatrix  mvpMatrix;
     40 } UserData;
     41 
     42 ///
     43 // Initialize the shader and program object
     44 //
     45 int Init ( ESContext *esContext )
     46 {
     47    UserData *userData = esContext->userData;
     48    GLbyte vShaderStr[] =
     49       "uniform mat4 u_mvpMatrix;                   \n"
     50       "attribute vec4 a_position;                  \n"
     51       "void main()                                 \n"
     52       "{                                           \n"
     53       "   gl_Position = u_mvpMatrix * a_position;  \n"
     54       "}                                           \n";
     55 
     56    GLbyte fShaderStr[] =
     57       "precision mediump float;                            \n"
     58       "void main()                                         \n"
     59       "{                                                   \n"
     60       "  gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );        \n"
     61       "}                                                   \n";
     62 
     63    // Load the shaders and get a linked program object
     64    userData->programObject = esLoadProgram ( vShaderStr, fShaderStr );
     65 
     66    // Get the attribute locations
     67    userData->positionLoc = glGetAttribLocation ( userData->programObject, "a_position" );
     68 
     69    // Get the uniform locations
     70    userData->mvpLoc = glGetUniformLocation( userData->programObject, "u_mvpMatrix" );
     71 
     72    // Generate the vertex data
     73    userData->numIndices = esGenCube( 1.0, &userData->vertices,
     74                                      NULL, NULL, &userData->indices );
     75 
     76    // Starting rotation angle for the cube
     77    userData->angle = 45.0f;
     78 
     79    glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
     80    return TRUE;
     81 }
     82 
     83 
     84 ///
     85 // Update MVP matrix based on time
     86 //
     87 void Update ( ESContext *esContext, float deltaTime )
     88 {
     89    UserData *userData = (UserData*) esContext->userData;
     90    ESMatrix perspective;
     91    ESMatrix modelview;
     92    float    aspect;
     93 
     94    // Compute a rotation angle based on time to rotate the cube
     95    userData->angle += ( deltaTime * 40.0f );
     96    if( userData->angle >= 360.0f )
     97       userData->angle -= 360.0f;
     98 
     99    // Compute the window aspect ratio
    100    aspect = (GLfloat) esContext->width / (GLfloat) esContext->height;
    101 
    102    // Generate a perspective matrix with a 60 degree FOV
    103    esMatrixLoadIdentity( &perspective );
    104    esPerspective( &perspective, 60.0f, aspect, 1.0f, 20.0f );
    105 
    106    // Generate a model view matrix to rotate/translate the cube
    107    esMatrixLoadIdentity( &modelview );
    108 
    109    // Translate away from the viewer
    110    esTranslate( &modelview, 0.0, 0.0, -2.0 );
    111 
    112    // Rotate the cube
    113    esRotate( &modelview, userData->angle, 1.0, 0.0, 1.0 );
    114 
    115    // Compute the final MVP by multiplying the
    116    // modevleiw and perspective matrices together
    117    esMatrixMultiply( &userData->mvpMatrix, &modelview, &perspective );
    118 }
    119 
    120 ///
    121 // Draw a triangle using the shader pair created in Init()
    122 //
    123 void Draw ( ESContext *esContext )
    124 {
    125    UserData *userData = esContext->userData;
    126 
    127    // Set the viewport
    128    glViewport ( 0, 0, esContext->width, esContext->height );
    129 
    130 
    131    // Clear the color buffer
    132    glClear ( GL_COLOR_BUFFER_BIT );
    133 
    134    // Use the program object
    135    glUseProgram ( userData->programObject );
    136 
    137    // Load the vertex position
    138    glVertexAttribPointer ( userData->positionLoc, 3, GL_FLOAT,
    139                            GL_FALSE, 3 * sizeof(GLfloat), userData->vertices );
    140 
    141    glEnableVertexAttribArray ( userData->positionLoc );
    142 
    143 
    144    // Load the MVP matrix
    145    glUniformMatrix4fv( userData->mvpLoc, 1, GL_FALSE, (GLfloat*) &userData->mvpMatrix.m[0][0] );
    146 
    147    // Draw the cube
    148    glDrawElements ( GL_TRIANGLES, userData->numIndices, GL_UNSIGNED_SHORT, userData->indices );
    149 
    150    eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );
    151 }
    152 
    153 ///
    154 // Cleanup
    155 //
    156 void ShutDown ( ESContext *esContext )
    157 {
    158    UserData *userData = esContext->userData;
    159 
    160    if ( userData->vertices != NULL )
    161    {
    162       free ( userData->vertices );
    163    }
    164 
    165    if ( userData->indices != NULL )
    166    {
    167       free ( userData->indices );
    168    }
    169 
    170    // Delete program object
    171    glDeleteProgram ( userData->programObject );
    172 }
    173 
    174 
    175 int main ( int argc, char *argv[] )
    176 {
    177    ESContext esContext;
    178    UserData  userData;
    179 
    180    esInitContext ( &esContext );
    181    esContext.userData = &userData;
    182 
    183    esCreateWindow ( &esContext, TEXT("Simple Vertex Shader"), 320, 240, ES_WINDOW_RGB );
    184 
    185    if ( !Init ( &esContext ) )
    186       return 0;
    187 
    188    esRegisterDrawFunc ( &esContext, Draw );
    189    esRegisterUpdateFunc ( &esContext, Update );
    190 
    191    esMainLoop ( &esContext );
    192 
    193    ShutDown ( &esContext );
    194 }
    195