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