1 // Simple OpenGL ES 1.x application showing how to initialize and draw something.
2
3 #include <EGL/egl.h>
4
5 #include <GLES/gl.h>
6 #include <GLES/glext.h>
7
8 #include <WindowSurface.h>
9 #include <EGLUtils.h>
10
11 #include <stdio.h>
12
13 #include <stdlib.h>
14 #include <math.h>
15
16 using namespace android;
17
18 EGLDisplay eglDisplay;
19 EGLSurface eglSurface;
20 EGLContext eglContext;
21 GLuint texture;
22
23 #define FIXED_ONE 0x10000
24 #define ITERATIONS 50
25
26 int init_gl_surface(const WindowSurface& windowSurface);
27 void free_gl_surface(void);
28 void init_scene(void);
29 void render();
30 void create_texture(void);
31 int readTimer(void);
32
printGLString(const char * name,GLenum s)33 static void printGLString(const char *name, GLenum s) {
34 const char *v = (const char *) glGetString(s);
35 fprintf(stderr, "GL %s = %s\n", name, v);
36 }
37
gluLookAt(float eyeX,float eyeY,float eyeZ,float centerX,float centerY,float centerZ,float upX,float upY,float upZ)38 static void gluLookAt(float eyeX, float eyeY, float eyeZ,
39 float centerX, float centerY, float centerZ, float upX, float upY,
40 float upZ)
41 {
42 // See the OpenGL GLUT documentation for gluLookAt for a description
43 // of the algorithm. We implement it in a straightforward way:
44
45 float fx = centerX - eyeX;
46 float fy = centerY - eyeY;
47 float fz = centerZ - eyeZ;
48
49 // Normalize f
50 float rlf = 1.0f / sqrtf(fx*fx + fy*fy + fz*fz);
51 fx *= rlf;
52 fy *= rlf;
53 fz *= rlf;
54
55 // Normalize up
56 float rlup = 1.0f / sqrtf(upX*upX + upY*upY + upZ*upZ);
57 upX *= rlup;
58 upY *= rlup;
59 upZ *= rlup;
60
61 // compute s = f x up (x means "cross product")
62
63 float sx = fy * upZ - fz * upY;
64 float sy = fz * upX - fx * upZ;
65 float sz = fx * upY - fy * upX;
66
67 // compute u = s x f
68 float ux = sy * fz - sz * fy;
69 float uy = sz * fx - sx * fz;
70 float uz = sx * fy - sy * fx;
71
72 float m[16] ;
73 m[0] = sx;
74 m[1] = ux;
75 m[2] = -fx;
76 m[3] = 0.0f;
77
78 m[4] = sy;
79 m[5] = uy;
80 m[6] = -fy;
81 m[7] = 0.0f;
82
83 m[8] = sz;
84 m[9] = uz;
85 m[10] = -fz;
86 m[11] = 0.0f;
87
88 m[12] = 0.0f;
89 m[13] = 0.0f;
90 m[14] = 0.0f;
91 m[15] = 1.0f;
92
93 glMultMatrixf(m);
94 glTranslatef(-eyeX, -eyeY, -eyeZ);
95 }
96
printEGLConfiguration(EGLDisplay dpy,EGLConfig config)97 void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {
98
99 #define X(VAL) {VAL, #VAL}
100 struct {EGLint attribute; const char* name;} names[] = {
101 X(EGL_BUFFER_SIZE),
102 X(EGL_ALPHA_SIZE),
103 X(EGL_BLUE_SIZE),
104 X(EGL_GREEN_SIZE),
105 X(EGL_RED_SIZE),
106 X(EGL_DEPTH_SIZE),
107 X(EGL_STENCIL_SIZE),
108 X(EGL_CONFIG_CAVEAT),
109 X(EGL_CONFIG_ID),
110 X(EGL_LEVEL),
111 X(EGL_MAX_PBUFFER_HEIGHT),
112 X(EGL_MAX_PBUFFER_PIXELS),
113 X(EGL_MAX_PBUFFER_WIDTH),
114 X(EGL_NATIVE_RENDERABLE),
115 X(EGL_NATIVE_VISUAL_ID),
116 X(EGL_NATIVE_VISUAL_TYPE),
117 X(EGL_SAMPLES),
118 X(EGL_SAMPLE_BUFFERS),
119 X(EGL_SURFACE_TYPE),
120 X(EGL_TRANSPARENT_TYPE),
121 X(EGL_TRANSPARENT_RED_VALUE),
122 X(EGL_TRANSPARENT_GREEN_VALUE),
123 X(EGL_TRANSPARENT_BLUE_VALUE),
124 X(EGL_BIND_TO_TEXTURE_RGB),
125 X(EGL_BIND_TO_TEXTURE_RGBA),
126 X(EGL_MIN_SWAP_INTERVAL),
127 X(EGL_MAX_SWAP_INTERVAL),
128 X(EGL_LUMINANCE_SIZE),
129 X(EGL_ALPHA_MASK_SIZE),
130 X(EGL_COLOR_BUFFER_TYPE),
131 X(EGL_RENDERABLE_TYPE),
132 X(EGL_CONFORMANT),
133 };
134 #undef X
135
136 for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
137 EGLint value = -1;
138 EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
139 EGLint error = eglGetError();
140 if (returnVal && error == EGL_SUCCESS) {
141 printf(" %s: ", names[j].name);
142 printf("%d (0x%x)", value, value);
143 }
144 }
145 printf("\n");
146 }
147
checkEglError(const char * op,EGLBoolean returnVal=EGL_TRUE)148 static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
149 if (returnVal != EGL_TRUE) {
150 fprintf(stderr, "%s() returned %d\n", op, returnVal);
151 }
152
153 for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
154 = eglGetError()) {
155 fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error),
156 error);
157 }
158 }
159
printEGLConfigurations(EGLDisplay dpy)160 int printEGLConfigurations(EGLDisplay dpy) {
161 EGLint numConfig = 0;
162 EGLint returnVal = eglGetConfigs(dpy, NULL, 0, &numConfig);
163 checkEglError("eglGetConfigs", returnVal);
164 if (!returnVal) {
165 return false;
166 }
167
168 printf("Number of EGL configurations: %d\n", numConfig);
169
170 EGLConfig* configs = (EGLConfig*) malloc(sizeof(EGLConfig) * numConfig);
171 if (! configs) {
172 printf("Could not allocate configs.\n");
173 return false;
174 }
175
176 returnVal = eglGetConfigs(dpy, configs, numConfig, &numConfig);
177 checkEglError("eglGetConfigs", returnVal);
178 if (!returnVal) {
179 free(configs);
180 return false;
181 }
182
183 for(int i = 0; i < numConfig; i++) {
184 printf("Configuration %d\n", i);
185 printEGLConfiguration(dpy, configs[i]);
186 }
187
188 free(configs);
189 return true;
190 }
191
main(int argc,char ** argv)192 int main(int argc, char **argv)
193 {
194 int q;
195 int start, end;
196 printf("Initializing EGL...\n");
197 WindowSurface windowSurface;
198 if(!init_gl_surface(windowSurface))
199 {
200 printf("GL initialisation failed - exiting\n");
201 return 0;
202 }
203 init_scene();
204 create_texture();
205 printf("Running...\n");
206 while(true) {
207 render();
208 }
209 free_gl_surface();
210 return 0;
211 }
212
init_gl_surface(const WindowSurface & windowSurface)213 int init_gl_surface(const WindowSurface& windowSurface)
214 {
215 EGLint numConfigs = 1;
216 EGLConfig myConfig = {0};
217 EGLint attrib[] =
218 {
219 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
220 EGL_NONE
221 };
222
223 if ( (eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY )
224 {
225 printf("eglGetDisplay failed\n");
226 return 0;
227 }
228
229 if ( eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE )
230 {
231 printf("eglInitialize failed\n");
232 return 0;
233 }
234
235 if (! printEGLConfigurations(eglDisplay)) {
236 printf("printEGLConfigurations failed.\n");
237 return 0;
238 }
239
240 EGLNativeWindowType window = windowSurface.getSurface();
241 EGLUtils::selectConfigForNativeWindow(eglDisplay, attrib, window, &myConfig);
242
243 if ( (eglSurface = eglCreateWindowSurface(eglDisplay, myConfig,
244 window, 0)) == EGL_NO_SURFACE )
245 {
246 printf("eglCreateWindowSurface failed\n");
247 return 0;
248 }
249
250 if ( (eglContext = eglCreateContext(eglDisplay, myConfig, 0, 0)) == EGL_NO_CONTEXT )
251 {
252 printf("eglCreateContext failed\n");
253 return 0;
254 }
255
256 if ( eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) != EGL_TRUE )
257 {
258 printf("eglMakeCurrent failed\n");
259 return 0;
260 }
261
262 int w, h;
263
264 eglQuerySurface(eglDisplay, eglSurface, EGL_WIDTH, &w);
265 checkEglError("eglQuerySurface");
266 eglQuerySurface(eglDisplay, eglSurface, EGL_HEIGHT, &h);
267 checkEglError("eglQuerySurface");
268 GLint dim = w < h ? w : h;
269
270 fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
271
272 printGLString("Version", GL_VERSION);
273 printGLString("Vendor", GL_VENDOR);
274 printGLString("Renderer", GL_RENDERER);
275 printGLString("Extensions", GL_EXTENSIONS);
276
277 return 1;
278 }
279
free_gl_surface(void)280 void free_gl_surface(void)
281 {
282 if (eglDisplay != EGL_NO_DISPLAY)
283 {
284 eglMakeCurrent( EGL_NO_DISPLAY, EGL_NO_SURFACE,
285 EGL_NO_SURFACE, EGL_NO_CONTEXT );
286 eglDestroyContext( eglDisplay, eglContext );
287 eglDestroySurface( eglDisplay, eglSurface );
288 eglTerminate( eglDisplay );
289 eglDisplay = EGL_NO_DISPLAY;
290 }
291 }
292
init_scene(void)293 void init_scene(void)
294 {
295 glDisable(GL_DITHER);
296 glEnable(GL_CULL_FACE);
297 float ratio = 320.0f / 480.0f;
298 glViewport(0, 0, 320, 480);
299 glMatrixMode(GL_PROJECTION);
300 glLoadIdentity();
301 glFrustumf(-ratio, ratio, -1, 1, 1, 10);
302 glMatrixMode(GL_MODELVIEW);
303 glLoadIdentity();
304 gluLookAt(
305 0, 0, 3, // eye
306 0, 0, 0, // center
307 0, 1, 0); // up
308 glEnable(GL_TEXTURE_2D);
309 glEnableClientState(GL_VERTEX_ARRAY);
310 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
311 }
312
create_texture(void)313 void create_texture(void)
314 {
315 const unsigned int on = 0xff0000ff;
316 const unsigned int off = 0xffffffff;
317 const unsigned int pixels[] =
318 {
319 on, off, on, off, on, off, on, off,
320 off, on, off, on, off, on, off, on,
321 on, off, on, off, on, off, on, off,
322 off, on, off, on, off, on, off, on,
323 on, off, on, off, on, off, on, off,
324 off, on, off, on, off, on, off, on,
325 on, off, on, off, on, off, on, off,
326 off, on, off, on, off, on, off, on,
327 };
328
329 glGenTextures(1, &texture);
330 glBindTexture(GL_TEXTURE_2D, texture);
331 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
332 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
333 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
334 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
335 }
336
render()337 void render()
338 {
339 int i, j;
340 int quads = 1;
341
342 const GLfloat vertices[] = {
343 -1, -1, 0,
344 1, -1, 0,
345 1, 1, 0,
346 -1, 1, 0
347 };
348
349 const GLfixed texCoords[] = {
350 0, 0,
351 FIXED_ONE, 0,
352 FIXED_ONE, FIXED_ONE,
353 0, FIXED_ONE
354 };
355
356 const GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
357
358 glVertexPointer(3, GL_FLOAT, 0, vertices);
359 glTexCoordPointer(2, GL_FIXED, 0, texCoords);
360 glClearColor(1.0, 1.0, 1.0, 1.0);
361 int nelem = sizeof(indices)/sizeof(indices[0]);
362 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
363 glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices);
364 eglSwapBuffers(eglDisplay, eglSurface);
365 }
366