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 16using namespace android; 17 18EGLDisplay eglDisplay; 19EGLSurface eglSurface; 20EGLContext eglContext; 21GLuint texture; 22 23#define FIXED_ONE 0x10000 24#define ITERATIONS 50 25 26int init_gl_surface(void); 27void free_gl_surface(void); 28void init_scene(void); 29void render(); 30void create_texture(void); 31int readTimer(void); 32 33static 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 38static 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 97void 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_PRESERVED_RESOURCES), 118 X(EGL_SAMPLES), 119 X(EGL_SAMPLE_BUFFERS), 120 X(EGL_SURFACE_TYPE), 121 X(EGL_TRANSPARENT_TYPE), 122 X(EGL_TRANSPARENT_RED_VALUE), 123 X(EGL_TRANSPARENT_GREEN_VALUE), 124 X(EGL_TRANSPARENT_BLUE_VALUE), 125 X(EGL_BIND_TO_TEXTURE_RGB), 126 X(EGL_BIND_TO_TEXTURE_RGBA), 127 X(EGL_MIN_SWAP_INTERVAL), 128 X(EGL_MAX_SWAP_INTERVAL), 129 X(EGL_LUMINANCE_SIZE), 130 X(EGL_ALPHA_MASK_SIZE), 131 X(EGL_COLOR_BUFFER_TYPE), 132 X(EGL_RENDERABLE_TYPE), 133 X(EGL_CONFORMANT), 134 }; 135#undef X 136 137 for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) { 138 EGLint value = -1; 139 EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value); 140 EGLint error = eglGetError(); 141 if (returnVal && error == EGL_SUCCESS) { 142 printf(" %s: ", names[j].name); 143 printf("%d (0x%x)", value, value); 144 } 145 } 146 printf("\n"); 147} 148 149static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) { 150 if (returnVal != EGL_TRUE) { 151 fprintf(stderr, "%s() returned %d\n", op, returnVal); 152 } 153 154 for (EGLint error = eglGetError(); error != EGL_SUCCESS; error 155 = eglGetError()) { 156 fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error), 157 error); 158 } 159} 160 161int printEGLConfigurations(EGLDisplay dpy) { 162 EGLint numConfig = 0; 163 EGLint returnVal = eglGetConfigs(dpy, NULL, 0, &numConfig); 164 checkEglError("eglGetConfigs", returnVal); 165 if (!returnVal) { 166 return false; 167 } 168 169 printf("Number of EGL configurations: %d\n", numConfig); 170 171 EGLConfig* configs = (EGLConfig*) malloc(sizeof(EGLConfig) * numConfig); 172 if (! configs) { 173 printf("Could not allocate configs.\n"); 174 return false; 175 } 176 177 returnVal = eglGetConfigs(dpy, configs, numConfig, &numConfig); 178 checkEglError("eglGetConfigs", returnVal); 179 if (!returnVal) { 180 free(configs); 181 return false; 182 } 183 184 for(int i = 0; i < numConfig; i++) { 185 printf("Configuration %d\n", i); 186 printEGLConfiguration(dpy, configs[i]); 187 } 188 189 free(configs); 190 return true; 191} 192 193int main(int argc, char **argv) 194{ 195 int q; 196 int start, end; 197 printf("Initializing EGL...\n"); 198 if(!init_gl_surface()) 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 213int init_gl_surface(void) 214{ 215 EGLint numConfigs = 1; 216 EGLConfig myConfig = {0}; 217 EGLint attrib[] = 218 { 219 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 220 EGL_NONE 221 }; 222 223 if ( (eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY ) 224 { 225 printf("eglGetDisplay failed\n"); 226 return 0; 227 } 228 229 if ( eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE ) 230 { 231 printf("eglInitialize failed\n"); 232 return 0; 233 } 234 235 if (! printEGLConfigurations(eglDisplay)) { 236 printf("printEGLConfigurations failed.\n"); 237 return 0; 238 } 239 240 EGLNativeWindowType window = android_createDisplaySurface(); 241 EGLUtils::selectConfigForNativeWindow(eglDisplay, attrib, window, &myConfig); 242 243 if ( (eglSurface = eglCreateWindowSurface(eglDisplay, myConfig, 244 window, 0)) == EGL_NO_SURFACE ) 245 { 246 printf("eglCreateWindowSurface failed\n"); 247 return 0; 248 } 249 250 if ( (eglContext = eglCreateContext(eglDisplay, myConfig, 0, 0)) == EGL_NO_CONTEXT ) 251 { 252 printf("eglCreateContext failed\n"); 253 return 0; 254 } 255 256 if ( eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) != EGL_TRUE ) 257 { 258 printf("eglMakeCurrent failed\n"); 259 return 0; 260 } 261 262 int w, h; 263 264 eglQuerySurface(eglDisplay, eglSurface, EGL_WIDTH, &w); 265 checkEglError("eglQuerySurface"); 266 eglQuerySurface(eglDisplay, eglSurface, EGL_HEIGHT, &h); 267 checkEglError("eglQuerySurface"); 268 GLint dim = w < h ? w : h; 269 270 fprintf(stderr, "Window dimensions: %d x %d\n", w, h); 271 272 printGLString("Version", GL_VERSION); 273 printGLString("Vendor", GL_VENDOR); 274 printGLString("Renderer", GL_RENDERER); 275 printGLString("Extensions", GL_EXTENSIONS); 276 277 return 1; 278} 279 280void free_gl_surface(void) 281{ 282 if (eglDisplay != EGL_NO_DISPLAY) 283 { 284 eglMakeCurrent( EGL_NO_DISPLAY, EGL_NO_SURFACE, 285 EGL_NO_SURFACE, EGL_NO_CONTEXT ); 286 eglDestroyContext( eglDisplay, eglContext ); 287 eglDestroySurface( eglDisplay, eglSurface ); 288 eglTerminate( eglDisplay ); 289 eglDisplay = EGL_NO_DISPLAY; 290 } 291} 292 293void init_scene(void) 294{ 295 glDisable(GL_DITHER); 296 glEnable(GL_CULL_FACE); 297 float ratio = 320.0f / 480.0f; 298 glViewport(0, 0, 320, 480); 299 glMatrixMode(GL_PROJECTION); 300 glLoadIdentity(); 301 glFrustumf(-ratio, ratio, -1, 1, 1, 10); 302 glMatrixMode(GL_MODELVIEW); 303 glLoadIdentity(); 304 gluLookAt( 305 0, 0, 3, // eye 306 0, 0, 0, // center 307 0, 1, 0); // up 308 glEnable(GL_TEXTURE_2D); 309 glEnableClientState(GL_VERTEX_ARRAY); 310 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 311} 312 313void create_texture(void) 314{ 315 const unsigned int on = 0xff0000ff; 316 const unsigned int off = 0xffffffff; 317 const unsigned int pixels[] = 318 { 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 on, off, on, off, on, off, on, off, 326 off, on, off, on, off, on, off, on, 327 }; 328 329 glGenTextures(1, &texture); 330 glBindTexture(GL_TEXTURE_2D, texture); 331 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 332 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 333 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 334 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 335} 336 337void render() 338{ 339 int i, j; 340 int quads = 1; 341 342 const GLfloat vertices[] = { 343 -1, -1, 0, 344 1, -1, 0, 345 1, 1, 0, 346 -1, 1, 0 347 }; 348 349 const GLfixed texCoords[] = { 350 0, 0, 351 FIXED_ONE, 0, 352 FIXED_ONE, FIXED_ONE, 353 0, FIXED_ONE 354 }; 355 356 const GLushort indices[] = { 0, 1, 2, 0, 2, 3 }; 357 358 glVertexPointer(3, GL_FLOAT, 0, vertices); 359 glTexCoordPointer(2, GL_FIXED, 0, texCoords); 360 glClearColor(1.0, 1.0, 1.0, 1.0); 361 int nelem = sizeof(indices)/sizeof(indices[0]); 362 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 363 glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices); 364 eglSwapBuffers(eglDisplay, eglSurface); 365} 366