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 <ui/FramebufferNativeWindow.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(void);
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 int q;
97 int start, end;
98
99 printf("Initializing EGL...\n");
100
101 if(!init_gl_surface())
102 {
103 printf("GL initialisation failed - exiting\n");
104 return 0;
105 }
106
107 init_scene();
108
109 create_texture();
110
111 printf("Start test...\n");
112
113 render(argc==2 ? atoi(argv[1]) : ITERATIONS);
114
115 free_gl_surface();
116
117 return 0;
118 }
119
init_gl_surface(void)120 int init_gl_surface(void)
121 {
122 EGLint numConfigs = 1;
123 EGLConfig myConfig = {0};
124 EGLint attrib[] =
125 {
126 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
127 EGL_DEPTH_SIZE, 16,
128 EGL_NONE
129 };
130
131 if ( (eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY )
132 {
133 printf("eglGetDisplay failed\n");
134 return 0;
135 }
136
137 if ( eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE )
138 {
139 printf("eglInitialize failed\n");
140 return 0;
141 }
142
143 EGLNativeWindowType window = android_createDisplaySurface();
144 EGLUtils::selectConfigForNativeWindow(eglDisplay, attrib, window, &myConfig);
145
146 if ( (eglSurface = eglCreateWindowSurface(eglDisplay, myConfig,
147 window, 0)) == EGL_NO_SURFACE )
148 {
149 printf("eglCreateWindowSurface failed\n");
150 return 0;
151 }
152
153 if ( (eglContext = eglCreateContext(eglDisplay, myConfig, 0, 0)) == EGL_NO_CONTEXT )
154 {
155 printf("eglCreateContext failed\n");
156 return 0;
157 }
158
159 if ( eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) != EGL_TRUE )
160 {
161 printf("eglMakeCurrent failed\n");
162 return 0;
163 }
164
165 return 1;
166 }
167
free_gl_surface(void)168 void free_gl_surface(void)
169 {
170 if (eglDisplay != EGL_NO_DISPLAY)
171 {
172 eglMakeCurrent( EGL_NO_DISPLAY, EGL_NO_SURFACE,
173 EGL_NO_SURFACE, EGL_NO_CONTEXT );
174 eglDestroyContext( eglDisplay, eglContext );
175 eglDestroySurface( eglDisplay, eglSurface );
176 eglTerminate( eglDisplay );
177 eglDisplay = EGL_NO_DISPLAY;
178 }
179 }
180
init_scene(void)181 void init_scene(void)
182 {
183 glDisable(GL_DITHER);
184 glEnable(GL_CULL_FACE);
185
186 float ratio = 320.0f / 480.0f;
187 glViewport(0, 0, 320, 480);
188
189 glMatrixMode(GL_PROJECTION);
190 glLoadIdentity();
191 glFrustumf(-ratio, ratio, -1, 1, 1, 10);
192
193 glMatrixMode(GL_MODELVIEW);
194 glLoadIdentity();
195 gluLookAt(
196 0, 0, 3, // eye
197 0, 0, 0, // center
198 0, 1, 0); // up
199
200 glEnable(GL_TEXTURE_2D);
201 glEnableClientState(GL_VERTEX_ARRAY);
202 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
203 }
204
create_texture(void)205 void create_texture(void)
206 {
207 const unsigned int on = 0xff0000ff;
208 const unsigned int off = 0xffffffff;
209 const unsigned int pixels[] =
210 {
211 on, off, on, off, on, off, on, off,
212 off, on, off, on, off, on, off, on,
213 on, off, on, off, on, off, on, off,
214 off, on, off, on, off, on, off, on,
215 on, off, on, off, on, off, on, off,
216 off, on, off, on, off, on, off, on,
217 on, off, on, off, on, off, on, off,
218 off, on, off, on, off, on, off, on,
219 };
220 glGenTextures(1, &texture);
221 glBindTexture(GL_TEXTURE_2D, texture);
222 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
223 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
224 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
225 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
226 }
227
render(int quads)228 void render(int quads)
229 {
230 int i, j;
231
232 const GLfloat vertices[] = {
233 -1, -1, 0,
234 1, -1, 0,
235 1, 1, 0,
236 -1, 1, 0
237 };
238
239 const GLfixed texCoords[] = {
240 0, 0,
241 FIXED_ONE, 0,
242 FIXED_ONE, FIXED_ONE,
243 0, FIXED_ONE
244 };
245
246 const GLushort quadIndices[] = { 0, 1, 2, 0, 2, 3 };
247
248
249 GLushort* indices = (GLushort*)malloc(quads*sizeof(quadIndices));
250 for (i=0 ; i<quads ; i++)
251 memcpy(indices+(sizeof(quadIndices)/sizeof(indices[0]))*i, quadIndices, sizeof(quadIndices));
252
253 glVertexPointer(3, GL_FLOAT, 0, vertices);
254 glTexCoordPointer(2, GL_FIXED, 0, texCoords);
255
256 // make sure to do a couple eglSwapBuffers to make sure there are
257 // no problems with the very first ones (who knows)
258 glClearColor(0.4, 0.4, 0.4, 0.4);
259 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
260 eglSwapBuffers(eglDisplay, eglSurface);
261 glClearColor(0.6, 0.6, 0.6, 0.6);
262 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
263 eglSwapBuffers(eglDisplay, eglSurface);
264 glClearColor(1.0, 1.0, 1.0, 1.0);
265
266 for (j=0 ; j<10 ; j++) {
267 printf("loop %d / 10 (%d quads / loop)\n", j, quads);
268
269 int nelem = sizeof(quadIndices)/sizeof(quadIndices[0]);
270 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
271 glDrawElements(GL_TRIANGLES, nelem*quads, GL_UNSIGNED_SHORT, indices);
272 eglSwapBuffers(eglDisplay, eglSurface);
273 }
274
275 free(indices);
276 }
277
278