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 
gluLookAt(float eyeX,float eyeY,float eyeZ,float centerX,float centerY,float centerZ,float upX,float upY,float upZ)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 
main(int argc,char ** argv)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 
init_gl_surface(const WindowSurface & windowSurface)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 
free_gl_surface(void)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 
init_scene(void)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 
create_texture(void)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 
render(int quads)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