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 <WindowSurface.h> 12 #include <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(const WindowSurface&); 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 printf("Initializing EGL...\n"); 97 98 WindowSurface windowSurface; 99 if(!init_gl_surface(windowSurface)) 100 { 101 printf("GL initialisation failed - exiting\n"); 102 return 0; 103 } 104 105 init_scene(); 106 107 create_texture(); 108 109 printf("Start test...\n"); 110 111 render(argc==2 ? atoi(argv[1]) : ITERATIONS); 112 113 free_gl_surface(); 114 115 return 0; 116 } 117 118 int init_gl_surface(const WindowSurface& windowSurface) 119 { 120 EGLConfig myConfig = {0}; 121 EGLint attrib[] = 122 { 123 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 124 EGL_DEPTH_SIZE, 16, 125 EGL_NONE 126 }; 127 128 if ( (eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY ) 129 { 130 printf("eglGetDisplay failed\n"); 131 return 0; 132 } 133 134 if ( eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE ) 135 { 136 printf("eglInitialize failed\n"); 137 return 0; 138 } 139 140 EGLNativeWindowType window = windowSurface.getSurface(); 141 EGLUtils::selectConfigForNativeWindow(eglDisplay, attrib, window, &myConfig); 142 143 if ( (eglSurface = eglCreateWindowSurface(eglDisplay, myConfig, 144 window, 0)) == EGL_NO_SURFACE ) 145 { 146 printf("eglCreateWindowSurface failed\n"); 147 return 0; 148 } 149 150 if ( (eglContext = eglCreateContext(eglDisplay, myConfig, 0, 0)) == EGL_NO_CONTEXT ) 151 { 152 printf("eglCreateContext failed\n"); 153 return 0; 154 } 155 156 if ( eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) != EGL_TRUE ) 157 { 158 printf("eglMakeCurrent failed\n"); 159 return 0; 160 } 161 162 return 1; 163 } 164 165 void free_gl_surface(void) 166 { 167 if (eglDisplay != EGL_NO_DISPLAY) 168 { 169 eglMakeCurrent( EGL_NO_DISPLAY, EGL_NO_SURFACE, 170 EGL_NO_SURFACE, EGL_NO_CONTEXT ); 171 eglDestroyContext( eglDisplay, eglContext ); 172 eglDestroySurface( eglDisplay, eglSurface ); 173 eglTerminate( eglDisplay ); 174 eglDisplay = EGL_NO_DISPLAY; 175 } 176 } 177 178 void init_scene(void) 179 { 180 glDisable(GL_DITHER); 181 glEnable(GL_CULL_FACE); 182 183 float ratio = 320.0f / 480.0f; 184 glViewport(0, 0, 320, 480); 185 186 glMatrixMode(GL_PROJECTION); 187 glLoadIdentity(); 188 glFrustumf(-ratio, ratio, -1, 1, 1, 10); 189 190 glMatrixMode(GL_MODELVIEW); 191 glLoadIdentity(); 192 gluLookAt( 193 0, 0, 3, // eye 194 0, 0, 0, // center 195 0, 1, 0); // up 196 197 glEnable(GL_TEXTURE_2D); 198 glEnableClientState(GL_VERTEX_ARRAY); 199 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 200 } 201 202 void create_texture(void) 203 { 204 const unsigned int on = 0xff0000ff; 205 const unsigned int off = 0xffffffff; 206 const unsigned int pixels[] = 207 { 208 on, off, on, off, on, off, on, off, 209 off, on, off, on, off, on, off, on, 210 on, off, on, off, on, off, on, off, 211 off, on, off, on, off, on, off, on, 212 on, off, on, off, on, off, on, off, 213 off, on, off, on, off, on, off, on, 214 on, off, on, off, on, off, on, off, 215 off, on, off, on, off, on, off, on, 216 }; 217 glGenTextures(1, &texture); 218 glBindTexture(GL_TEXTURE_2D, texture); 219 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 220 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 221 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 222 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 223 } 224 225 void render(int quads) 226 { 227 int i, j; 228 229 const GLfloat vertices[] = { 230 -1, -1, 0, 231 1, -1, 0, 232 1, 1, 0, 233 -1, 1, 0 234 }; 235 236 const GLfixed texCoords[] = { 237 0, 0, 238 FIXED_ONE, 0, 239 FIXED_ONE, FIXED_ONE, 240 0, FIXED_ONE 241 }; 242 243 const GLushort quadIndices[] = { 0, 1, 2, 0, 2, 3 }; 244 245 246 GLushort* indices = (GLushort*)malloc(quads*sizeof(quadIndices)); 247 for (i=0 ; i<quads ; i++) 248 memcpy(indices+(sizeof(quadIndices)/sizeof(indices[0]))*i, quadIndices, sizeof(quadIndices)); 249 250 glVertexPointer(3, GL_FLOAT, 0, vertices); 251 glTexCoordPointer(2, GL_FIXED, 0, texCoords); 252 253 // make sure to do a couple eglSwapBuffers to make sure there are 254 // no problems with the very first ones (who knows) 255 glClearColor(0.4, 0.4, 0.4, 0.4); 256 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 257 eglSwapBuffers(eglDisplay, eglSurface); 258 glClearColor(0.6, 0.6, 0.6, 0.6); 259 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 260 eglSwapBuffers(eglDisplay, eglSurface); 261 glClearColor(1.0, 1.0, 1.0, 1.0); 262 263 for (j=0 ; j<10 ; j++) { 264 printf("loop %d / 10 (%d quads / loop)\n", j, quads); 265 266 int nelem = sizeof(quadIndices)/sizeof(quadIndices[0]); 267 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 268 glDrawElements(GL_TRIANGLES, nelem*quads, GL_UNSIGNED_SHORT, indices); 269 eglSwapBuffers(eglDisplay, eglSurface); 270 } 271 272 free(indices); 273 } 274 275