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 //
LoadShader(GLenum type,const char * shaderSrc)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 //
Init(ESContext * esContext)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 //
Draw(ESContext * esContext)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
main(int argc,char * argv[])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