• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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    GLushort   *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    UserData *userData = esContext->userData;
48    GLbyte vShaderStr[] =
49       "uniform mat4 u_mvpMatrix;                   \n"
50       "attribute vec4 a_position;                  \n"
51       "void main()                                 \n"
52       "{                                           \n"
53       "   gl_Position = u_mvpMatrix * a_position;  \n"
54       "}                                           \n";
55 
56    GLbyte fShaderStr[] =
57       "precision mediump float;                            \n"
58       "void main()                                         \n"
59       "{                                                   \n"
60       "  gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );        \n"
61       "}                                                   \n";
62 
63    // Load the shaders and get a linked program object
64    userData->programObject = esLoadProgram ( vShaderStr, fShaderStr );
65 
66    // Get the attribute locations
67    userData->positionLoc = glGetAttribLocation ( userData->programObject, "a_position" );
68 
69    // Get the uniform locations
70    userData->mvpLoc = glGetUniformLocation( userData->programObject, "u_mvpMatrix" );
71 
72    // Generate the vertex data
73    userData->numIndices = esGenCube( 1.0, &userData->vertices,
74                                      NULL, NULL, &userData->indices );
75 
76    // Starting rotation angle for the cube
77    userData->angle = 45.0f;
78 
79    glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
80    return TRUE;
81 }
82 
83 
84 ///
85 // Update MVP matrix based on time
86 //
Update(ESContext * esContext,float deltaTime)87 void Update ( ESContext *esContext, float deltaTime )
88 {
89    UserData *userData = (UserData*) esContext->userData;
90    ESMatrix perspective;
91    ESMatrix modelview;
92    float    aspect;
93 
94    // Compute a rotation angle based on time to rotate the cube
95    userData->angle += ( deltaTime * 40.0f );
96    if( userData->angle >= 360.0f )
97       userData->angle -= 360.0f;
98 
99    // Compute the window aspect ratio
100    aspect = (GLfloat) esContext->width / (GLfloat) esContext->height;
101 
102    // Generate a perspective matrix with a 60 degree FOV
103    esMatrixLoadIdentity( &perspective );
104    esPerspective( &perspective, 60.0f, aspect, 1.0f, 20.0f );
105 
106    // Generate a model view matrix to rotate/translate the cube
107    esMatrixLoadIdentity( &modelview );
108 
109    // Translate away from the viewer
110    esTranslate( &modelview, 0.0, 0.0, -2.0 );
111 
112    // Rotate the cube
113    esRotate( &modelview, userData->angle, 1.0, 0.0, 1.0 );
114 
115    // Compute the final MVP by multiplying the
116    // modevleiw and perspective matrices together
117    esMatrixMultiply( &userData->mvpMatrix, &modelview, &perspective );
118 }
119 
120 ///
121 // Draw a triangle using the shader pair created in Init()
122 //
Draw(ESContext * esContext)123 void Draw ( ESContext *esContext )
124 {
125    UserData *userData = esContext->userData;
126 
127    // Set the viewport
128    glViewport ( 0, 0, esContext->width, esContext->height );
129 
130 
131    // Clear the color buffer
132    glClear ( GL_COLOR_BUFFER_BIT );
133 
134    // Use the program object
135    glUseProgram ( userData->programObject );
136 
137    // Load the vertex position
138    glVertexAttribPointer ( userData->positionLoc, 3, GL_FLOAT,
139                            GL_FALSE, 3 * sizeof(GLfloat), userData->vertices );
140 
141    glEnableVertexAttribArray ( userData->positionLoc );
142 
143 
144    // Load the MVP matrix
145    glUniformMatrix4fv( userData->mvpLoc, 1, GL_FALSE, (GLfloat*) &userData->mvpMatrix.m[0][0] );
146 
147    // Draw the cube
148    glDrawElements ( GL_TRIANGLES, userData->numIndices, GL_UNSIGNED_SHORT, userData->indices );
149 
150    eglSwapBuffers ( esContext->eglDisplay, esContext->eglSurface );
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 
174 
main(int argc,char * argv[])175 int main ( int argc, char *argv[] )
176 {
177    ESContext esContext;
178    UserData  userData;
179 
180    esInitContext ( &esContext );
181    esContext.userData = &userData;
182 
183    esCreateWindow ( &esContext, TEXT("Simple Vertex Shader"), 320, 240, ES_WINDOW_RGB );
184 
185    if ( !Init ( &esContext ) )
186       return 0;
187 
188    esRegisterDrawFunc ( &esContext, Draw );
189    esRegisterUpdateFunc ( &esContext, Update );
190 
191    esMainLoop ( &esContext );
192 
193    ShutDown ( &esContext );
194 }
195