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 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(const WindowSurface& windowSurface); 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_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 148static 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 160int 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 192int main(int argc, char **argv) 193{ 194 int q; 195 int start, end; 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 213int init_gl_surface(const WindowSurface& windowSurface) 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 = windowSurface.getSurface(); 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