1f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich// Simple OpenGL ES 1.x application showing how to initialize and draw something.
2f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
3909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich#include <EGL/egl.h>
4909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
5f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich#include <GLES/gl.h>
6f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich#include <GLES/glext.h>
7f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
86ef57d7b368ebbac5f2b27c36a9032fee1cda8b1Andy McFadden#include <WindowSurface.h>
96ef57d7b368ebbac5f2b27c36a9032fee1cda8b1Andy McFadden#include <EGLUtils.h>
10f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
11909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich#include <stdio.h>
12909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
13f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich#include <stdlib.h>
14f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich#include <math.h>
15f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
16f38bce2387deb10f5685f4a393138b12eec85623Jack Palevichusing namespace android;
17909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
18909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack PalevichEGLDisplay eglDisplay;
19909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack PalevichEGLSurface eglSurface;
20909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack PalevichEGLContext eglContext;
21909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack PalevichGLuint texture;
22909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
23f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich#define FIXED_ONE 0x10000
24909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich#define ITERATIONS 50
25909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
266ef57d7b368ebbac5f2b27c36a9032fee1cda8b1Andy McFaddenint init_gl_surface(const WindowSurface& windowSurface);
27909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevichvoid free_gl_surface(void);
28909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevichvoid init_scene(void);
29909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevichvoid render();
30f38bce2387deb10f5685f4a393138b12eec85623Jack Palevichvoid create_texture(void);
31909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevichint readTimer(void);
32909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
33909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevichstatic void printGLString(const char *name, GLenum s) {
34909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    const char *v = (const char *) glGetString(s);
35909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    fprintf(stderr, "GL %s = %s\n", name, v);
36909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich}
37f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
38f38bce2387deb10f5685f4a393138b12eec85623Jack Palevichstatic void gluLookAt(float eyeX, float eyeY, float eyeZ,
39f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich        float centerX, float centerY, float centerZ, float upX, float upY,
40f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich        float upZ)
41f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich{
42f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    // See the OpenGL GLUT documentation for gluLookAt for a description
43f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    // of the algorithm. We implement it in a straightforward way:
44f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
45f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    float fx = centerX - eyeX;
46f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    float fy = centerY - eyeY;
47f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    float fz = centerZ - eyeZ;
48f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
49f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    // Normalize f
50f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    float rlf = 1.0f / sqrtf(fx*fx + fy*fy + fz*fz);
51f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    fx *= rlf;
52f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    fy *= rlf;
53f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    fz *= rlf;
54f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
55f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    // Normalize up
56f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    float rlup = 1.0f / sqrtf(upX*upX + upY*upY + upZ*upZ);
57f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    upX *= rlup;
58f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    upY *= rlup;
59f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    upZ *= rlup;
60f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
61f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    // compute s = f x up (x means "cross product")
62f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
63f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    float sx = fy * upZ - fz * upY;
64f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    float sy = fz * upX - fx * upZ;
65f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    float sz = fx * upY - fy * upX;
66f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
67f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    // compute u = s x f
68f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    float ux = sy * fz - sz * fy;
69f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    float uy = sz * fx - sx * fz;
70f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    float uz = sx * fy - sy * fx;
71f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
72f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    float m[16] ;
73f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    m[0] = sx;
74f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    m[1] = ux;
75f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    m[2] = -fx;
76f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    m[3] = 0.0f;
77f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
78f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    m[4] = sy;
79f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    m[5] = uy;
80f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    m[6] = -fy;
81f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    m[7] = 0.0f;
82f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
83f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    m[8] = sz;
84f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    m[9] = uz;
85f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    m[10] = -fz;
86f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    m[11] = 0.0f;
87f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
88f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    m[12] = 0.0f;
89f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    m[13] = 0.0f;
90f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    m[14] = 0.0f;
91f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    m[15] = 1.0f;
92f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
93f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glMultMatrixf(m);
94f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glTranslatef(-eyeX, -eyeY, -eyeZ);
95f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich}
96f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
97f38bce2387deb10f5685f4a393138b12eec85623Jack Palevichvoid printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {
98f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
99f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich#define X(VAL) {VAL, #VAL}
100f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    struct {EGLint attribute; const char* name;} names[] = {
101f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_BUFFER_SIZE),
102f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_ALPHA_SIZE),
103f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_BLUE_SIZE),
104f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_GREEN_SIZE),
105f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_RED_SIZE),
106f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_DEPTH_SIZE),
107f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_STENCIL_SIZE),
108f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_CONFIG_CAVEAT),
109f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_CONFIG_ID),
110f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_LEVEL),
111f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_MAX_PBUFFER_HEIGHT),
112f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_MAX_PBUFFER_PIXELS),
113f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_MAX_PBUFFER_WIDTH),
114f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_NATIVE_RENDERABLE),
115f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_NATIVE_VISUAL_ID),
116f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_NATIVE_VISUAL_TYPE),
117f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_SAMPLES),
118f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_SAMPLE_BUFFERS),
119f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_SURFACE_TYPE),
120f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_TRANSPARENT_TYPE),
121f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_TRANSPARENT_RED_VALUE),
122f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_TRANSPARENT_GREEN_VALUE),
123f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_TRANSPARENT_BLUE_VALUE),
124f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_BIND_TO_TEXTURE_RGB),
125f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_BIND_TO_TEXTURE_RGBA),
126f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_MIN_SWAP_INTERVAL),
127f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_MAX_SWAP_INTERVAL),
128f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_LUMINANCE_SIZE),
129f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_ALPHA_MASK_SIZE),
130f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_COLOR_BUFFER_TYPE),
131f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_RENDERABLE_TYPE),
132f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    X(EGL_CONFORMANT),
133f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich   };
134f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich#undef X
135f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
136f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
137f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich        EGLint value = -1;
138f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich        EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
139f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich        EGLint error = eglGetError();
140f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich        if (returnVal && error == EGL_SUCCESS) {
141f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            printf(" %s: ", names[j].name);
142f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            printf("%d (0x%x)", value, value);
143f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich        }
144f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    }
145f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    printf("\n");
146f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich}
147f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
148f38bce2387deb10f5685f4a393138b12eec85623Jack Palevichstatic void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
149f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    if (returnVal != EGL_TRUE) {
150f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich        fprintf(stderr, "%s() returned %d\n", op, returnVal);
151f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    }
152f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
153f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
154f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            = eglGetError()) {
155f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich        fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error),
156f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich                error);
157f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    }
158f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich}
159f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
160f38bce2387deb10f5685f4a393138b12eec85623Jack Palevichint printEGLConfigurations(EGLDisplay dpy) {
161f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    EGLint numConfig = 0;
162f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    EGLint returnVal = eglGetConfigs(dpy, NULL, 0, &numConfig);
163f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    checkEglError("eglGetConfigs", returnVal);
164f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    if (!returnVal) {
165f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich        return false;
166f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    }
167f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
168f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    printf("Number of EGL configurations: %d\n", numConfig);
169f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
170f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    EGLConfig* configs = (EGLConfig*) malloc(sizeof(EGLConfig) * numConfig);
171f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    if (! configs) {
172f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich        printf("Could not allocate configs.\n");
173f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich        return false;
174f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    }
175f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
176f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    returnVal = eglGetConfigs(dpy, configs, numConfig, &numConfig);
177f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    checkEglError("eglGetConfigs", returnVal);
178f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    if (!returnVal) {
179f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich        free(configs);
180f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich        return false;
181f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    }
182f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
183f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    for(int i = 0; i < numConfig; i++) {
184f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich        printf("Configuration %d\n", i);
185f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich        printEGLConfiguration(dpy, configs[i]);
186f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    }
187f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
188f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    free(configs);
189f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    return true;
190f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich}
191f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
192909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevichint main(int argc, char **argv)
193909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich{
194909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    int q;
195909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    int start, end;
196f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    printf("Initializing EGL...\n");
1976ef57d7b368ebbac5f2b27c36a9032fee1cda8b1Andy McFadden    WindowSurface windowSurface;
1986ef57d7b368ebbac5f2b27c36a9032fee1cda8b1Andy McFadden    if(!init_gl_surface(windowSurface))
199909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    {
200909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        printf("GL initialisation failed - exiting\n");
201909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        return 0;
202909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    }
203909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    init_scene();
204909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    create_texture();
205f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    printf("Running...\n");
206f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    while(true) {
207f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich        render();
208f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    }
209909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    free_gl_surface();
210909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    return 0;
211909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich}
212909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
2136ef57d7b368ebbac5f2b27c36a9032fee1cda8b1Andy McFaddenint init_gl_surface(const WindowSurface& windowSurface)
214909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich{
215909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    EGLint numConfigs = 1;
216909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    EGLConfig myConfig = {0};
217909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    EGLint attrib[] =
218909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    {
219909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich            EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
220909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich            EGL_NONE
221909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    };
222909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
223909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    if ( (eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY )
224909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    {
225909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        printf("eglGetDisplay failed\n");
226909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        return 0;
227909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    }
228909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
229909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    if ( eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE )
230909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    {
231909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        printf("eglInitialize failed\n");
232909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        return 0;
233f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    }
234f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
235f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    if (! printEGLConfigurations(eglDisplay)) {
236f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich        printf("printEGLConfigurations failed.\n");
237f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich        return 0;
238909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    }
239909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
2406ef57d7b368ebbac5f2b27c36a9032fee1cda8b1Andy McFadden    EGLNativeWindowType window = windowSurface.getSurface();
241909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    EGLUtils::selectConfigForNativeWindow(eglDisplay, attrib, window, &myConfig);
242909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
243f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    if ( (eglSurface = eglCreateWindowSurface(eglDisplay, myConfig,
244909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich            window, 0)) == EGL_NO_SURFACE )
245909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    {
246909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        printf("eglCreateWindowSurface failed\n");
247909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        return 0;
248909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    }
249909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
250909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    if ( (eglContext = eglCreateContext(eglDisplay, myConfig, 0, 0)) == EGL_NO_CONTEXT )
251909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    {
252909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        printf("eglCreateContext failed\n");
253909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        return 0;
254909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    }
255909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
256909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    if ( eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) != EGL_TRUE )
257909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    {
258909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        printf("eglMakeCurrent failed\n");
259909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        return 0;
260909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    }
261909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
262909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    int w, h;
263909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
264909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    eglQuerySurface(eglDisplay, eglSurface, EGL_WIDTH, &w);
265909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    checkEglError("eglQuerySurface");
266909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    eglQuerySurface(eglDisplay, eglSurface, EGL_HEIGHT, &h);
267909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    checkEglError("eglQuerySurface");
268909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    GLint dim = w < h ? w : h;
269909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
270909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
271909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
272909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    printGLString("Version", GL_VERSION);
273909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    printGLString("Vendor", GL_VENDOR);
274909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    printGLString("Renderer", GL_RENDERER);
275909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    printGLString("Extensions", GL_EXTENSIONS);
276909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
277909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    return 1;
278909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich}
279909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
280909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevichvoid free_gl_surface(void)
281909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich{
282909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    if (eglDisplay != EGL_NO_DISPLAY)
283909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    {
284909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        eglMakeCurrent( EGL_NO_DISPLAY, EGL_NO_SURFACE,
285909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich                EGL_NO_SURFACE, EGL_NO_CONTEXT );
286909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        eglDestroyContext( eglDisplay, eglContext );
287909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        eglDestroySurface( eglDisplay, eglSurface );
288909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        eglTerminate( eglDisplay );
289909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        eglDisplay = EGL_NO_DISPLAY;
290909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    }
291909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich}
292909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
293909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevichvoid init_scene(void)
294909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich{
295f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glDisable(GL_DITHER);
296f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glEnable(GL_CULL_FACE);
297f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    float ratio = 320.0f / 480.0f;
298f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glViewport(0, 0, 320, 480);
299f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glMatrixMode(GL_PROJECTION);
300f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glLoadIdentity();
301f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glFrustumf(-ratio, ratio, -1, 1, 1, 10);
302909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    glMatrixMode(GL_MODELVIEW);
303f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glLoadIdentity();
304f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    gluLookAt(
305f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            0, 0, 3,  // eye
306f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            0, 0, 0,  // center
307f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            0, 1, 0); // up
308909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    glEnable(GL_TEXTURE_2D);
309909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    glEnableClientState(GL_VERTEX_ARRAY);
310f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
311909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich}
312909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
313909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevichvoid create_texture(void)
314909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich{
315f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    const unsigned int on = 0xff0000ff;
316f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    const unsigned int off = 0xffffffff;
317f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    const unsigned int pixels[] =
318f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    {
319f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            on, off, on, off, on, off, on, off,
320f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            off, on, off, on, off, on, off, on,
321f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            on, off, on, off, on, off, on, off,
322f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            off, on, off, on, off, on, off, on,
323f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            on, off, on, off, on, off, on, off,
324f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            off, on, off, on, off, on, off, on,
325f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            on, off, on, off, on, off, on, off,
326f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            off, on, off, on, off, on, off, on,
327909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    };
328909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
329909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    glGenTextures(1, &texture);
330909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    glBindTexture(GL_TEXTURE_2D, texture);
331909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
332909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
333909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
334909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
335909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich}
336909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
337909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevichvoid render()
338909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich{
339f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    int i, j;
340909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    int quads = 1;
341909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
342909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    const GLfloat vertices[] = {
343909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich            -1,  -1,  0,
344909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich             1,  -1,  0,
345909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich             1,   1,  0,
346909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich            -1,   1,  0
347909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    };
348909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
349909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    const GLfixed texCoords[] = {
350909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich            0,            0,
351909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich            FIXED_ONE,    0,
352909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich            FIXED_ONE,    FIXED_ONE,
353909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich            0,            FIXED_ONE
354909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    };
355909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
356f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    const GLushort indices[] = { 0, 1, 2,  0, 2, 3 };
357f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
358909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    glVertexPointer(3, GL_FLOAT, 0, vertices);
359909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    glTexCoordPointer(2, GL_FIXED, 0, texCoords);
360f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glClearColor(1.0, 1.0, 1.0, 1.0);
361f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    int nelem = sizeof(indices)/sizeof(indices[0]);
362f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
363f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices);
364909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    eglSwapBuffers(eglDisplay, eglSurface);
365909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich}
366