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