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 
16 using namespace android;
17 
18 EGLDisplay eglDisplay;
19 EGLSurface eglSurface;
20 EGLContext eglContext;
21 GLuint texture;
22 
23 #define FIXED_ONE 0x10000
24 #define ITERATIONS 50
25 
26 int init_gl_surface(const WindowSurface& windowSurface);
27 void free_gl_surface(void);
28 void init_scene(void);
29 void render();
30 void create_texture(void);
31 int readTimer(void);
32 
printGLString(const char * name,GLenum s)33 static 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 
gluLookAt(float eyeX,float eyeY,float eyeZ,float centerX,float centerY,float centerZ,float upX,float upY,float upZ)38 static 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 
printEGLConfiguration(EGLDisplay dpy,EGLConfig config)97 void 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 
checkEglError(const char * op,EGLBoolean returnVal=EGL_TRUE)148 static 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 
printEGLConfigurations(EGLDisplay dpy)160 int 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 
main(int argc,char ** argv)192 int 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 
init_gl_surface(const WindowSurface & windowSurface)213 int 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 
free_gl_surface(void)280 void 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 
init_scene(void)293 void 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 
create_texture(void)313 void 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 
render()337 void 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