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 <ui/FramebufferNativeWindow.h>
9#include <ui/EGLUtils.h>
10
11#include <stdio.h>
12
13#include <stdlib.h>
14#include <math.h>
15
16using namespace android;
17
18EGLDisplay eglDisplay;
19EGLSurface eglSurface;
20EGLContext eglContext;
21GLuint texture;
22
23#define FIXED_ONE 0x10000
24#define ITERATIONS 50
25
26int init_gl_surface(void);
27void free_gl_surface(void);
28void init_scene(void);
29void render();
30void create_texture(void);
31int 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}
37
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
97void 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_PRESERVED_RESOURCES),
118    X(EGL_SAMPLES),
119    X(EGL_SAMPLE_BUFFERS),
120    X(EGL_SURFACE_TYPE),
121    X(EGL_TRANSPARENT_TYPE),
122    X(EGL_TRANSPARENT_RED_VALUE),
123    X(EGL_TRANSPARENT_GREEN_VALUE),
124    X(EGL_TRANSPARENT_BLUE_VALUE),
125    X(EGL_BIND_TO_TEXTURE_RGB),
126    X(EGL_BIND_TO_TEXTURE_RGBA),
127    X(EGL_MIN_SWAP_INTERVAL),
128    X(EGL_MAX_SWAP_INTERVAL),
129    X(EGL_LUMINANCE_SIZE),
130    X(EGL_ALPHA_MASK_SIZE),
131    X(EGL_COLOR_BUFFER_TYPE),
132    X(EGL_RENDERABLE_TYPE),
133    X(EGL_CONFORMANT),
134   };
135#undef X
136
137    for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
138        EGLint value = -1;
139        EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
140        EGLint error = eglGetError();
141        if (returnVal && error == EGL_SUCCESS) {
142            printf(" %s: ", names[j].name);
143            printf("%d (0x%x)", value, value);
144        }
145    }
146    printf("\n");
147}
148
149static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
150    if (returnVal != EGL_TRUE) {
151        fprintf(stderr, "%s() returned %d\n", op, returnVal);
152    }
153
154    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
155            = eglGetError()) {
156        fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error),
157                error);
158    }
159}
160
161int printEGLConfigurations(EGLDisplay dpy) {
162    EGLint numConfig = 0;
163    EGLint returnVal = eglGetConfigs(dpy, NULL, 0, &numConfig);
164    checkEglError("eglGetConfigs", returnVal);
165    if (!returnVal) {
166        return false;
167    }
168
169    printf("Number of EGL configurations: %d\n", numConfig);
170
171    EGLConfig* configs = (EGLConfig*) malloc(sizeof(EGLConfig) * numConfig);
172    if (! configs) {
173        printf("Could not allocate configs.\n");
174        return false;
175    }
176
177    returnVal = eglGetConfigs(dpy, configs, numConfig, &numConfig);
178    checkEglError("eglGetConfigs", returnVal);
179    if (!returnVal) {
180        free(configs);
181        return false;
182    }
183
184    for(int i = 0; i < numConfig; i++) {
185        printf("Configuration %d\n", i);
186        printEGLConfiguration(dpy, configs[i]);
187    }
188
189    free(configs);
190    return true;
191}
192
193int main(int argc, char **argv)
194{
195    int q;
196    int start, end;
197    printf("Initializing EGL...\n");
198    if(!init_gl_surface())
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
213int init_gl_surface(void)
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 = android_createDisplaySurface();
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
280void 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
293void 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
313void 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
337void 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