15ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich// Simple OpenGL ES 1.x application showing how to initialize and draw something.
25ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
31c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich#include <EGL/egl.h>
41c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
55ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich#include <GLES/gl.h>
65ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich#include <GLES/glext.h>
75ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
85ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich#include <ui/FramebufferNativeWindow.h>
95ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich#include <ui/EGLUtils.h>
105ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
111c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich#include <stdio.h>
121c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
135ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich#include <stdlib.h>
145ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich#include <math.h>
155ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
165ffd62405ae6a801308989368a2473e4baaf3170Jack Palevichusing namespace android;
171c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
181c875584c5d90a3935f4c53376dfb2ba098795b5Jack PalevichEGLDisplay eglDisplay;
191c875584c5d90a3935f4c53376dfb2ba098795b5Jack PalevichEGLSurface eglSurface;
201c875584c5d90a3935f4c53376dfb2ba098795b5Jack PalevichEGLContext eglContext;
211c875584c5d90a3935f4c53376dfb2ba098795b5Jack PalevichGLuint texture;
221c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
235ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich#define FIXED_ONE 0x10000
241c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich#define ITERATIONS 50
251c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
261c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevichint init_gl_surface(void);
271c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevichvoid free_gl_surface(void);
281c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevichvoid init_scene(void);
291c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevichvoid render();
305ffd62405ae6a801308989368a2473e4baaf3170Jack Palevichvoid create_texture(void);
311c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevichint readTimer(void);
321c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
331c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevichstatic void printGLString(const char *name, GLenum s) {
341c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    const char *v = (const char *) glGetString(s);
351c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    fprintf(stderr, "GL %s = %s\n", name, v);
361c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich}
375ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
385ffd62405ae6a801308989368a2473e4baaf3170Jack Palevichstatic void gluLookAt(float eyeX, float eyeY, float eyeZ,
395ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich        float centerX, float centerY, float centerZ, float upX, float upY,
405ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich        float upZ)
415ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich{
425ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    // See the OpenGL GLUT documentation for gluLookAt for a description
435ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    // of the algorithm. We implement it in a straightforward way:
445ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
455ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    float fx = centerX - eyeX;
465ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    float fy = centerY - eyeY;
475ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    float fz = centerZ - eyeZ;
485ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
495ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    // Normalize f
505ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    float rlf = 1.0f / sqrtf(fx*fx + fy*fy + fz*fz);
515ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    fx *= rlf;
525ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    fy *= rlf;
535ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    fz *= rlf;
545ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
555ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    // Normalize up
565ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    float rlup = 1.0f / sqrtf(upX*upX + upY*upY + upZ*upZ);
575ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    upX *= rlup;
585ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    upY *= rlup;
595ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    upZ *= rlup;
605ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
615ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    // compute s = f x up (x means "cross product")
625ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
635ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    float sx = fy * upZ - fz * upY;
645ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    float sy = fz * upX - fx * upZ;
655ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    float sz = fx * upY - fy * upX;
665ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
675ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    // compute u = s x f
685ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    float ux = sy * fz - sz * fy;
695ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    float uy = sz * fx - sx * fz;
705ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    float uz = sx * fy - sy * fx;
715ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
725ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    float m[16] ;
735ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    m[0] = sx;
745ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    m[1] = ux;
755ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    m[2] = -fx;
765ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    m[3] = 0.0f;
775ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
785ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    m[4] = sy;
795ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    m[5] = uy;
805ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    m[6] = -fy;
815ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    m[7] = 0.0f;
825ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
835ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    m[8] = sz;
845ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    m[9] = uz;
855ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    m[10] = -fz;
865ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    m[11] = 0.0f;
875ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
885ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    m[12] = 0.0f;
895ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    m[13] = 0.0f;
905ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    m[14] = 0.0f;
915ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    m[15] = 1.0f;
925ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
935ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    glMultMatrixf(m);
945ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    glTranslatef(-eyeX, -eyeY, -eyeZ);
955ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich}
965ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
975ffd62405ae6a801308989368a2473e4baaf3170Jack Palevichvoid printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {
985ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
995ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich#define X(VAL) {VAL, #VAL}
1005ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    struct {EGLint attribute; const char* name;} names[] = {
1015ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_BUFFER_SIZE),
1025ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_ALPHA_SIZE),
1035ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_BLUE_SIZE),
1045ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_GREEN_SIZE),
1055ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_RED_SIZE),
1065ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_DEPTH_SIZE),
1075ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_STENCIL_SIZE),
1085ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_CONFIG_CAVEAT),
1095ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_CONFIG_ID),
1105ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_LEVEL),
1115ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_MAX_PBUFFER_HEIGHT),
1125ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_MAX_PBUFFER_PIXELS),
1135ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_MAX_PBUFFER_WIDTH),
1145ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_NATIVE_RENDERABLE),
1155ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_NATIVE_VISUAL_ID),
1165ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_NATIVE_VISUAL_TYPE),
1175ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_PRESERVED_RESOURCES),
1185ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_SAMPLES),
1195ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_SAMPLE_BUFFERS),
1205ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_SURFACE_TYPE),
1215ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_TRANSPARENT_TYPE),
1225ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_TRANSPARENT_RED_VALUE),
1235ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_TRANSPARENT_GREEN_VALUE),
1245ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_TRANSPARENT_BLUE_VALUE),
1255ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_BIND_TO_TEXTURE_RGB),
1265ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_BIND_TO_TEXTURE_RGBA),
1275ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_MIN_SWAP_INTERVAL),
1285ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_MAX_SWAP_INTERVAL),
1295ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_LUMINANCE_SIZE),
1305ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_ALPHA_MASK_SIZE),
1315ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_COLOR_BUFFER_TYPE),
1325ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_RENDERABLE_TYPE),
1335ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    X(EGL_CONFORMANT),
1345ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich   };
1355ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich#undef X
1365ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
1375ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
1385ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich        EGLint value = -1;
1395ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich        EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
1405ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich        EGLint error = eglGetError();
1415ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich        if (returnVal && error == EGL_SUCCESS) {
1425ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich            printf(" %s: ", names[j].name);
1435ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich            printf("%d (0x%x)", value, value);
1445ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich        }
1455ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    }
1465ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    printf("\n");
1475ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich}
1485ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
1495ffd62405ae6a801308989368a2473e4baaf3170Jack Palevichstatic void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
1505ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    if (returnVal != EGL_TRUE) {
1515ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich        fprintf(stderr, "%s() returned %d\n", op, returnVal);
1525ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    }
1535ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
1545ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
1555ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich            = eglGetError()) {
1565ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich        fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error),
1575ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich                error);
1585ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    }
1595ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich}
1605ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
1615ffd62405ae6a801308989368a2473e4baaf3170Jack Palevichint printEGLConfigurations(EGLDisplay dpy) {
1625ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    EGLint numConfig = 0;
1635ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    EGLint returnVal = eglGetConfigs(dpy, NULL, 0, &numConfig);
1645ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    checkEglError("eglGetConfigs", returnVal);
1655ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    if (!returnVal) {
1665ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich        return false;
1675ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    }
1685ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
1695ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    printf("Number of EGL configurations: %d\n", numConfig);
1705ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
1715ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    EGLConfig* configs = (EGLConfig*) malloc(sizeof(EGLConfig) * numConfig);
1725ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    if (! configs) {
1735ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich        printf("Could not allocate configs.\n");
1745ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich        return false;
1755ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    }
1765ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
1775ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    returnVal = eglGetConfigs(dpy, configs, numConfig, &numConfig);
1785ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    checkEglError("eglGetConfigs", returnVal);
1795ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    if (!returnVal) {
1805ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich        free(configs);
1815ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich        return false;
1825ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    }
1835ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
1845ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    for(int i = 0; i < numConfig; i++) {
1855ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich        printf("Configuration %d\n", i);
1865ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich        printEGLConfiguration(dpy, configs[i]);
1875ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    }
1885ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
1895ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    free(configs);
1905ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    return true;
1915ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich}
1925ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
1931c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevichint main(int argc, char **argv)
1941c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich{
1951c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    int q;
1961c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    int start, end;
1975ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    printf("Initializing EGL...\n");
1981c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    if(!init_gl_surface())
1991c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    {
2001c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich        printf("GL initialisation failed - exiting\n");
2011c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich        return 0;
2021c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    }
2031c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    init_scene();
2041c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    create_texture();
2055ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    printf("Running...\n");
2065ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    while(true) {
2075ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich        render();
2085ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    }
2091c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    free_gl_surface();
2101c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    return 0;
2111c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich}
2121c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
2131c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevichint init_gl_surface(void)
2141c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich{
2151c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    EGLint numConfigs = 1;
2161c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    EGLConfig myConfig = {0};
2171c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    EGLint attrib[] =
2181c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    {
2191c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich            EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
2201c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich            EGL_NONE
2211c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    };
2221c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
2231c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    if ( (eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY )
2241c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    {
2251c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich        printf("eglGetDisplay failed\n");
2261c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich        return 0;
2271c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    }
2281c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
2291c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    if ( eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE )
2301c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    {
2311c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich        printf("eglInitialize failed\n");
2321c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich        return 0;
2335ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    }
2345ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
2355ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    if (! printEGLConfigurations(eglDisplay)) {
2365ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich        printf("printEGLConfigurations failed.\n");
2375ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich        return 0;
2381c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    }
2391c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
2401c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    EGLNativeWindowType window = android_createDisplaySurface();
2411c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    EGLUtils::selectConfigForNativeWindow(eglDisplay, attrib, window, &myConfig);
2421c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
2435ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    if ( (eglSurface = eglCreateWindowSurface(eglDisplay, myConfig,
2441c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich            window, 0)) == EGL_NO_SURFACE )
2451c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    {
2461c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich        printf("eglCreateWindowSurface failed\n");
2471c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich        return 0;
2481c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    }
2491c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
2501c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    if ( (eglContext = eglCreateContext(eglDisplay, myConfig, 0, 0)) == EGL_NO_CONTEXT )
2511c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    {
2521c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich        printf("eglCreateContext failed\n");
2531c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich        return 0;
2541c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    }
2551c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
2561c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    if ( eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) != EGL_TRUE )
2571c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    {
2581c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich        printf("eglMakeCurrent failed\n");
2591c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich        return 0;
2601c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    }
2611c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
2621c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    int w, h;
2631c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
2641c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    eglQuerySurface(eglDisplay, eglSurface, EGL_WIDTH, &w);
2651c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    checkEglError("eglQuerySurface");
2661c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    eglQuerySurface(eglDisplay, eglSurface, EGL_HEIGHT, &h);
2671c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    checkEglError("eglQuerySurface");
2681c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    GLint dim = w < h ? w : h;
2691c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
2701c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
2711c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
2721c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    printGLString("Version", GL_VERSION);
2731c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    printGLString("Vendor", GL_VENDOR);
2741c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    printGLString("Renderer", GL_RENDERER);
2751c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    printGLString("Extensions", GL_EXTENSIONS);
2761c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
2771c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    return 1;
2781c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich}
2791c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
2801c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevichvoid free_gl_surface(void)
2811c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich{
2821c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    if (eglDisplay != EGL_NO_DISPLAY)
2831c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    {
2841c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich        eglMakeCurrent( EGL_NO_DISPLAY, EGL_NO_SURFACE,
2851c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich                EGL_NO_SURFACE, EGL_NO_CONTEXT );
2861c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich        eglDestroyContext( eglDisplay, eglContext );
2871c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich        eglDestroySurface( eglDisplay, eglSurface );
2881c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich        eglTerminate( eglDisplay );
2891c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich        eglDisplay = EGL_NO_DISPLAY;
2901c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    }
2911c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich}
2921c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
2931c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevichvoid init_scene(void)
2941c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich{
2955ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    glDisable(GL_DITHER);
2965ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    glEnable(GL_CULL_FACE);
2975ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    float ratio = 320.0f / 480.0f;
2985ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    glViewport(0, 0, 320, 480);
2995ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    glMatrixMode(GL_PROJECTION);
3005ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    glLoadIdentity();
3015ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    glFrustumf(-ratio, ratio, -1, 1, 1, 10);
3021c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    glMatrixMode(GL_MODELVIEW);
3035ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    glLoadIdentity();
3045ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    gluLookAt(
3055ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich            0, 0, 3,  // eye
3065ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich            0, 0, 0,  // center
3075ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich            0, 1, 0); // up
3081c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    glEnable(GL_TEXTURE_2D);
3091c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    glEnableClientState(GL_VERTEX_ARRAY);
3105ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3111c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich}
3121c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
3131c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevichvoid create_texture(void)
3141c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich{
3155ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    const unsigned int on = 0xff0000ff;
3165ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    const unsigned int off = 0xffffffff;
3175ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    const unsigned int pixels[] =
3185ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    {
3195ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich            on, off, on, off, on, off, on, off,
3205ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich            off, on, off, on, off, on, off, on,
3215ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich            on, off, on, off, on, off, on, off,
3225ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich            off, on, off, on, off, on, off, on,
3235ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich            on, off, on, off, on, off, on, off,
3245ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich            off, on, off, on, off, on, off, on,
3255ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich            on, off, on, off, on, off, on, off,
3265ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich            off, on, off, on, off, on, off, on,
3271c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    };
3281c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
3291c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    glGenTextures(1, &texture);
3301c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    glBindTexture(GL_TEXTURE_2D, texture);
3311c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
3321c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3331c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3341c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
3351c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich}
3361c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
3371c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevichvoid render()
3381c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich{
3395ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    int i, j;
3401c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    int quads = 1;
3411c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
3421c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    const GLfloat vertices[] = {
3431c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich            -1,  -1,  0,
3441c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich             1,  -1,  0,
3451c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich             1,   1,  0,
3461c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich            -1,   1,  0
3471c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    };
3481c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
3491c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    const GLfixed texCoords[] = {
3501c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich            0,            0,
3511c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich            FIXED_ONE,    0,
3521c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich            FIXED_ONE,    FIXED_ONE,
3531c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich            0,            FIXED_ONE
3541c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    };
3551c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich
3565ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    const GLushort indices[] = { 0, 1, 2,  0, 2, 3 };
3575ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich
3581c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    glVertexPointer(3, GL_FLOAT, 0, vertices);
3591c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    glTexCoordPointer(2, GL_FIXED, 0, texCoords);
3605ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    glClearColor(1.0, 1.0, 1.0, 1.0);
3615ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    int nelem = sizeof(indices)/sizeof(indices[0]);
3625ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
3635ffd62405ae6a801308989368a2473e4baaf3170Jack Palevich    glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices);
3641c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich    eglSwapBuffers(eglDisplay, eglSurface);
3651c875584c5d90a3935f4c53376dfb2ba098795b5Jack Palevich}
366