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
20typedef 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//
31GLuint 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//
78int 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//
152void 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
178int 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