blob: 0cc8398a4adaeb7ffa8026b72b0a4fcc91a1ffba [file] [log] [blame]
Jack Palevich5ffd6242009-09-30 14:17:12 -07001// Simple OpenGL ES 1.x application showing how to initialize and draw something.
2
Jack Palevich1c875582009-12-24 11:09:56 +08003#include <EGL/egl.h>
4
Jack Palevich5ffd6242009-09-30 14:17:12 -07005#include <GLES/gl.h>
6#include <GLES/glext.h>
7
8#include <ui/FramebufferNativeWindow.h>
9#include <ui/EGLUtils.h>
10
Jack Palevich1c875582009-12-24 11:09:56 +080011#include <stdio.h>
12
Jack Palevich5ffd6242009-09-30 14:17:12 -070013#include <stdlib.h>
14#include <math.h>
15
16using namespace android;
Jack Palevich1c875582009-12-24 11:09:56 +080017
18EGLDisplay eglDisplay;
19EGLSurface eglSurface;
20EGLContext eglContext;
21GLuint texture;
22
Jack Palevich5ffd6242009-09-30 14:17:12 -070023#define FIXED_ONE 0x10000
Jack Palevich1c875582009-12-24 11:09:56 +080024#define ITERATIONS 50
25
26int init_gl_surface(void);
27void free_gl_surface(void);
28void init_scene(void);
29void render();
Jack Palevich5ffd6242009-09-30 14:17:12 -070030void create_texture(void);
Jack Palevich1c875582009-12-24 11:09:56 +080031int readTimer(void);
32
33static 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}
Jack Palevich5ffd6242009-09-30 14:17:12 -070037
38static 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
Jack Palevich5ffd6242009-09-30 14:17:12 -070097void 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),
Jack Palevich5ffd6242009-09-30 14:17:12 -0700117 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
148static 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
160int 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}
Jack Palevich1c875582009-12-24 11:09:56 +0800191
192int main(int argc, char **argv)
193{
Jack Palevich5ffd6242009-09-30 14:17:12 -0700194 int q;
Jack Palevich1c875582009-12-24 11:09:56 +0800195 int start, end;
Jack Palevich5ffd6242009-09-30 14:17:12 -0700196 printf("Initializing EGL...\n");
Jack Palevich1c875582009-12-24 11:09:56 +0800197 if(!init_gl_surface())
198 {
199 printf("GL initialisation failed - exiting\n");
200 return 0;
201 }
202 init_scene();
203 create_texture();
Jack Palevich5ffd6242009-09-30 14:17:12 -0700204 printf("Running...\n");
Jack Palevich5ffd6242009-09-30 14:17:12 -0700205 while(true) {
206 render();
Jack Palevich5ffd6242009-09-30 14:17:12 -0700207 }
Jack Palevich1c875582009-12-24 11:09:56 +0800208 free_gl_surface();
209 return 0;
210}
211
212int init_gl_surface(void)
213{
214 EGLint numConfigs = 1;
215 EGLConfig myConfig = {0};
216 EGLint attrib[] =
217 {
218 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
219 EGL_NONE
220 };
221
222 if ( (eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY )
223 {
224 printf("eglGetDisplay failed\n");
225 return 0;
226 }
227
228 if ( eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE )
229 {
230 printf("eglInitialize failed\n");
231 return 0;
Jack Palevich5ffd6242009-09-30 14:17:12 -0700232 }
233
234 if (! printEGLConfigurations(eglDisplay)) {
235 printf("printEGLConfigurations failed.\n");
236 return 0;
Jack Palevich1c875582009-12-24 11:09:56 +0800237 }
238
239 EGLNativeWindowType window = android_createDisplaySurface();
240 EGLUtils::selectConfigForNativeWindow(eglDisplay, attrib, window, &myConfig);
241
Jack Palevich5ffd6242009-09-30 14:17:12 -0700242 if ( (eglSurface = eglCreateWindowSurface(eglDisplay, myConfig,
Jack Palevich1c875582009-12-24 11:09:56 +0800243 window, 0)) == EGL_NO_SURFACE )
244 {
245 printf("eglCreateWindowSurface failed\n");
246 return 0;
247 }
248
249 if ( (eglContext = eglCreateContext(eglDisplay, myConfig, 0, 0)) == EGL_NO_CONTEXT )
250 {
251 printf("eglCreateContext failed\n");
252 return 0;
253 }
254
255 if ( eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) != EGL_TRUE )
256 {
257 printf("eglMakeCurrent failed\n");
258 return 0;
259 }
260
261 int w, h;
262
263 eglQuerySurface(eglDisplay, eglSurface, EGL_WIDTH, &w);
264 checkEglError("eglQuerySurface");
265 eglQuerySurface(eglDisplay, eglSurface, EGL_HEIGHT, &h);
266 checkEglError("eglQuerySurface");
267 GLint dim = w < h ? w : h;
268
269 fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
270
271 printGLString("Version", GL_VERSION);
272 printGLString("Vendor", GL_VENDOR);
273 printGLString("Renderer", GL_RENDERER);
274 printGLString("Extensions", GL_EXTENSIONS);
275
276 return 1;
277}
278
279void free_gl_surface(void)
280{
281 if (eglDisplay != EGL_NO_DISPLAY)
282 {
283 eglMakeCurrent( EGL_NO_DISPLAY, EGL_NO_SURFACE,
284 EGL_NO_SURFACE, EGL_NO_CONTEXT );
285 eglDestroyContext( eglDisplay, eglContext );
286 eglDestroySurface( eglDisplay, eglSurface );
287 eglTerminate( eglDisplay );
288 eglDisplay = EGL_NO_DISPLAY;
289 }
290}
291
292void init_scene(void)
293{
Jack Palevich5ffd6242009-09-30 14:17:12 -0700294 glDisable(GL_DITHER);
295 glEnable(GL_CULL_FACE);
Jack Palevich5ffd6242009-09-30 14:17:12 -0700296 float ratio = 320.0f / 480.0f;
297 glViewport(0, 0, 320, 480);
Jack Palevich5ffd6242009-09-30 14:17:12 -0700298 glMatrixMode(GL_PROJECTION);
299 glLoadIdentity();
300 glFrustumf(-ratio, ratio, -1, 1, 1, 10);
Jack Palevich1c875582009-12-24 11:09:56 +0800301 glMatrixMode(GL_MODELVIEW);
Jack Palevich5ffd6242009-09-30 14:17:12 -0700302 glLoadIdentity();
303 gluLookAt(
304 0, 0, 3, // eye
305 0, 0, 0, // center
306 0, 1, 0); // up
Jack Palevich1c875582009-12-24 11:09:56 +0800307 glEnable(GL_TEXTURE_2D);
308 glEnableClientState(GL_VERTEX_ARRAY);
Jack Palevich5ffd6242009-09-30 14:17:12 -0700309 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
Jack Palevich1c875582009-12-24 11:09:56 +0800310}
311
312void create_texture(void)
313{
Jack Palevich5ffd6242009-09-30 14:17:12 -0700314 const unsigned int on = 0xff0000ff;
315 const unsigned int off = 0xffffffff;
316 const unsigned int pixels[] =
317 {
318 on, off, on, off, on, off, on, off,
319 off, on, off, on, off, on, off, on,
320 on, off, on, off, on, off, on, off,
321 off, on, off, on, off, on, off, on,
322 on, off, on, off, on, off, on, off,
323 off, on, off, on, off, on, off, on,
324 on, off, on, off, on, off, on, off,
325 off, on, off, on, off, on, off, on,
Jack Palevich1c875582009-12-24 11:09:56 +0800326 };
327
328 glGenTextures(1, &texture);
329 glBindTexture(GL_TEXTURE_2D, texture);
330 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
331 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
332 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
333 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
334}
335
336void render()
337{
Jack Palevich5ffd6242009-09-30 14:17:12 -0700338 int i, j;
Jack Palevich1c875582009-12-24 11:09:56 +0800339 int quads = 1;
340
341 const GLfloat vertices[] = {
342 -1, -1, 0,
343 1, -1, 0,
344 1, 1, 0,
345 -1, 1, 0
346 };
347
348 const GLfixed texCoords[] = {
349 0, 0,
350 FIXED_ONE, 0,
351 FIXED_ONE, FIXED_ONE,
352 0, FIXED_ONE
353 };
354
Jack Palevich5ffd6242009-09-30 14:17:12 -0700355 const GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
Jack Palevich1c875582009-12-24 11:09:56 +0800356
357 glVertexPointer(3, GL_FLOAT, 0, vertices);
Jack Palevich5ffd6242009-09-30 14:17:12 -0700358 glTexCoordPointer(2, GL_FIXED, 0, texCoords);
Jack Palevich5ffd6242009-09-30 14:17:12 -0700359 glClearColor(1.0, 1.0, 1.0, 1.0);
Jack Palevich5ffd6242009-09-30 14:17:12 -0700360 int nelem = sizeof(indices)/sizeof(indices[0]);
361 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
362 glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices);
Jack Palevich1c875582009-12-24 11:09:56 +0800363 eglSwapBuffers(eglDisplay, eglSurface);
364}