OSDN Git Service

es: update window title
[android-x86/external-mesa.git] / progs / es1 / xegl / tri.c
1 /*
2  * Copyright (C) 2008  Brian Paul   All Rights Reserved.
3  * 
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  * 
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  * 
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20  */
21
22 /*
23  * Draw a triangle with X/EGL and OpenGL ES 1.x
24  * Brian Paul
25  * 5 June 2008
26  */
27
28 #define USE_FULL_GL 0
29
30 #define USE_FIXED_POINT 0
31
32
33 #include <assert.h>
34 #include <math.h>
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <X11/Xlib.h>
39 #include <X11/Xutil.h>
40 #include <X11/keysym.h>
41 #if USE_FULL_GL
42 #include <GL/gl.h>  /* use full OpenGL */
43 #else
44 #include <GLES/gl.h>  /* use OpenGL ES 1.x */
45 #include <GLES/glext.h>
46 #endif
47 #include <EGL/egl.h>
48
49
50 #define FLOAT_TO_FIXED(X)   ((X) * 65535.0)
51
52
53
54 static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0;
55
56
57 static void
58 draw(void)
59 {
60 #if USE_FIXED_POINT
61    static const GLfixed verts[3][2] = {
62       { -65536, -65536 },
63       {  65536, -65536 },
64       {      0,  65536 }
65    };
66    static const GLfixed colors[3][4] = {
67       { 65536,     0,     0,    65536 },
68       {     0, 65536,     0 ,   65536},
69       {     0,     0, 65536 ,   65536}
70    };
71 #else
72    static const GLfloat verts[3][2] = {
73       { -1, -1 },
74       {  1, -1 },
75       {  0,  1 }
76    };
77    static const GLfloat colors[3][4] = {
78       { 1, 0, 0, 1 },
79       { 0, 1, 0, 1 },
80       { 0, 0, 1, 1 }
81    };
82 #endif
83
84    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
85
86    glPushMatrix();
87    glRotatef(view_rotx, 1, 0, 0);
88    glRotatef(view_roty, 0, 1, 0);
89    glRotatef(view_rotz, 0, 0, 1);
90
91    {
92 #if USE_FIXED_POINT
93       glVertexPointer(2, GL_FIXED, 0, verts);
94       glColorPointer(4, GL_FIXED, 0, colors);
95 #else
96       glVertexPointer(2, GL_FLOAT, 0, verts);
97       glColorPointer(4, GL_FLOAT, 0, colors);
98 #endif
99       glEnableClientState(GL_VERTEX_ARRAY);
100       glEnableClientState(GL_COLOR_ARRAY);
101
102       /* draw triangle */
103       glDrawArrays(GL_TRIANGLES, 0, 3);
104
105       /* draw some points */
106       glPointSizex(FLOAT_TO_FIXED(15.5));
107       glDrawArrays(GL_POINTS, 0, 3);
108
109       glDisableClientState(GL_VERTEX_ARRAY);
110       glDisableClientState(GL_COLOR_ARRAY);
111    }
112
113    if (0) {
114       /* test code */
115       GLfixed size;
116       glGetFixedv(GL_POINT_SIZE, &size);
117       printf("GL_POINT_SIZE = 0x%x %f\n", size, size / 65536.0);
118    }
119
120    glPopMatrix();
121 }
122
123
124 /* new window size or exposure */
125 static void
126 reshape(int width, int height)
127 {
128    GLfloat ar = (GLfloat) width / (GLfloat) height;
129
130    glViewport(0, 0, (GLint) width, (GLint) height);
131
132    glMatrixMode(GL_PROJECTION);
133    glLoadIdentity();
134 #ifdef GL_VERSION_ES_CM_1_0
135    glFrustumf(-ar, ar, -1, 1, 5.0, 60.0);
136 #else
137    glFrustum(-ar, ar, -1, 1, 5.0, 60.0);
138 #endif
139    
140    glMatrixMode(GL_MODELVIEW);
141    glLoadIdentity();
142    glTranslatef(0.0, 0.0, -10.0);
143 }
144
145
146 static void
147 test_query_matrix(void)
148 {
149    PFNGLQUERYMATRIXXOESPROC procQueryMatrixx;
150    typedef void (*voidproc)();
151    GLfixed mantissa[16];
152    GLint exponent[16];
153    GLbitfield rv;
154    int i;
155    voidproc p = eglGetProcAddress("eglCreateContext");
156
157    assert(p);
158    procQueryMatrixx = (PFNGLQUERYMATRIXXOESPROC) eglGetProcAddress("glQueryMatrixxOES");
159    assert(procQueryMatrixx);
160    /* Actually try out this one */
161    rv = (*procQueryMatrixx)(mantissa, exponent);
162    for (i = 0; i < 16; i++) {
163       if (rv & (1<<i)) {
164         printf("matrix[%d] invalid\n", i);
165       }
166       else {
167          printf("matrix[%d] = %f * 2^(%d)\n", i, mantissa[i]/65536.0, exponent[i]);
168       }
169    }
170    p = eglGetProcAddress("glFoo");
171    assert(!p);
172 }
173
174
175 static void
176 init(void)
177 {
178    glClearColor(0.4, 0.4, 0.4, 0.0);
179
180    if (0)
181       test_query_matrix();
182 }
183
184
185 /*
186  * Create an RGB, double-buffered X window.
187  * Return the window and context handles.
188  */
189 static void
190 make_x_window(Display *x_dpy, EGLDisplay egl_dpy,
191               const char *name,
192               int x, int y, int width, int height,
193               Window *winRet,
194               EGLContext *ctxRet,
195               EGLSurface *surfRet)
196 {
197    static const EGLint attribs[] = {
198       EGL_RED_SIZE, 1,
199       EGL_GREEN_SIZE, 1,
200       EGL_BLUE_SIZE, 1,
201       EGL_DEPTH_SIZE, 1,
202       EGL_NONE
203    };
204
205    int scrnum;
206    XSetWindowAttributes attr;
207    unsigned long mask;
208    Window root;
209    Window win;
210    XVisualInfo *visInfo, visTemplate;
211    int num_visuals;
212    EGLContext ctx;
213    EGLConfig config;
214    EGLint num_configs;
215    EGLint vid;
216
217    scrnum = DefaultScreen( x_dpy );
218    root = RootWindow( x_dpy, scrnum );
219
220    if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) {
221       printf("Error: couldn't get an EGL visual config\n");
222       exit(1);
223    }
224
225    assert(config);
226    assert(num_configs > 0);
227
228    if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
229       printf("Error: eglGetConfigAttrib() failed\n");
230       exit(1);
231    }
232
233    /* The X window visual must match the EGL config */
234    visTemplate.visualid = vid;
235    visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals);
236    if (!visInfo) {
237       printf("Error: couldn't get X visual\n");
238       exit(1);
239    }
240
241    /* window attributes */
242    attr.background_pixel = 0;
243    attr.border_pixel = 0;
244    attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone);
245    attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
246    mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
247
248    win = XCreateWindow( x_dpy, root, 0, 0, width, height,
249                         0, visInfo->depth, InputOutput,
250                         visInfo->visual, mask, &attr );
251
252    /* set hints and properties */
253    {
254       XSizeHints sizehints;
255       sizehints.x = x;
256       sizehints.y = y;
257       sizehints.width  = width;
258       sizehints.height = height;
259       sizehints.flags = USSize | USPosition;
260       XSetNormalHints(x_dpy, win, &sizehints);
261       XSetStandardProperties(x_dpy, win, name, name,
262                               None, (char **)NULL, 0, &sizehints);
263    }
264
265 #if USE_FULL_GL
266    eglBindAPI(EGL_OPENGL_API);
267 #else
268    eglBindAPI(EGL_OPENGL_ES_API);
269 #endif
270
271    ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL );
272    if (!ctx) {
273       printf("Error: eglCreateContext failed\n");
274       exit(1);
275    }
276
277    *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL);
278
279    if (!*surfRet) {
280       printf("Error: eglCreateWindowSurface failed\n");
281       exit(1);
282    }
283
284    XFree(visInfo);
285
286    *winRet = win;
287    *ctxRet = ctx;
288 }
289
290
291 static void
292 event_loop(Display *dpy, Window win,
293            EGLDisplay egl_dpy, EGLSurface egl_surf)
294 {
295    while (1) {
296       int redraw = 0;
297       XEvent event;
298
299       XNextEvent(dpy, &event);
300
301       switch (event.type) {
302       case Expose:
303          redraw = 1;
304          break;
305       case ConfigureNotify:
306          reshape(event.xconfigure.width, event.xconfigure.height);
307          break;
308       case KeyPress:
309          {
310             char buffer[10];
311             int r, code;
312             code = XLookupKeysym(&event.xkey, 0);
313             if (code == XK_Left) {
314                view_roty += 5.0;
315             }
316             else if (code == XK_Right) {
317                view_roty -= 5.0;
318             }
319             else if (code == XK_Up) {
320                view_rotx += 5.0;
321             }
322             else if (code == XK_Down) {
323                view_rotx -= 5.0;
324             }
325             else {
326                r = XLookupString(&event.xkey, buffer, sizeof(buffer),
327                                  NULL, NULL);
328                if (buffer[0] == 27) {
329                   /* escape */
330                   return;
331                }
332             }
333          }
334          redraw = 1;
335          break;
336       default:
337          ; /*no-op*/
338       }
339
340       if (redraw) {
341          draw();
342          eglSwapBuffers(egl_dpy, egl_surf);
343       }
344    }
345 }
346
347
348 static void
349 usage(void)
350 {
351    printf("Usage:\n");
352    printf("  -display <displayname>  set the display to run on\n");
353    printf("  -info                   display OpenGL renderer info\n");
354 }
355  
356
357 int
358 main(int argc, char *argv[])
359 {
360    const int winWidth = 300, winHeight = 300;
361    Display *x_dpy;
362    Window win;
363    EGLSurface egl_surf;
364    EGLContext egl_ctx;
365    EGLDisplay egl_dpy;
366    char *dpyName = NULL;
367    GLboolean printInfo = GL_FALSE;
368    EGLint egl_major, egl_minor;
369    int i;
370    const char *s;
371
372    static struct {
373       char *name;
374       GLenum value;
375       enum {GetString, GetInteger} type;
376    } info_items[] = {
377       {"GL_RENDERER", GL_RENDERER, GetString},
378       {"GL_VERSION", GL_VERSION, GetString},
379       {"GL_VENDOR", GL_VENDOR, GetString},
380       {"GL_EXTENSIONS", GL_EXTENSIONS, GetString},
381       {"GL_MAX_PALETTE_MATRICES_OES", GL_MAX_PALETTE_MATRICES_OES, GetInteger},
382       {"GL_MAX_VERTEX_UNITS_OES", GL_MAX_VERTEX_UNITS_OES, GetInteger},
383    };
384
385    for (i = 1; i < argc; i++) {
386       if (strcmp(argv[i], "-display") == 0) {
387          dpyName = argv[i+1];
388          i++;
389       }
390       else if (strcmp(argv[i], "-info") == 0) {
391          printInfo = GL_TRUE;
392       }
393       else {
394          usage();
395          return -1;
396       }
397    }
398
399    x_dpy = XOpenDisplay(dpyName);
400    if (!x_dpy) {
401       printf("Error: couldn't open display %s\n",
402              dpyName ? dpyName : getenv("DISPLAY"));
403       return -1;
404    }
405
406    egl_dpy = eglGetDisplay(x_dpy);
407    if (!egl_dpy) {
408       printf("Error: eglGetDisplay() failed\n");
409       return -1;
410    }
411
412    if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) {
413       printf("Error: eglInitialize() failed\n");
414       return -1;
415    }
416
417    s = eglQueryString(egl_dpy, EGL_VERSION);
418    printf("EGL_VERSION = %s\n", s);
419
420    s = eglQueryString(egl_dpy, EGL_VENDOR);
421    printf("EGL_VENDOR = %s\n", s);
422
423    s = eglQueryString(egl_dpy, EGL_EXTENSIONS);
424    printf("EGL_EXTENSIONS = %s\n", s);
425
426    s = eglQueryString(egl_dpy, EGL_CLIENT_APIS);
427    printf("EGL_CLIENT_APIS = %s\n", s);
428
429    make_x_window(x_dpy, egl_dpy,
430                  "OpenGL ES 1.x tri", 0, 0, winWidth, winHeight,
431                  &win, &egl_ctx, &egl_surf);
432
433    XMapWindow(x_dpy, win);
434    if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) {
435       printf("Error: eglMakeCurrent() failed\n");
436       return -1;
437    }
438
439    if (printInfo) {
440       for (i = 0; i < sizeof(info_items)/sizeof(info_items[0]); i++) {
441          switch (info_items[i].type) {
442             case GetString:
443                printf("%s = %s\n", info_items[i].name, (char *)glGetString(info_items[i].value));
444                break;
445             case GetInteger: {
446                GLint rv = -1;
447                glGetIntegerv(info_items[i].value, &rv);
448                printf("%s = %d\n", info_items[i].name, rv);
449                break;
450             }
451          }
452       }
453    };
454    init();
455
456    /* Set initial projection/viewing transformation.
457     * We can't be sure we'll get a ConfigureNotify event when the window
458     * first appears.
459     */
460    reshape(winWidth, winHeight);
461
462    event_loop(x_dpy, win, egl_dpy, egl_surf);
463
464    eglDestroyContext(egl_dpy, egl_ctx);
465    eglDestroySurface(egl_dpy, egl_surf);
466    eglTerminate(egl_dpy);
467
468
469    XDestroyWindow(x_dpy, win);
470    XCloseDisplay(x_dpy);
471
472    return 0;
473 }