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 <ui/FramebufferNativeWindow.h>
      9 #include <ui/EGLUtils.h>
     10 
     11 #include <stdio.h>
     12 
     13 #include <stdlib.h>
     14 #include <math.h>
     15 
     16 using namespace android;
     17 
     18 EGLDisplay eglDisplay;
     19 EGLSurface eglSurface;
     20 EGLContext eglContext;
     21 GLuint texture;
     22 
     23 #define FIXED_ONE 0x10000
     24 #define ITERATIONS 50
     25 
     26 int init_gl_surface(void);
     27 void free_gl_surface(void);
     28 void init_scene(void);
     29 void render();
     30 void create_texture(void);
     31 int readTimer(void);
     32 
     33 static void printGLString(const char *name, GLenum s) {
     34     const char *v = (const char *) glGetString(s);
     35     fprintf(stderr, "GL %s = %s\n", name, v);
     36 }
     37 
     38 static void gluLookAt(float eyeX, float eyeY, float eyeZ,
     39         float centerX, float centerY, float centerZ, float upX, float upY,
     40         float upZ)
     41 {
     42     // See the OpenGL GLUT documentation for gluLookAt for a description
     43     // of the algorithm. We implement it in a straightforward way:
     44 
     45     float fx = centerX - eyeX;
     46     float fy = centerY - eyeY;
     47     float fz = centerZ - eyeZ;
     48 
     49     // Normalize f
     50     float rlf = 1.0f / sqrtf(fx*fx + fy*fy + fz*fz);
     51     fx *= rlf;
     52     fy *= rlf;
     53     fz *= rlf;
     54 
     55     // Normalize up
     56     float rlup = 1.0f / sqrtf(upX*upX + upY*upY + upZ*upZ);
     57     upX *= rlup;
     58     upY *= rlup;
     59     upZ *= rlup;
     60 
     61     // compute s = f x up (x means "cross product")
     62 
     63     float sx = fy * upZ - fz * upY;
     64     float sy = fz * upX - fx * upZ;
     65     float sz = fx * upY - fy * upX;
     66 
     67     // compute u = s x f
     68     float ux = sy * fz - sz * fy;
     69     float uy = sz * fx - sx * fz;
     70     float uz = sx * fy - sy * fx;
     71 
     72     float m[16] ;
     73     m[0] = sx;
     74     m[1] = ux;
     75     m[2] = -fx;
     76     m[3] = 0.0f;
     77 
     78     m[4] = sy;
     79     m[5] = uy;
     80     m[6] = -fy;
     81     m[7] = 0.0f;
     82 
     83     m[8] = sz;
     84     m[9] = uz;
     85     m[10] = -fz;
     86     m[11] = 0.0f;
     87 
     88     m[12] = 0.0f;
     89     m[13] = 0.0f;
     90     m[14] = 0.0f;
     91     m[15] = 1.0f;
     92 
     93     glMultMatrixf(m);
     94     glTranslatef(-eyeX, -eyeY, -eyeZ);
     95 }
     96 
     97 void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {
     98 
     99 #define X(VAL) {VAL, #VAL}
    100     struct {EGLint attribute; const char* name;} names[] = {
    101     X(EGL_BUFFER_SIZE),
    102     X(EGL_ALPHA_SIZE),
    103     X(EGL_BLUE_SIZE),
    104     X(EGL_GREEN_SIZE),
    105     X(EGL_RED_SIZE),
    106     X(EGL_DEPTH_SIZE),
    107     X(EGL_STENCIL_SIZE),
    108     X(EGL_CONFIG_CAVEAT),
    109     X(EGL_CONFIG_ID),
    110     X(EGL_LEVEL),
    111     X(EGL_MAX_PBUFFER_HEIGHT),
    112     X(EGL_MAX_PBUFFER_PIXELS),
    113     X(EGL_MAX_PBUFFER_WIDTH),
    114     X(EGL_NATIVE_RENDERABLE),
    115     X(EGL_NATIVE_VISUAL_ID),
    116     X(EGL_NATIVE_VISUAL_TYPE),
    117     X(EGL_SAMPLES),
    118     X(EGL_SAMPLE_BUFFERS),
    119     X(EGL_SURFACE_TYPE),
    120     X(EGL_TRANSPARENT_TYPE),
    121     X(EGL_TRANSPARENT_RED_VALUE),
    122     X(EGL_TRANSPARENT_GREEN_VALUE),
    123     X(EGL_TRANSPARENT_BLUE_VALUE),
    124     X(EGL_BIND_TO_TEXTURE_RGB),
    125     X(EGL_BIND_TO_TEXTURE_RGBA),
    126     X(EGL_MIN_SWAP_INTERVAL),
    127     X(EGL_MAX_SWAP_INTERVAL),
    128     X(EGL_LUMINANCE_SIZE),
    129     X(EGL_ALPHA_MASK_SIZE),
    130     X(EGL_COLOR_BUFFER_TYPE),
    131     X(EGL_RENDERABLE_TYPE),
    132     X(EGL_CONFORMANT),
    133    };
    134 #undef X
    135 
    136     for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
    137         EGLint value = -1;
    138         EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
    139         EGLint error = eglGetError();
    140         if (returnVal && error == EGL_SUCCESS) {
    141             printf(" %s: ", names[j].name);
    142             printf("%d (0x%x)", value, value);
    143         }
    144     }
    145     printf("\n");
    146 }
    147 
    148 static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
    149     if (returnVal != EGL_TRUE) {
    150         fprintf(stderr, "%s() returned %d\n", op, returnVal);
    151     }
    152 
    153     for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
    154             = eglGetError()) {
    155         fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error),
    156                 error);
    157     }
    158 }
    159 
    160 int printEGLConfigurations(EGLDisplay dpy) {
    161     EGLint numConfig = 0;
    162     EGLint returnVal = eglGetConfigs(dpy, NULL, 0, &numConfig);
    163     checkEglError("eglGetConfigs", returnVal);
    164     if (!returnVal) {
    165         return false;
    166     }
    167 
    168     printf("Number of EGL configurations: %d\n", numConfig);
    169 
    170     EGLConfig* configs = (EGLConfig*) malloc(sizeof(EGLConfig) * numConfig);
    171     if (! configs) {
    172         printf("Could not allocate configs.\n");
    173         return false;
    174     }
    175 
    176     returnVal = eglGetConfigs(dpy, configs, numConfig, &numConfig);
    177     checkEglError("eglGetConfigs", returnVal);
    178     if (!returnVal) {
    179         free(configs);
    180         return false;
    181     }
    182 
    183     for(int i = 0; i < numConfig; i++) {
    184         printf("Configuration %d\n", i);
    185         printEGLConfiguration(dpy, configs[i]);
    186     }
    187 
    188     free(configs);
    189     return true;
    190 }
    191 
    192 int main(int argc, char **argv)
    193 {
    194     int q;
    195     int start, end;
    196     printf("Initializing EGL...\n");
    197     if(!init_gl_surface())
    198     {
    199         printf("GL initialisation failed - exiting\n");
    200         return 0;
    201     }
    202     init_scene();
    203     create_texture();
    204     printf("Running...\n");
    205     while(true) {
    206         render();
    207     }
    208     free_gl_surface();
    209     return 0;
    210 }
    211 
    212 int init_gl_surface(void)
    213 {
    214     EGLint numConfigs = 1;
    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 = android_createDisplaySurface();
    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     GLint dim = w < h ? w : h;
    268 
    269     fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
    270 
    271     printGLString("Version", GL_VERSION);
    272     printGLString("Vendor", GL_VENDOR);
    273     printGLString("Renderer", GL_RENDERER);
    274     printGLString("Extensions", GL_EXTENSIONS);
    275 
    276     return 1;
    277 }
    278 
    279 void free_gl_surface(void)
    280 {
    281     if (eglDisplay != EGL_NO_DISPLAY)
    282     {
    283         eglMakeCurrent( EGL_NO_DISPLAY, EGL_NO_SURFACE,
    284                 EGL_NO_SURFACE, EGL_NO_CONTEXT );
    285         eglDestroyContext( eglDisplay, eglContext );
    286         eglDestroySurface( eglDisplay, eglSurface );
    287         eglTerminate( eglDisplay );
    288         eglDisplay = EGL_NO_DISPLAY;
    289     }
    290 }
    291 
    292 void init_scene(void)
    293 {
    294     glDisable(GL_DITHER);
    295     glEnable(GL_CULL_FACE);
    296     float ratio = 320.0f / 480.0f;
    297     glViewport(0, 0, 320, 480);
    298     glMatrixMode(GL_PROJECTION);
    299     glLoadIdentity();
    300     glFrustumf(-ratio, ratio, -1, 1, 1, 10);
    301     glMatrixMode(GL_MODELVIEW);
    302     glLoadIdentity();
    303     gluLookAt(
    304             0, 0, 3,  // eye
    305             0, 0, 0,  // center
    306             0, 1, 0); // up
    307     glEnable(GL_TEXTURE_2D);
    308     glEnableClientState(GL_VERTEX_ARRAY);
    309     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    310 }
    311 
    312 void create_texture(void)
    313 {
    314     const unsigned int on = 0xff0000ff;
    315     const unsigned int off = 0xffffffff;
    316     const unsigned int pixels[] =
    317     {
    318             on, off, on, off, on, off, on, off,
    319             off, on, off, on, off, on, off, on,
    320             on, off, on, off, on, off, on, off,
    321             off, on, off, on, off, on, off, on,
    322             on, off, on, off, on, off, on, off,
    323             off, on, off, on, off, on, off, on,
    324             on, off, on, off, on, off, on, off,
    325             off, on, off, on, off, on, off, on,
    326     };
    327 
    328     glGenTextures(1, &texture);
    329     glBindTexture(GL_TEXTURE_2D, texture);
    330     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
    331     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    332     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    333     glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    334 }
    335 
    336 void render()
    337 {
    338     int i, j;
    339     int quads = 1;
    340 
    341     const GLfloat vertices[] = {
    342             -1,  -1,  0,
    343              1,  -1,  0,
    344              1,   1,  0,
    345             -1,   1,  0
    346     };
    347 
    348     const GLfixed texCoords[] = {
    349             0,            0,
    350             FIXED_ONE,    0,
    351             FIXED_ONE,    FIXED_ONE,
    352             0,            FIXED_ONE
    353     };
    354 
    355     const GLushort indices[] = { 0, 1, 2,  0, 2, 3 };
    356 
    357     glVertexPointer(3, GL_FLOAT, 0, vertices);
    358     glTexCoordPointer(2, GL_FIXED, 0, texCoords);
    359     glClearColor(1.0, 1.0, 1.0, 1.0);
    360     int nelem = sizeof(indices)/sizeof(indices[0]);
    361     glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    362     glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices);
    363     eglSwapBuffers(eglDisplay, eglSurface);
    364 }
    365