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