Home | History | Annotate | Download | only in Hello_Triangle
      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 // Hello_Triangle.c
     12 //
     13 //    This is a simple example that draws a single triangle with
     14 //    a minimal vertex/fragment shader.  The purpose of this
     15 //    example is to demonstrate the basic concepts of
     16 //    OpenGL ES 2.0 rendering.
     17 #include <stdlib.h>
     18 #include "esUtil.h"
     19 
     20 typedef struct
     21 {
     22    // Handle to a program object
     23    GLuint programObject;
     24 
     25 } UserData;
     26 
     27 ///
     28 // Create a shader object, load the shader source, and
     29 // compile the shader.
     30 //
     31 GLuint LoadShader ( GLenum type, const char *shaderSrc )
     32 {
     33    GLuint shader;
     34    GLint compiled;
     35 
     36    // Create the shader object
     37    shader = glCreateShader ( type );
     38 
     39    if ( shader == 0 )
     40    	return 0;
     41 
     42    // Load the shader source
     43    glShaderSource ( shader, 1, &shaderSrc, NULL );
     44 
     45    // Compile the shader
     46    glCompileShader ( shader );
     47 
     48    // Check the compile status
     49    glGetShaderiv ( shader, GL_COMPILE_STATUS, &compiled );
     50 
     51    if ( !compiled )
     52    {
     53       GLint infoLen = 0;
     54 
     55       glGetShaderiv ( shader, GL_INFO_LOG_LENGTH, &infoLen );
     56 
     57       if ( infoLen > 1 )
     58       {
     59          char* infoLog = malloc (sizeof(char) * infoLen );
     60 
     61          glGetShaderInfoLog ( shader, infoLen, NULL, infoLog );
     62          esLogMessage ( "Error compiling shader:\n%s\n", infoLog );
     63 
     64          free ( infoLog );
     65       }
     66 
     67       glDeleteShader ( shader );
     68       return 0;
     69    }
     70 
     71    return shader;
     72 
     73 }
     74 
     75 ///
     76 // Initialize the shader and program object
     77 //
     78 int Init ( ESContext *esContext )
     79 {
     80    UserData *userData = esContext->userData;
     81    GLbyte vShaderStr[] =
     82       "attribute vec4 vPosition;    \n"
     83       "void main()                  \n"
     84       "{                            \n"
     85       "   gl_Position = vPosition;  \n"
     86       "}                            \n";
     87 
     88    GLbyte fShaderStr[] =
     89       "precision mediump float;\n"\
     90       "void main()                                  \n"
     91       "{                                            \n"
     92       "  gl_FragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 );\n"
     93       "}                                            \n";
     94 
     95    GLuint vertexShader;
     96    GLuint fragmentShader;
     97    GLuint programObject;
     98    GLint linked;
     99 
    100    // Load the vertex/fragment shaders
    101    vertexShader = LoadShader ( GL_VERTEX_SHADER, vShaderStr );
    102    fragmentShader = LoadShader ( GL_FRAGMENT_SHADER, fShaderStr );
    103 
    104    // Create the program object
    105    programObject = glCreateProgram ( );
    106 
    107    if ( programObject == 0 )
    108       return 0;
    109 
    110    glAttachShader ( programObject, vertexShader );
    111    glAttachShader ( programObject, fragmentShader );
    112 
    113    // Bind vPosition to attribute 0
    114    glBindAttribLocation ( programObject, 0, "vPosition" );
    115 
    116    // Link the program
    117    glLinkProgram ( programObject );
    118 
    119    // Check the link status
    120    glGetProgramiv ( programObject, GL_LINK_STATUS, &linked );
    121 
    122    if ( !linked )
    123    {
    124       GLint infoLen = 0;
    125 
    126       glGetProgramiv ( programObject, GL_INFO_LOG_LENGTH, &infoLen );
    127 
    128       if ( infoLen > 1 )
    129       {
    130          char* infoLog = malloc (sizeof(char) * infoLen );
    131 
    132          glGetProgramInfoLog ( programObject, infoLen, NULL, infoLog );
    133          esLogMessage ( "Error linking program:\n%s\n", infoLog );
    134 
    135          free ( infoLog );
    136       }
    137 
    138       glDeleteProgram ( programObject );
    139       return FALSE;
    140    }
    141 
    142    // Store the program object
    143    userData->programObject = programObject;
    144 
    145    glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
    146    return TRUE;
    147 }
    148 
    149 ///
    150 // Draw a triangle using the shader pair created in Init()
    151 //
    152 void Draw ( ESContext *esContext )
    153 {
    154    UserData *userData = esContext->userData;
    155    GLfloat vVertices[] = {  0.0f,  0.5f, 0.0f,
    156                            -0.5f, -0.5f, 0.0f,
    157                             0.5f, -0.5f, 0.0f };
    158 
    159    // Set the viewport
    160    glViewport ( 0, 0, esContext->width, esContext->height );
    161 
    162    // Clear the color buffer
    163    glClear ( GL_COLOR_BUFFER_BIT );
    164 
    165    // Use the program object
    166    glUseProgram ( userData->programObject );
    167 
    168    // Load the vertex data
    169    glVertexAttribPointer ( 0, 3, GL_FLOAT, GL_FALSE, 0, vVertices );
    170    glEnableVertexAttribArray ( 0 );
    171 
    172    glDrawArrays ( GL_TRIANGLES, 0, 3 );
    173 
    174    eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );
    175 }
    176 
    177 
    178 int main ( int argc, char *argv[] )
    179 {
    180    ESContext esContext;
    181    UserData  userData;
    182 
    183    esInitContext ( &esContext );
    184    esContext.userData = &userData;
    185 
    186    esCreateWindow ( &esContext, TEXT("Hello Triangle"), 320, 240, ES_WINDOW_RGB );
    187 
    188    if ( !Init ( &esContext ) )
    189       return 0;
    190 
    191    esRegisterDrawFunc ( &esContext, Draw );
    192 
    193    esMainLoop ( &esContext );
    194 }
    195