1 // Calls glDrawElements() the number of times specified by
2 // ITERATIONS. Should draw a checkerboard on the screen after
3 // a few seconds.
4 //
5 // Ported from a Java version by Google.
6
7 #include <EGL/egl.h>
8 #include <GLES/gl.h>
9 #include <GLES/glext.h>
10
11 #include <WindowSurface.h>
12 #include <EGLUtils.h>
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <math.h>
17
18 using namespace android;
19
20 EGLDisplay eglDisplay;
21 EGLSurface eglSurface;
22 EGLContext eglContext;
23 GLuint texture;
24
25 #define FIXED_ONE 0x10000
26 #define ITERATIONS 50
27
28 int init_gl_surface(const WindowSurface&);
29 void free_gl_surface(void);
30 void init_scene(void);
31 void render(int quads);
32 void create_texture(void);
33 int readTimer(void);
34
gluLookAt(float eyeX,float eyeY,float eyeZ,float centerX,float centerY,float centerZ,float upX,float upY,float upZ)35 static void gluLookAt(float eyeX, float eyeY, float eyeZ,
36 float centerX, float centerY, float centerZ, float upX, float upY,
37 float upZ)
38 {
39 // See the OpenGL GLUT documentation for gluLookAt for a description
40 // of the algorithm. We implement it in a straightforward way:
41
42 float fx = centerX - eyeX;
43 float fy = centerY - eyeY;
44 float fz = centerZ - eyeZ;
45
46 // Normalize f
47 float rlf = 1.0f / sqrtf(fx*fx + fy*fy + fz*fz);
48 fx *= rlf;
49 fy *= rlf;
50 fz *= rlf;
51
52 // Normalize up
53 float rlup = 1.0f / sqrtf(upX*upX + upY*upY + upZ*upZ);
54 upX *= rlup;
55 upY *= rlup;
56 upZ *= rlup;
57
58 // compute s = f x up (x means "cross product")
59
60 float sx = fy * upZ - fz * upY;
61 float sy = fz * upX - fx * upZ;
62 float sz = fx * upY - fy * upX;
63
64 // compute u = s x f
65 float ux = sy * fz - sz * fy;
66 float uy = sz * fx - sx * fz;
67 float uz = sx * fy - sy * fx;
68
69 float m[16] ;
70 m[0] = sx;
71 m[1] = ux;
72 m[2] = -fx;
73 m[3] = 0.0f;
74
75 m[4] = sy;
76 m[5] = uy;
77 m[6] = -fy;
78 m[7] = 0.0f;
79
80 m[8] = sz;
81 m[9] = uz;
82 m[10] = -fz;
83 m[11] = 0.0f;
84
85 m[12] = 0.0f;
86 m[13] = 0.0f;
87 m[14] = 0.0f;
88 m[15] = 1.0f;
89
90 glMultMatrixf(m);
91 glTranslatef(-eyeX, -eyeY, -eyeZ);
92 }
93
main(int argc,char ** argv)94 int main(int argc, char **argv)
95 {
96 printf("Initializing EGL...\n");
97
98 WindowSurface windowSurface;
99 if(!init_gl_surface(windowSurface))
100 {
101 printf("GL initialisation failed - exiting\n");
102 return 0;
103 }
104
105 init_scene();
106
107 create_texture();
108
109 printf("Start test...\n");
110
111 render(argc==2 ? atoi(argv[1]) : ITERATIONS);
112
113 free_gl_surface();
114
115 return 0;
116 }
117
init_gl_surface(const WindowSurface & windowSurface)118 int init_gl_surface(const WindowSurface& windowSurface)
119 {
120 EGLConfig myConfig = {0};
121 EGLint attrib[] =
122 {
123 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
124 EGL_DEPTH_SIZE, 16,
125 EGL_NONE
126 };
127
128 if ( (eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY )
129 {
130 printf("eglGetDisplay failed\n");
131 return 0;
132 }
133
134 if ( eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE )
135 {
136 printf("eglInitialize failed\n");
137 return 0;
138 }
139
140 EGLNativeWindowType window = windowSurface.getSurface();
141 EGLUtils::selectConfigForNativeWindow(eglDisplay, attrib, window, &myConfig);
142
143 if ( (eglSurface = eglCreateWindowSurface(eglDisplay, myConfig,
144 window, 0)) == EGL_NO_SURFACE )
145 {
146 printf("eglCreateWindowSurface failed\n");
147 return 0;
148 }
149
150 if ( (eglContext = eglCreateContext(eglDisplay, myConfig, 0, 0)) == EGL_NO_CONTEXT )
151 {
152 printf("eglCreateContext failed\n");
153 return 0;
154 }
155
156 if ( eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) != EGL_TRUE )
157 {
158 printf("eglMakeCurrent failed\n");
159 return 0;
160 }
161
162 return 1;
163 }
164
free_gl_surface(void)165 void free_gl_surface(void)
166 {
167 if (eglDisplay != EGL_NO_DISPLAY)
168 {
169 eglMakeCurrent( EGL_NO_DISPLAY, EGL_NO_SURFACE,
170 EGL_NO_SURFACE, EGL_NO_CONTEXT );
171 eglDestroyContext( eglDisplay, eglContext );
172 eglDestroySurface( eglDisplay, eglSurface );
173 eglTerminate( eglDisplay );
174 eglDisplay = EGL_NO_DISPLAY;
175 }
176 }
177
init_scene(void)178 void init_scene(void)
179 {
180 glDisable(GL_DITHER);
181 glEnable(GL_CULL_FACE);
182
183 float ratio = 320.0f / 480.0f;
184 glViewport(0, 0, 320, 480);
185
186 glMatrixMode(GL_PROJECTION);
187 glLoadIdentity();
188 glFrustumf(-ratio, ratio, -1, 1, 1, 10);
189
190 glMatrixMode(GL_MODELVIEW);
191 glLoadIdentity();
192 gluLookAt(
193 0, 0, 3, // eye
194 0, 0, 0, // center
195 0, 1, 0); // up
196
197 glEnable(GL_TEXTURE_2D);
198 glEnableClientState(GL_VERTEX_ARRAY);
199 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
200 }
201
create_texture(void)202 void create_texture(void)
203 {
204 const unsigned int on = 0xff0000ff;
205 const unsigned int off = 0xffffffff;
206 const unsigned int pixels[] =
207 {
208 on, off, on, off, on, off, on, off,
209 off, on, off, on, off, on, off, on,
210 on, off, on, off, on, off, on, off,
211 off, on, off, on, off, on, off, on,
212 on, off, on, off, on, off, on, off,
213 off, on, off, on, off, on, off, on,
214 on, off, on, off, on, off, on, off,
215 off, on, off, on, off, on, off, on,
216 };
217 glGenTextures(1, &texture);
218 glBindTexture(GL_TEXTURE_2D, texture);
219 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
220 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
221 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
222 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
223 }
224
render(int quads)225 void render(int quads)
226 {
227 int i, j;
228
229 const GLfloat vertices[] = {
230 -1, -1, 0,
231 1, -1, 0,
232 1, 1, 0,
233 -1, 1, 0
234 };
235
236 const GLfixed texCoords[] = {
237 0, 0,
238 FIXED_ONE, 0,
239 FIXED_ONE, FIXED_ONE,
240 0, FIXED_ONE
241 };
242
243 const GLushort quadIndices[] = { 0, 1, 2, 0, 2, 3 };
244
245
246 GLushort* indices = (GLushort*)malloc(quads*sizeof(quadIndices));
247 for (i=0 ; i<quads ; i++)
248 memcpy(indices+(sizeof(quadIndices)/sizeof(indices[0]))*i, quadIndices, sizeof(quadIndices));
249
250 glVertexPointer(3, GL_FLOAT, 0, vertices);
251 glTexCoordPointer(2, GL_FIXED, 0, texCoords);
252
253 // make sure to do a couple eglSwapBuffers to make sure there are
254 // no problems with the very first ones (who knows)
255 glClearColor(0.4, 0.4, 0.4, 0.4);
256 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
257 eglSwapBuffers(eglDisplay, eglSurface);
258 glClearColor(0.6, 0.6, 0.6, 0.6);
259 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
260 eglSwapBuffers(eglDisplay, eglSurface);
261 glClearColor(1.0, 1.0, 1.0, 1.0);
262
263 for (j=0 ; j<10 ; j++) {
264 printf("loop %d / 10 (%d quads / loop)\n", j, quads);
265
266 int nelem = sizeof(quadIndices)/sizeof(quadIndices[0]);
267 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
268 glDrawElements(GL_TRIANGLES, nelem*quads, GL_UNSIGNED_SHORT, indices);
269 eglSwapBuffers(eglDisplay, eglSurface);
270 }
271
272 free(indices);
273 }
274
275