blob: f18348367d265fdeb5fd3add89fa37222bbc0013 [file] [log] [blame]
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001// 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>
Jack Palevichbc4a4172009-09-24 12:19:05 -07009#include <GLES/glext.h>
10
11#include <ui/FramebufferNativeWindow.h>
Mathias Agopian870b8aa2012-02-24 16:42:46 -080012#include "EGLUtils.h"
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080013
14#include <stdio.h>
15#include <stdlib.h>
16#include <math.h>
Jack Palevichbc4a4172009-09-24 12:19:05 -070017
18using namespace android;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080019
20EGLDisplay eglDisplay;
21EGLSurface eglSurface;
22EGLContext eglContext;
23GLuint texture;
24
25#define FIXED_ONE 0x10000
26#define ITERATIONS 50
27
28int init_gl_surface(void);
29void free_gl_surface(void);
30void init_scene(void);
31void render(int quads);
32void create_texture(void);
33int readTimer(void);
34
35static 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
94int 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
120int init_gl_surface(void)
121{
122 EGLint numConfigs = 1;
123 EGLConfig myConfig = {0};
124 EGLint attrib[] =
125 {
Jack Palevich38d3c2a2009-09-28 18:28:07 -0700126 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800127 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 }
Jack Palevichbc4a4172009-09-24 12:19:05 -0700142
143 EGLNativeWindowType window = android_createDisplaySurface();
144 EGLUtils::selectConfigForNativeWindow(eglDisplay, attrib, window, &myConfig);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800145
146 if ( (eglSurface = eglCreateWindowSurface(eglDisplay, myConfig,
Jack Palevichbc4a4172009-09-24 12:19:05 -0700147 window, 0)) == EGL_NO_SURFACE )
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800148 {
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
168void 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
181void 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
205void 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
228void 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
Jack Palevichbc4a4172009-09-24 12:19:05 -0700246 const GLushort quadIndices[] = { 0, 1, 2, 0, 2, 3 };
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800247
248
Jack Palevichbc4a4172009-09-24 12:19:05 -0700249 GLushort* indices = (GLushort*)malloc(quads*sizeof(quadIndices));
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800250 for (i=0 ; i<quads ; i++)
Jack Palevichbc4a4172009-09-24 12:19:05 -0700251 memcpy(indices+(sizeof(quadIndices)/sizeof(indices[0]))*i, quadIndices, sizeof(quadIndices));
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800252
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
Jack Palevichbc4a4172009-09-24 12:19:05 -0700269 int nelem = sizeof(quadIndices)/sizeof(quadIndices[0]);
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800270 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