1 // Calls glDrawElements() the number of times specified by 2 // ITERATIONS. Should draw a checkerboard on the screen after 3 // a few seconds. 4 // 5 // Ported from a Java version by Google. 6 7 #include <EGL/egl.h> 8 #include <GLES/gl.h> 9 #include <GLES/glext.h> 10 11 #include <ui/FramebufferNativeWindow.h> 12 #include <ui/EGLUtils.h> 13 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <math.h> 17 18 using namespace android; 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(void); 29 void free_gl_surface(void); 30 void init_scene(void); 31 void render(int quads); 32 void create_texture(void); 33 int readTimer(void); 34 35 static void gluLookAt(float eyeX, float eyeY, float eyeZ, 36 float centerX, float centerY, float centerZ, float upX, float upY, 37 float upZ) 38 { 39 // See the OpenGL GLUT documentation for gluLookAt for a description 40 // of the algorithm. We implement it in a straightforward way: 41 42 float fx = centerX - eyeX; 43 float fy = centerY - eyeY; 44 float fz = centerZ - eyeZ; 45 46 // Normalize f 47 float rlf = 1.0f / sqrtf(fx*fx + fy*fy + fz*fz); 48 fx *= rlf; 49 fy *= rlf; 50 fz *= rlf; 51 52 // Normalize up 53 float rlup = 1.0f / sqrtf(upX*upX + upY*upY + upZ*upZ); 54 upX *= rlup; 55 upY *= rlup; 56 upZ *= rlup; 57 58 // compute s = f x up (x means "cross product") 59 60 float sx = fy * upZ - fz * upY; 61 float sy = fz * upX - fx * upZ; 62 float sz = fx * upY - fy * upX; 63 64 // compute u = s x f 65 float ux = sy * fz - sz * fy; 66 float uy = sz * fx - sx * fz; 67 float uz = sx * fy - sy * fx; 68 69 float m[16] ; 70 m[0] = sx; 71 m[1] = ux; 72 m[2] = -fx; 73 m[3] = 0.0f; 74 75 m[4] = sy; 76 m[5] = uy; 77 m[6] = -fy; 78 m[7] = 0.0f; 79 80 m[8] = sz; 81 m[9] = uz; 82 m[10] = -fz; 83 m[11] = 0.0f; 84 85 m[12] = 0.0f; 86 m[13] = 0.0f; 87 m[14] = 0.0f; 88 m[15] = 1.0f; 89 90 glMultMatrixf(m); 91 glTranslatef(-eyeX, -eyeY, -eyeZ); 92 } 93 94 int main(int argc, char **argv) 95 { 96 int q; 97 int start, end; 98 99 printf("Initializing EGL...\n"); 100 101 if(!init_gl_surface()) 102 { 103 printf("GL initialisation failed - exiting\n"); 104 return 0; 105 } 106 107 init_scene(); 108 109 create_texture(); 110 111 printf("Start test...\n"); 112 113 render(argc==2 ? atoi(argv[1]) : ITERATIONS); 114 115 free_gl_surface(); 116 117 return 0; 118 } 119 120 int init_gl_surface(void) 121 { 122 EGLint numConfigs = 1; 123 EGLConfig myConfig = {0}; 124 EGLint attrib[] = 125 { 126 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 127 EGL_DEPTH_SIZE, 16, 128 EGL_NONE 129 }; 130 131 if ( (eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY ) 132 { 133 printf("eglGetDisplay failed\n"); 134 return 0; 135 } 136 137 if ( eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE ) 138 { 139 printf("eglInitialize failed\n"); 140 return 0; 141 } 142 143 EGLNativeWindowType window = android_createDisplaySurface(); 144 EGLUtils::selectConfigForNativeWindow(eglDisplay, attrib, window, &myConfig); 145 146 if ( (eglSurface = eglCreateWindowSurface(eglDisplay, myConfig, 147 window, 0)) == EGL_NO_SURFACE ) 148 { 149 printf("eglCreateWindowSurface failed\n"); 150 return 0; 151 } 152 153 if ( (eglContext = eglCreateContext(eglDisplay, myConfig, 0, 0)) == EGL_NO_CONTEXT ) 154 { 155 printf("eglCreateContext failed\n"); 156 return 0; 157 } 158 159 if ( eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) != EGL_TRUE ) 160 { 161 printf("eglMakeCurrent failed\n"); 162 return 0; 163 } 164 165 return 1; 166 } 167 168 void free_gl_surface(void) 169 { 170 if (eglDisplay != EGL_NO_DISPLAY) 171 { 172 eglMakeCurrent( EGL_NO_DISPLAY, EGL_NO_SURFACE, 173 EGL_NO_SURFACE, EGL_NO_CONTEXT ); 174 eglDestroyContext( eglDisplay, eglContext ); 175 eglDestroySurface( eglDisplay, eglSurface ); 176 eglTerminate( eglDisplay ); 177 eglDisplay = EGL_NO_DISPLAY; 178 } 179 } 180 181 void init_scene(void) 182 { 183 glDisable(GL_DITHER); 184 glEnable(GL_CULL_FACE); 185 186 float ratio = 320.0f / 480.0f; 187 glViewport(0, 0, 320, 480); 188 189 glMatrixMode(GL_PROJECTION); 190 glLoadIdentity(); 191 glFrustumf(-ratio, ratio, -1, 1, 1, 10); 192 193 glMatrixMode(GL_MODELVIEW); 194 glLoadIdentity(); 195 gluLookAt( 196 0, 0, 3, // eye 197 0, 0, 0, // center 198 0, 1, 0); // up 199 200 glEnable(GL_TEXTURE_2D); 201 glEnableClientState(GL_VERTEX_ARRAY); 202 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 203 } 204 205 void create_texture(void) 206 { 207 const unsigned int on = 0xff0000ff; 208 const unsigned int off = 0xffffffff; 209 const unsigned int pixels[] = 210 { 211 on, off, on, off, on, off, on, off, 212 off, on, off, on, off, on, off, on, 213 on, off, on, off, on, off, on, off, 214 off, on, off, on, off, on, off, on, 215 on, off, on, off, on, off, on, off, 216 off, on, off, on, off, on, off, on, 217 on, off, on, off, on, off, on, off, 218 off, on, off, on, off, on, off, on, 219 }; 220 glGenTextures(1, &texture); 221 glBindTexture(GL_TEXTURE_2D, texture); 222 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 223 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 224 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 225 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 226 } 227 228 void render(int quads) 229 { 230 int i, j; 231 232 const GLfloat vertices[] = { 233 -1, -1, 0, 234 1, -1, 0, 235 1, 1, 0, 236 -1, 1, 0 237 }; 238 239 const GLfixed texCoords[] = { 240 0, 0, 241 FIXED_ONE, 0, 242 FIXED_ONE, FIXED_ONE, 243 0, FIXED_ONE 244 }; 245 246 const GLushort quadIndices[] = { 0, 1, 2, 0, 2, 3 }; 247 248 249 GLushort* indices = (GLushort*)malloc(quads*sizeof(quadIndices)); 250 for (i=0 ; i<quads ; i++) 251 memcpy(indices+(sizeof(quadIndices)/sizeof(indices[0]))*i, quadIndices, sizeof(quadIndices)); 252 253 glVertexPointer(3, GL_FLOAT, 0, vertices); 254 glTexCoordPointer(2, GL_FIXED, 0, texCoords); 255 256 // make sure to do a couple eglSwapBuffers to make sure there are 257 // no problems with the very first ones (who knows) 258 glClearColor(0.4, 0.4, 0.4, 0.4); 259 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 260 eglSwapBuffers(eglDisplay, eglSurface); 261 glClearColor(0.6, 0.6, 0.6, 0.6); 262 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 263 eglSwapBuffers(eglDisplay, eglSurface); 264 glClearColor(1.0, 1.0, 1.0, 1.0); 265 266 for (j=0 ; j<10 ; j++) { 267 printf("loop %d / 10 (%d quads / loop)\n", j, quads); 268 269 int nelem = sizeof(quadIndices)/sizeof(quadIndices[0]); 270 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 271 glDrawElements(GL_TRIANGLES, nelem*quads, GL_UNSIGNED_SHORT, indices); 272 eglSwapBuffers(eglDisplay, eglSurface); 273 } 274 275 free(indices); 276 } 277 278