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