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