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
8f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich#include <ui/FramebufferNativeWindow.h>
9870b8aa15cb5c722b5d8eb7726eaa5f1a7c23d69Mathias Agopian#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
26909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevichint init_gl_surface(void);
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");
197909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    if(!init_gl_surface())
198909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    {
199909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        printf("GL initialisation failed - exiting\n");
200909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        return 0;
201909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    }
202909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    init_scene();
203909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    create_texture();
204f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    printf("Running...\n");
205f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    while(true) {
206f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich        render();
207f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    }
208909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    free_gl_surface();
209909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    return 0;
210909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich}
211909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
212909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevichint init_gl_surface(void)
213909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich{
214909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    EGLint numConfigs = 1;
215909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    EGLConfig myConfig = {0};
216909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    EGLint attrib[] =
217909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    {
218909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich            EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
219909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich            EGL_NONE
220909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    };
221909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
222909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    if ( (eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY )
223909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    {
224909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        printf("eglGetDisplay failed\n");
225909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        return 0;
226909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    }
227909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
228909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    if ( eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE )
229909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    {
230909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        printf("eglInitialize failed\n");
231909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        return 0;
232f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    }
233f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
234f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    if (! printEGLConfigurations(eglDisplay)) {
235f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich        printf("printEGLConfigurations failed.\n");
236f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich        return 0;
237909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    }
238909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
239909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    EGLNativeWindowType window = android_createDisplaySurface();
240909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    EGLUtils::selectConfigForNativeWindow(eglDisplay, attrib, window, &myConfig);
241909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
242f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    if ( (eglSurface = eglCreateWindowSurface(eglDisplay, myConfig,
243909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich            window, 0)) == EGL_NO_SURFACE )
244909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    {
245909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        printf("eglCreateWindowSurface failed\n");
246909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        return 0;
247909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    }
248909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
249909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    if ( (eglContext = eglCreateContext(eglDisplay, myConfig, 0, 0)) == EGL_NO_CONTEXT )
250909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    {
251909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        printf("eglCreateContext failed\n");
252909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        return 0;
253909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    }
254909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
255909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    if ( eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) != EGL_TRUE )
256909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    {
257909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        printf("eglMakeCurrent failed\n");
258909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        return 0;
259909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    }
260909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
261909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    int w, h;
262909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
263909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    eglQuerySurface(eglDisplay, eglSurface, EGL_WIDTH, &w);
264909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    checkEglError("eglQuerySurface");
265909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    eglQuerySurface(eglDisplay, eglSurface, EGL_HEIGHT, &h);
266909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    checkEglError("eglQuerySurface");
267909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    GLint dim = w < h ? w : h;
268909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
269909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
270909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
271909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    printGLString("Version", GL_VERSION);
272909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    printGLString("Vendor", GL_VENDOR);
273909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    printGLString("Renderer", GL_RENDERER);
274909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    printGLString("Extensions", GL_EXTENSIONS);
275909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
276909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    return 1;
277909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich}
278909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
279909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevichvoid free_gl_surface(void)
280909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich{
281909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    if (eglDisplay != EGL_NO_DISPLAY)
282909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    {
283909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        eglMakeCurrent( EGL_NO_DISPLAY, EGL_NO_SURFACE,
284909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich                EGL_NO_SURFACE, EGL_NO_CONTEXT );
285909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        eglDestroyContext( eglDisplay, eglContext );
286909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        eglDestroySurface( eglDisplay, eglSurface );
287909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        eglTerminate( eglDisplay );
288909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich        eglDisplay = EGL_NO_DISPLAY;
289909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    }
290909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich}
291909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
292909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevichvoid init_scene(void)
293909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich{
294f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glDisable(GL_DITHER);
295f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glEnable(GL_CULL_FACE);
296f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    float ratio = 320.0f / 480.0f;
297f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glViewport(0, 0, 320, 480);
298f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glMatrixMode(GL_PROJECTION);
299f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glLoadIdentity();
300f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glFrustumf(-ratio, ratio, -1, 1, 1, 10);
301909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    glMatrixMode(GL_MODELVIEW);
302f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glLoadIdentity();
303f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    gluLookAt(
304f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            0, 0, 3,  // eye
305f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            0, 0, 0,  // center
306f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            0, 1, 0); // up
307909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    glEnable(GL_TEXTURE_2D);
308909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    glEnableClientState(GL_VERTEX_ARRAY);
309f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
310909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich}
311909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
312909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevichvoid create_texture(void)
313909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich{
314f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    const unsigned int on = 0xff0000ff;
315f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    const unsigned int off = 0xffffffff;
316f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    const unsigned int pixels[] =
317f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    {
318f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            on, off, on, off, on, off, on, off,
319f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            off, on, off, on, off, on, off, on,
320f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            on, off, on, off, on, off, on, off,
321f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            off, on, off, on, off, on, off, on,
322f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            on, off, on, off, on, off, on, off,
323f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            off, on, off, on, off, on, off, on,
324f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            on, off, on, off, on, off, on, off,
325f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich            off, on, off, on, off, on, off, on,
326909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    };
327909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
328909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    glGenTextures(1, &texture);
329909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    glBindTexture(GL_TEXTURE_2D, texture);
330909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
331909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
332909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
333909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
334909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich}
335909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
336909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevichvoid render()
337909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich{
338f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    int i, j;
339909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    int quads = 1;
340909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
341909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    const GLfloat vertices[] = {
342909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich            -1,  -1,  0,
343909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich             1,  -1,  0,
344909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich             1,   1,  0,
345909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich            -1,   1,  0
346909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    };
347909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
348909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    const GLfixed texCoords[] = {
349909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich            0,            0,
350909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich            FIXED_ONE,    0,
351909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich            FIXED_ONE,    FIXED_ONE,
352909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich            0,            FIXED_ONE
353909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    };
354909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich
355f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    const GLushort indices[] = { 0, 1, 2,  0, 2, 3 };
356f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich
357909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    glVertexPointer(3, GL_FLOAT, 0, vertices);
358909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    glTexCoordPointer(2, GL_FIXED, 0, texCoords);
359f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glClearColor(1.0, 1.0, 1.0, 1.0);
360f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    int nelem = sizeof(indices)/sizeof(indices[0]);
361f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
362f38bce2387deb10f5685f4a393138b12eec85623Jack Palevich    glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices);
363909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich    eglSwapBuffers(eglDisplay, eglSurface);
364909486a7cbb89b7163e221d1c7b93e1dba0ee5c7Jack Palevich}
365