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