.*.sw?
+*.a
+*.o
*.pyc
+*.so
CMakeCache.txt
CMakeFiles
CTestTestfile.cmake
project (apitrace-tests)
+include (FindPkgConfig)
+
# Set default built type
if (NOT CMAKE_BUILD_TYPE)
set (CMAKE_BUILD_TYPE Debug
find_path (GLEW_INCLUDE_DIR GL/glew.h /usr/include/GL)
find_library (GLEW_glew_LIBRARY GLEW /usr/lib)
+if (NOT WIN32)
+ pkg_check_modules (EGL egl)
+ pkg_check_modules (GLESV1 glesv1_cm)
+ pkg_check_modules (GLESV2 glesv2)
+ pkg_check_modules (VG vg)
+endif ()
+
if (UNIX)
link_libraries(m)
endif (UNIX)
if (OPENGL_FOUND)
add_subdirectory (gl)
endif ()
+
+if (EGL_FOUND)
+ add_subdirectory (egl)
+endif ()
--- /dev/null
+add_subdirectory(eglut)
+
+if (OPENGL_FOUND)
+ add_subdirectory(gl)
+endif ()
+
+if (GLESV1_FOUND)
+ add_subdirectory(gles1)
+endif ()
+
+if (GLESV2_FOUND)
+ add_subdirectory(gles2)
+endif ()
--- /dev/null
+include_directories (
+ ${EGL_INCLUDE_DIRS}
+)
+
+if (X11_FOUND)
+ add_library (eglut eglut.c eglut_x11.c)
+ target_link_libraries (eglut ${EGL_LIBRARIES} ${X11_X11_LIB})
+else ()
+ add_library (eglut eglut.c eglut_screen.c)
+ target_link_libraries (eglut ${EGL_LIBRARIES})
+endif ()
+
--- /dev/null
+/*
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <sys/time.h>
+
+#include "EGL/egl.h"
+#include "EGL/eglext.h"
+
+#include "eglutint.h"
+
+static struct eglut_state _eglut_state = {
+ .api_mask = EGLUT_OPENGL_ES1_BIT,
+ .window_width = 300,
+ .window_height = 300,
+ .verbose = 0,
+ .num_windows = 0,
+};
+
+struct eglut_state *_eglut = &_eglut_state;
+
+void
+_eglutFatal(char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+
+ fprintf(stderr, "EGLUT: ");
+ vfprintf(stderr, format, args);
+ va_end(args);
+ putc('\n', stderr);
+
+ exit(1);
+}
+
+/* return current time (in milliseconds) */
+int
+_eglutNow(void)
+{
+ struct timeval tv;
+#ifdef __VMS
+ (void) gettimeofday(&tv, NULL );
+#else
+ struct timezone tz;
+ (void) gettimeofday(&tv, &tz);
+#endif
+ return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}
+
+static void
+_eglutDestroyWindow(struct eglut_window *win)
+{
+ if (_eglut->surface_type != EGL_PBUFFER_BIT &&
+ _eglut->surface_type != EGL_SCREEN_BIT_MESA)
+ eglDestroySurface(_eglut->dpy, win->surface);
+
+ _eglutNativeFiniWindow(win);
+
+ eglDestroyContext(_eglut->dpy, win->context);
+}
+
+static EGLConfig
+_eglutChooseConfig(void)
+{
+ EGLConfig config;
+ EGLint config_attribs[32];
+ EGLint renderable_type, num_configs, i;
+
+ i = 0;
+ config_attribs[i++] = EGL_RED_SIZE;
+ config_attribs[i++] = 1;
+ config_attribs[i++] = EGL_GREEN_SIZE;
+ config_attribs[i++] = 1;
+ config_attribs[i++] = EGL_BLUE_SIZE;
+ config_attribs[i++] = 1;
+ config_attribs[i++] = EGL_DEPTH_SIZE;
+ config_attribs[i++] = 1;
+
+ config_attribs[i++] = EGL_SURFACE_TYPE;
+ config_attribs[i++] = _eglut->surface_type;
+
+ config_attribs[i++] = EGL_RENDERABLE_TYPE;
+ renderable_type = 0x0;
+ if (_eglut->api_mask & EGLUT_OPENGL_BIT)
+ renderable_type |= EGL_OPENGL_BIT;
+ if (_eglut->api_mask & EGLUT_OPENGL_ES1_BIT)
+ renderable_type |= EGL_OPENGL_ES_BIT;
+ if (_eglut->api_mask & EGLUT_OPENGL_ES2_BIT)
+ renderable_type |= EGL_OPENGL_ES2_BIT;
+ if (_eglut->api_mask & EGLUT_OPENVG_BIT)
+ renderable_type |= EGL_OPENVG_BIT;
+ config_attribs[i++] = renderable_type;
+
+ config_attribs[i] = EGL_NONE;
+
+ if (!eglChooseConfig(_eglut->dpy,
+ config_attribs, &config, 1, &num_configs) || !num_configs)
+ _eglutFatal("failed to choose a config");
+
+ return config;
+}
+
+static struct eglut_window *
+_eglutCreateWindow(const char *title, int x, int y, int w, int h)
+{
+ struct eglut_window *win;
+ EGLint context_attribs[4];
+ EGLint api, i;
+
+ win = calloc(1, sizeof(*win));
+ if (!win)
+ _eglutFatal("failed to allocate window");
+
+ win->config = _eglutChooseConfig();
+
+ i = 0;
+ context_attribs[i] = EGL_NONE;
+
+ /* multiple APIs? */
+
+ api = EGL_OPENGL_ES_API;
+ if (_eglut->api_mask & EGLUT_OPENGL_BIT) {
+ api = EGL_OPENGL_API;
+ }
+ else if (_eglut->api_mask & EGLUT_OPENVG_BIT) {
+ api = EGL_OPENVG_API;
+ }
+ else if (_eglut->api_mask & EGLUT_OPENGL_ES2_BIT) {
+ context_attribs[i++] = EGL_CONTEXT_CLIENT_VERSION;
+ context_attribs[i++] = 2;
+ }
+
+ context_attribs[i] = EGL_NONE;
+
+ eglBindAPI(api);
+ win->context = eglCreateContext(_eglut->dpy,
+ win->config, EGL_NO_CONTEXT, context_attribs);
+ if (!win->context)
+ _eglutFatal("failed to create context");
+
+ _eglutNativeInitWindow(win, title, x, y, w, h);
+ switch (_eglut->surface_type) {
+ case EGL_WINDOW_BIT:
+ win->surface = eglCreateWindowSurface(_eglut->dpy,
+ win->config, win->native.u.window, NULL);
+ break;
+ case EGL_PIXMAP_BIT:
+ win->surface = eglCreatePixmapSurface(_eglut->dpy,
+ win->config, win->native.u.pixmap, NULL);
+ break;
+ case EGL_PBUFFER_BIT:
+ case EGL_SCREEN_BIT_MESA:
+ win->surface = win->native.u.surface;
+ break;
+ default:
+ break;
+ }
+ if (win->surface == EGL_NO_SURFACE)
+ _eglutFatal("failed to create surface");
+
+ return win;
+}
+
+void
+eglutInitAPIMask(int mask)
+{
+ _eglut->api_mask = mask;
+}
+
+void
+eglutInitWindowSize(int width, int height)
+{
+ _eglut->window_width = width;
+ _eglut->window_height = height;
+}
+
+void
+eglutInit(int argc, char **argv)
+{
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-display") == 0)
+ _eglut->display_name = argv[++i];
+ else if (strcmp(argv[i], "-info") == 0) {
+ _eglut->verbose = 1;
+ }
+ }
+
+ _eglutNativeInitDisplay();
+ _eglut->dpy = eglGetDisplay(_eglut->native_dpy);
+
+ if (!eglInitialize(_eglut->dpy, &_eglut->major, &_eglut->minor))
+ _eglutFatal("failed to initialize EGL display");
+
+ _eglut->init_time = _eglutNow();
+
+ printf("EGL_VERSION = %s\n", eglQueryString(_eglut->dpy, EGL_VERSION));
+ if (_eglut->verbose) {
+ printf("EGL_VENDOR = %s\n", eglQueryString(_eglut->dpy, EGL_VENDOR));
+ printf("EGL_EXTENSIONS = %s\n",
+ eglQueryString(_eglut->dpy, EGL_EXTENSIONS));
+ printf("EGL_CLIENT_APIS = %s\n",
+ eglQueryString(_eglut->dpy, EGL_CLIENT_APIS));
+ }
+}
+
+int
+eglutGet(int state)
+{
+ int val;
+
+ switch (state) {
+ case EGLUT_ELAPSED_TIME:
+ val = _eglutNow() - _eglut->init_time;
+ break;
+ default:
+ val = -1;
+ break;
+ }
+
+ return val;
+}
+
+void
+eglutIdleFunc(EGLUTidleCB func)
+{
+ _eglut->idle_cb = func;
+}
+
+void
+eglutPostRedisplay(void)
+{
+ _eglut->redisplay = 1;
+}
+
+void
+eglutMainLoop(void)
+{
+ struct eglut_window *win = _eglut->current;
+
+ if (!win)
+ _eglutFatal("no window is created\n");
+
+ if (win->reshape_cb)
+ win->reshape_cb(win->native.width, win->native.height);
+
+ _eglutNativeEventLoop();
+}
+
+static void
+_eglutFini(void)
+{
+ eglTerminate(_eglut->dpy);
+ _eglutNativeFiniDisplay();
+}
+
+void
+eglutDestroyWindow(int win)
+{
+ struct eglut_window *window = _eglut->current;
+
+ if (window->index != win)
+ return;
+
+ /* XXX it causes some bug in st/egl KMS backend */
+ if ( _eglut->surface_type != EGL_SCREEN_BIT_MESA)
+ eglMakeCurrent(_eglut->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+ _eglutDestroyWindow(_eglut->current);
+}
+
+static void
+_eglutDefaultKeyboard(unsigned char key)
+{
+ if (key == 27) {
+ if (_eglut->current)
+ eglutDestroyWindow(_eglut->current->index);
+ _eglutFini();
+
+ exit(0);
+ }
+}
+
+int
+eglutCreateWindow(const char *title)
+{
+ struct eglut_window *win;
+
+ win = _eglutCreateWindow(title, 0, 0,
+ _eglut->window_width, _eglut->window_height);
+
+ win->index = _eglut->num_windows++;
+ win->reshape_cb = NULL;
+ win->display_cb = NULL;
+ win->keyboard_cb = _eglutDefaultKeyboard;
+ win->special_cb = NULL;
+
+ if (!eglMakeCurrent(_eglut->dpy, win->surface, win->surface, win->context))
+ _eglutFatal("failed to make window current");
+ _eglut->current = win;
+
+ return win->index;
+}
+
+int
+eglutGetWindowWidth(void)
+{
+ struct eglut_window *win = _eglut->current;
+ return win->native.width;
+}
+
+int
+eglutGetWindowHeight(void)
+{
+ struct eglut_window *win = _eglut->current;
+ return win->native.height;
+}
+
+void
+eglutDisplayFunc(EGLUTdisplayCB func)
+{
+ struct eglut_window *win = _eglut->current;
+ win->display_cb = func;
+
+}
+
+void
+eglutReshapeFunc(EGLUTreshapeCB func)
+{
+ struct eglut_window *win = _eglut->current;
+ win->reshape_cb = func;
+}
+
+void
+eglutKeyboardFunc(EGLUTkeyboardCB func)
+{
+ struct eglut_window *win = _eglut->current;
+ win->keyboard_cb = func;
+}
+
+void
+eglutSpecialFunc(EGLUTspecialCB func)
+{
+ struct eglut_window *win = _eglut->current;
+ win->special_cb = func;
+}
--- /dev/null
+/*
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef EGLUT_H
+#define EGLUT_H
+
+/* used by eglutInitAPIMask */
+enum {
+ EGLUT_OPENGL_BIT = 0x1,
+ EGLUT_OPENGL_ES1_BIT = 0x2,
+ EGLUT_OPENGL_ES2_BIT = 0x4,
+ EGLUT_OPENVG_BIT = 0x8
+};
+
+/* used by EGLUTspecialCB */
+enum {
+ /* function keys */
+ EGLUT_KEY_F1,
+ EGLUT_KEY_F2,
+ EGLUT_KEY_F3,
+ EGLUT_KEY_F4,
+ EGLUT_KEY_F5,
+ EGLUT_KEY_F6,
+ EGLUT_KEY_F7,
+ EGLUT_KEY_F8,
+ EGLUT_KEY_F9,
+ EGLUT_KEY_F10,
+ EGLUT_KEY_F11,
+ EGLUT_KEY_F12,
+
+ /* directional keys */
+ EGLUT_KEY_LEFT,
+ EGLUT_KEY_UP,
+ EGLUT_KEY_RIGHT,
+ EGLUT_KEY_DOWN,
+};
+
+/* used by eglutGet */
+enum {
+ EGLUT_ELAPSED_TIME
+};
+
+typedef void (*EGLUTidleCB)(void);
+typedef void (*EGLUTreshapeCB)(int, int);
+typedef void (*EGLUTdisplayCB)(void);
+typedef void (*EGLUTkeyboardCB)(unsigned char);
+typedef void (*EGLUTspecialCB)(int);
+
+void eglutInitAPIMask(int mask);
+void eglutInitWindowSize(int width, int height);
+void eglutInit(int argc, char **argv);
+
+int eglutGet(int state);
+
+void eglutIdleFunc(EGLUTidleCB func);
+void eglutPostRedisplay(void);
+
+void eglutMainLoop(void);
+
+int eglutCreateWindow(const char *title);
+void eglutDestroyWindow(int win);
+
+int eglutGetWindowWidth(void);
+int eglutGetWindowHeight(void);
+
+void eglutDisplayFunc(EGLUTdisplayCB func);
+void eglutReshapeFunc(EGLUTreshapeCB func);
+void eglutKeyboardFunc(EGLUTkeyboardCB func);
+void eglutSpecialFunc(EGLUTspecialCB func);
+
+#endif /* EGLUT_H */
--- /dev/null
+/*
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+
+#define EGL_EGLEXT_PROTOTYPES
+#include "EGL/egl.h"
+#include "EGL/eglext.h"
+
+#include "eglutint.h"
+
+#define MAX_MODES 100
+
+static EGLScreenMESA kms_screen;
+static EGLModeMESA kms_mode;
+static EGLint kms_width, kms_height;
+
+void
+_eglutNativeInitDisplay(void)
+{
+ _eglut->native_dpy = EGL_DEFAULT_DISPLAY;
+ _eglut->surface_type = EGL_SCREEN_BIT_MESA;
+}
+
+void
+_eglutNativeFiniDisplay(void)
+{
+ kms_screen = 0;
+ kms_mode = 0;
+ kms_width = 0;
+ kms_height = 0;
+}
+
+static void
+init_kms(void)
+{
+ EGLModeMESA modes[MAX_MODES];
+ EGLint num_screens, num_modes;
+ EGLint width, height, best_mode;
+ EGLint i;
+
+ if (!eglGetScreensMESA(_eglut->dpy, &kms_screen, 1, &num_screens) ||
+ !num_screens)
+ _eglutFatal("eglGetScreensMESA failed\n");
+
+ if (!eglGetModesMESA(_eglut->dpy, kms_screen,
+ modes, MAX_MODES, &num_modes) || !num_modes)
+ _eglutFatal("eglGetModesMESA failed!\n");
+
+ printf("Found %d modes:\n", num_modes);
+
+ best_mode = 0;
+ width = 0;
+ height = 0;
+ for (i = 0; i < num_modes; i++) {
+ EGLint w, h;
+ eglGetModeAttribMESA(_eglut->dpy, modes[i], EGL_WIDTH, &w);
+ eglGetModeAttribMESA(_eglut->dpy, modes[i], EGL_HEIGHT, &h);
+ printf("%3d: %d x %d\n", i, w, h);
+ if (w > width && h > height) {
+ width = w;
+ height = h;
+ best_mode = i;
+ }
+ }
+
+ printf("Will use screen size: %d x %d\n", width, height);
+
+ kms_mode = modes[best_mode];
+ kms_width = width;
+ kms_height = height;
+}
+
+void
+_eglutNativeInitWindow(struct eglut_window *win, const char *title,
+ int x, int y, int w, int h)
+{
+ EGLint surf_attribs[16];
+ EGLint i;
+ const char *exts;
+
+ exts = eglQueryString(_eglut->dpy, EGL_EXTENSIONS);
+ if (!exts || !strstr(exts, "EGL_MESA_screen_surface"))
+ _eglutFatal("EGL_MESA_screen_surface is not supported\n");
+
+ init_kms();
+
+ i = 0;
+ surf_attribs[i++] = EGL_WIDTH;
+ surf_attribs[i++] = kms_width;
+ surf_attribs[i++] = EGL_HEIGHT;
+ surf_attribs[i++] = kms_height;
+ surf_attribs[i++] = EGL_NONE;
+
+ /* create surface */
+ win->native.u.surface = eglCreateScreenSurfaceMESA(_eglut->dpy,
+ win->config, surf_attribs);
+ if (win->native.u.surface == EGL_NO_SURFACE)
+ _eglutFatal("eglCreateScreenSurfaceMESA failed\n");
+
+ if (!eglShowScreenSurfaceMESA(_eglut->dpy, kms_screen,
+ win->native.u.surface, kms_mode))
+ _eglutFatal("eglShowScreenSurfaceMESA failed\n");
+
+ win->native.width = kms_width;
+ win->native.height = kms_height;
+}
+
+void
+_eglutNativeFiniWindow(struct eglut_window *win)
+{
+ eglShowScreenSurfaceMESA(_eglut->dpy,
+ kms_screen, EGL_NO_SURFACE, 0);
+ eglDestroySurface(_eglut->dpy, win->native.u.surface);
+}
+
+void
+_eglutNativeEventLoop(void)
+{
+ int start = _eglutNow();
+ int frames = 0;
+
+ _eglut->redisplay = 1;
+
+ while (1) {
+ struct eglut_window *win = _eglut->current;
+ int now = _eglutNow();
+
+ if (now - start > 5000) {
+ double elapsed = (double) (now - start) / 1000.0;
+
+ printf("%d frames in %3.1f seconds = %6.3f FPS\n",
+ frames, elapsed, frames / elapsed);
+ fflush(stdout);
+
+ start = now;
+ frames = 0;
+
+ /* send escape */
+ if (win->keyboard_cb)
+ win->keyboard_cb(27);
+ }
+
+ if (_eglut->idle_cb)
+ _eglut->idle_cb();
+
+ if (_eglut->redisplay) {
+ _eglut->redisplay = 0;
+
+ if (win->display_cb)
+ win->display_cb();
+ eglSwapBuffers(_eglut->dpy, win->surface);
+ frames++;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+
+#include "eglutint.h"
+
+void
+_eglutNativeInitDisplay(void)
+{
+ _eglut->native_dpy = XOpenDisplay(_eglut->display_name);
+ if (!_eglut->native_dpy)
+ _eglutFatal("failed to initialize native display");
+
+ _eglut->surface_type = EGL_WINDOW_BIT;
+}
+
+void
+_eglutNativeFiniDisplay(void)
+{
+ XCloseDisplay(_eglut->native_dpy);
+}
+
+void
+_eglutNativeInitWindow(struct eglut_window *win, const char *title,
+ int x, int y, int w, int h)
+{
+ XVisualInfo *visInfo, visTemplate;
+ int num_visuals;
+ Window root, xwin;
+ XSetWindowAttributes attr;
+ unsigned long mask;
+ EGLint vid;
+
+ if (!eglGetConfigAttrib(_eglut->dpy,
+ win->config, EGL_NATIVE_VISUAL_ID, &vid))
+ _eglutFatal("failed to get visual id");
+
+ /* The X window visual must match the EGL config */
+ visTemplate.visualid = vid;
+ visInfo = XGetVisualInfo(_eglut->native_dpy,
+ VisualIDMask, &visTemplate, &num_visuals);
+ if (!visInfo)
+ _eglutFatal("failed to get an visual of id 0x%x", vid);
+
+ root = RootWindow(_eglut->native_dpy, DefaultScreen(_eglut->native_dpy));
+
+ /* window attributes */
+ attr.background_pixel = 0;
+ attr.border_pixel = 0;
+ attr.colormap = XCreateColormap(_eglut->native_dpy,
+ root, visInfo->visual, AllocNone);
+ attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+ xwin = XCreateWindow(_eglut->native_dpy, root, x, y, w, h,
+ 0, visInfo->depth, InputOutput, visInfo->visual, mask, &attr);
+ if (!xwin)
+ _eglutFatal("failed to create a window");
+
+ XFree(visInfo);
+
+ /* set hints and properties */
+ {
+ XSizeHints sizehints;
+ sizehints.x = x;
+ sizehints.y = y;
+ sizehints.width = w;
+ sizehints.height = h;
+ sizehints.flags = USSize | USPosition;
+ XSetNormalHints(_eglut->native_dpy, xwin, &sizehints);
+ XSetStandardProperties(_eglut->native_dpy, xwin,
+ title, title, None, (char **) NULL, 0, &sizehints);
+ }
+
+ XMapWindow(_eglut->native_dpy, xwin);
+
+ win->native.u.window = xwin;
+ win->native.width = w;
+ win->native.height = h;
+}
+
+void
+_eglutNativeFiniWindow(struct eglut_window *win)
+{
+ XDestroyWindow(_eglut->native_dpy, win->native.u.window);
+}
+
+static int
+lookup_keysym(KeySym sym)
+{
+ int special;
+
+ switch (sym) {
+ case XK_F1:
+ special = EGLUT_KEY_F1;
+ break;
+ case XK_F2:
+ special = EGLUT_KEY_F2;
+ break;
+ case XK_F3:
+ special = EGLUT_KEY_F3;
+ break;
+ case XK_F4:
+ special = EGLUT_KEY_F4;
+ break;
+ case XK_F5:
+ special = EGLUT_KEY_F5;
+ break;
+ case XK_F6:
+ special = EGLUT_KEY_F6;
+ break;
+ case XK_F7:
+ special = EGLUT_KEY_F7;
+ break;
+ case XK_F8:
+ special = EGLUT_KEY_F8;
+ break;
+ case XK_F9:
+ special = EGLUT_KEY_F9;
+ break;
+ case XK_F10:
+ special = EGLUT_KEY_F10;
+ break;
+ case XK_F11:
+ special = EGLUT_KEY_F11;
+ break;
+ case XK_F12:
+ special = EGLUT_KEY_F12;
+ break;
+ case XK_KP_Left:
+ case XK_Left:
+ special = EGLUT_KEY_LEFT;
+ break;
+ case XK_KP_Up:
+ case XK_Up:
+ special = EGLUT_KEY_UP;
+ break;
+ case XK_KP_Right:
+ case XK_Right:
+ special = EGLUT_KEY_RIGHT;
+ break;
+ case XK_KP_Down:
+ case XK_Down:
+ special = EGLUT_KEY_DOWN;
+ break;
+ default:
+ special = -1;
+ break;
+ }
+
+ return special;
+}
+
+static void
+next_event(struct eglut_window *win)
+{
+ int redraw = 0;
+ XEvent event;
+
+ if (!XPending(_eglut->native_dpy)) {
+ /* there is an idle callback */
+ if (_eglut->idle_cb) {
+ _eglut->idle_cb();
+ return;
+ }
+
+ /* the app requests re-display */
+ if (_eglut->redisplay)
+ return;
+ }
+
+ /* block for next event */
+ XNextEvent(_eglut->native_dpy, &event);
+
+ switch (event.type) {
+ case Expose:
+ redraw = 1;
+ break;
+ case ConfigureNotify:
+ win->native.width = event.xconfigure.width;
+ win->native.height = event.xconfigure.height;
+ if (win->reshape_cb)
+ win->reshape_cb(win->native.width, win->native.height);
+ break;
+ case KeyPress:
+ {
+ char buffer[1];
+ KeySym sym;
+ int r;
+
+ r = XLookupString(&event.xkey,
+ buffer, sizeof(buffer), &sym, NULL);
+ if (r && win->keyboard_cb) {
+ win->keyboard_cb(buffer[0]);
+ }
+ else if (!r && win->special_cb) {
+ r = lookup_keysym(sym);
+ if (r >= 0)
+ win->special_cb(r);
+ }
+ }
+ redraw = 1;
+ break;
+ default:
+ ; /*no-op*/
+ }
+
+ _eglut->redisplay = redraw;
+}
+
+void
+_eglutNativeEventLoop(void)
+{
+ while (1) {
+ struct eglut_window *win = _eglut->current;
+
+ next_event(win);
+
+ if (_eglut->redisplay) {
+ _eglut->redisplay = 0;
+
+ if (win->display_cb)
+ win->display_cb();
+ eglSwapBuffers(_eglut->dpy, win->surface);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef _EGLUTINT_H_
+#define _EGLUTINT_H_
+
+#include "EGL/egl.h"
+#include "eglut.h"
+
+struct eglut_window {
+ EGLConfig config;
+ EGLContext context;
+
+ /* initialized by native display */
+ struct {
+ union {
+ EGLNativeWindowType window;
+ EGLNativePixmapType pixmap;
+ EGLSurface surface; /* pbuffer or screen surface */
+ } u;
+ int width, height;
+ } native;
+
+ EGLSurface surface;
+
+ int index;
+
+ EGLUTreshapeCB reshape_cb;
+ EGLUTdisplayCB display_cb;
+ EGLUTkeyboardCB keyboard_cb;
+ EGLUTspecialCB special_cb;
+};
+
+struct eglut_state {
+ int api_mask;
+ int window_width, window_height;
+ const char *display_name;
+ int verbose;
+ int init_time;
+
+ EGLUTidleCB idle_cb;
+
+ int num_windows;
+
+ /* initialized by native display */
+ EGLNativeDisplayType native_dpy;
+ EGLint surface_type;
+
+ EGLDisplay dpy;
+ EGLint major, minor;
+
+ struct eglut_window *current;
+
+ int redisplay;
+};
+
+extern struct eglut_state *_eglut;
+
+void
+_eglutFatal(char *format, ...);
+
+int
+_eglutNow(void);
+
+void
+_eglutNativeInitDisplay(void);
+
+void
+_eglutNativeFiniDisplay(void);
+
+void
+_eglutNativeInitWindow(struct eglut_window *win, const char *title,
+ int x, int y, int w, int h);
+
+void
+_eglutNativeFiniWindow(struct eglut_window *win);
+
+void
+_eglutNativeEventLoop(void);
+
+#endif /* _EGLUTINT_H_ */
--- /dev/null
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}/../eglut
+ ${EGL_INCLUDE_DIRS}
+ ${OPENGL_INCLUDE_PATH}
+)
+
+set (api egl)
+
+set (targets
+ tri
+)
+
+foreach (target ${targets})
+ add_executable (${api}_${target} ${target}.c)
+ set_target_properties (${api}_${target} PROPERTIES OUTPUT_NAME ${target})
+ target_link_libraries (${api}_${target} eglut ${OPENGL_gl_LIBRARY})
+endforeach (target)
--- /dev/null
+/*
+ * Copyright (C) 2008 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Draw a triangle with X/EGL.
+ * Brian Paul
+ * 3 June 2008
+ */
+
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <GL/gl.h>
+
+#include "eglut.h"
+
+
+static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0;
+
+
+static void
+draw(void)
+{
+ static const GLfloat verts[3][2] = {
+ { -1, -1 },
+ { 1, -1 },
+ { 0, 1 }
+ };
+ static const GLfloat colors[3][3] = {
+ { 1, 0, 0 },
+ { 0, 1, 0 },
+ { 0, 0, 1 }
+ };
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glPushMatrix();
+ glRotatef(view_rotx, 1, 0, 0);
+ glRotatef(view_roty, 0, 1, 0);
+ glRotatef(view_rotz, 0, 0, 1);
+
+ {
+ glVertexPointer(2, GL_FLOAT, 0, verts);
+ glColorPointer(3, GL_FLOAT, 0, colors);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ }
+
+ glPopMatrix();
+}
+
+
+/* new window size or exposure */
+static void
+reshape(int width, int height)
+{
+ GLfloat ar = (GLfloat) width / (GLfloat) height;
+
+ glViewport(0, 0, (GLint) width, (GLint) height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-ar, ar, -1, 1, 5.0, 60.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -10.0);
+}
+
+
+static void
+init(void)
+{
+ glClearColor(0.4, 0.4, 0.4, 0.0);
+}
+
+
+static void
+special_key(int special)
+{
+ switch (special) {
+ case EGLUT_KEY_LEFT:
+ view_roty += 5.0;
+ break;
+ case EGLUT_KEY_RIGHT:
+ view_roty -= 5.0;
+ break;
+ case EGLUT_KEY_UP:
+ view_rotx += 5.0;
+ break;
+ case EGLUT_KEY_DOWN:
+ view_rotx -= 5.0;
+ break;
+ default:
+ break;
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ eglutInitWindowSize(300, 300);
+ eglutInitAPIMask(EGLUT_OPENGL_BIT);
+ eglutInit(argc, argv);
+
+ eglutCreateWindow("egltri");
+
+ eglutReshapeFunc(reshape);
+ eglutDisplayFunc(draw);
+ eglutSpecialFunc(special_key);
+
+ init();
+
+ eglutMainLoop();
+
+ return 0;
+}
--- /dev/null
+clear
+tri
--- /dev/null
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}/../eglut
+ ${EGL_INCLUDE_DIRS}
+ ${GLESV1_INCLUDE_DIRS}
+)
+
+set (api gles1)
+
+set (targets
+ clear
+ tri
+)
+
+foreach (target ${targets})
+ add_executable (${api}_${target} ${target}.c)
+ set_target_properties (${api}_${target} PROPERTIES OUTPUT_NAME ${target})
+ target_link_libraries (${api}_${target} eglut ${GLESV1_LIBRARIES})
+endforeach (target)
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+/*
+ * This demo tests eglGetProcAddress and glClear.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <EGL/egl.h>
+#include <GLES/gl.h>
+
+#include "eglut.h"
+
+typedef void (GL_APIENTRY *type_ClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+typedef void (GL_APIENTRY *type_Clear)(GLbitfield mask);
+
+static type_ClearColor fn_ClearColor;
+static type_Clear fn_Clear;
+
+static void
+draw(void)
+{
+ fn_Clear(GL_COLOR_BUFFER_BIT);
+}
+
+static void *
+get_proc(const char *name)
+{
+ void *proc;
+
+ proc = (void *) eglGetProcAddress(name);
+ if (!proc) {
+ /*
+ * note that eglGetProcAddress is not required to support non-extension
+ * functions
+ */
+ printf("failed to find %s (not necessarily a bug)\n", name);
+ exit(1);
+ }
+
+ return proc;
+}
+
+static void
+init(void)
+{
+ fn_ClearColor = (type_ClearColor) get_proc("glClearColor");
+ fn_Clear = (type_Clear) get_proc("glClear");
+
+ fn_ClearColor(1.0, 0.4, 0.4, 0.0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ eglutInitWindowSize(300, 300);
+ eglutInitAPIMask(EGLUT_OPENGL_ES1_BIT);
+ eglutInit(argc, argv);
+
+ eglutCreateWindow("clear");
+
+ eglutDisplayFunc(draw);
+
+ init();
+
+ eglutMainLoop();
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (C) 2008 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Draw a triangle with X/EGL and OpenGL ES 1.x
+ * Brian Paul
+ * 5 June 2008
+ */
+
+#define USE_FIXED_POINT 0
+
+
+#include <assert.h>
+#include <math.h>
+#include <stdio.h>
+#include <GLES/gl.h> /* use OpenGL ES 1.x */
+#include <GLES/glext.h>
+#include <EGL/egl.h>
+
+#include "eglut.h"
+
+
+#define FLOAT_TO_FIXED(X) ((X) * 65535.0)
+
+
+
+static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0;
+
+
+static void
+draw(void)
+{
+#if USE_FIXED_POINT
+ static const GLfixed verts[3][2] = {
+ { -65536, -65536 },
+ { 65536, -65536 },
+ { 0, 65536 }
+ };
+ static const GLfixed colors[3][4] = {
+ { 65536, 0, 0, 65536 },
+ { 0, 65536, 0 , 65536},
+ { 0, 0, 65536 , 65536}
+ };
+#else
+ static const GLfloat verts[3][2] = {
+ { -1, -1 },
+ { 1, -1 },
+ { 0, 1 }
+ };
+ static const GLfloat colors[3][4] = {
+ { 1, 0, 0, 1 },
+ { 0, 1, 0, 1 },
+ { 0, 0, 1, 1 }
+ };
+#endif
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glPushMatrix();
+ glRotatef(view_rotx, 1, 0, 0);
+ glRotatef(view_roty, 0, 1, 0);
+ glRotatef(view_rotz, 0, 0, 1);
+
+ {
+#if USE_FIXED_POINT
+ glVertexPointer(2, GL_FIXED, 0, verts);
+ glColorPointer(4, GL_FIXED, 0, colors);
+#else
+ glVertexPointer(2, GL_FLOAT, 0, verts);
+ glColorPointer(4, GL_FLOAT, 0, colors);
+#endif
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+
+ /* draw triangle */
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+
+ /* draw some points */
+ glPointSizex(FLOAT_TO_FIXED(15.5));
+ glDrawArrays(GL_POINTS, 0, 3);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ }
+
+ if (0) {
+ /* test code */
+ GLfixed size;
+ glGetFixedv(GL_POINT_SIZE, &size);
+ printf("GL_POINT_SIZE = 0x%x %f\n", size, size / 65536.0);
+ }
+
+ glPopMatrix();
+}
+
+
+/* new window size or exposure */
+static void
+reshape(int width, int height)
+{
+ GLfloat ar = (GLfloat) width / (GLfloat) height;
+
+ glViewport(0, 0, (GLint) width, (GLint) height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+#ifdef GL_VERSION_ES_CM_1_0
+ glFrustumf(-ar, ar, -1, 1, 5.0, 60.0);
+#else
+ glFrustum(-ar, ar, -1, 1, 5.0, 60.0);
+#endif
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -10.0);
+}
+
+
+static void
+test_query_matrix(void)
+{
+ PFNGLQUERYMATRIXXOESPROC procQueryMatrixx;
+ typedef void (*voidproc)();
+ GLfixed mantissa[16];
+ GLint exponent[16];
+ GLbitfield rv;
+ int i;
+
+ procQueryMatrixx = (PFNGLQUERYMATRIXXOESPROC) eglGetProcAddress("glQueryMatrixxOES");
+ assert(procQueryMatrixx);
+ /* Actually try out this one */
+ rv = (*procQueryMatrixx)(mantissa, exponent);
+ for (i = 0; i < 16; i++) {
+ if (rv & (1<<i)) {
+ printf("matrix[%d] invalid\n", i);
+ }
+ else {
+ printf("matrix[%d] = %f * 2^(%d)\n", i, mantissa[i]/65536.0, exponent[i]);
+ }
+ }
+ assert(!eglGetProcAddress("glFoo"));
+}
+
+
+static void
+init(void)
+{
+ glClearColor(0.4, 0.4, 0.4, 0.0);
+
+ if (0)
+ test_query_matrix();
+}
+
+static void
+special_key(int special)
+{
+ switch (special) {
+ case EGLUT_KEY_LEFT:
+ view_roty += 5.0;
+ break;
+ case EGLUT_KEY_RIGHT:
+ view_roty -= 5.0;
+ break;
+ case EGLUT_KEY_UP:
+ view_rotx += 5.0;
+ break;
+ case EGLUT_KEY_DOWN:
+ view_rotx -= 5.0;
+ break;
+ default:
+ break;
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ eglutInitWindowSize(300, 300);
+ eglutInitAPIMask(EGLUT_OPENGL_ES1_BIT);
+ eglutInit(argc, argv);
+
+ eglutCreateWindow("tri");
+
+ eglutReshapeFunc(reshape);
+ eglutDisplayFunc(draw);
+ eglutSpecialFunc(special_key);
+
+ init();
+
+ eglutMainLoop();
+
+ return 0;
+}
--- /dev/null
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}/../eglut
+ ${EGL_INCLUDE_DIRS}
+ ${GLESV2_INCLUDE_DIRS}
+)
+
+set (api gles2)
+
+set (targets
+ tri
+)
+
+if (X11_FOUND)
+ foreach (target ${targets})
+ add_executable (${api}_${target} ${target}.c)
+ set_target_properties (${api}_${target} PROPERTIES OUTPUT_NAME ${target})
+ target_link_libraries (${api}_${target} ${EGL_LIBRARIES} ${GLESV2_LIBRARIES})
+ endforeach (target)
+endif ()
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ **************************************************************************/
+
+/*
+ * Draw a triangle with X/EGL and OpenGL ES 2.x
+ */
+
+#define USE_FULL_GL 0
+
+
+
+#include <assert.h>
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#if USE_FULL_GL
+#include <GL/gl.h> /* use full OpenGL */
+#else
+#include <GLES2/gl2.h> /* use OpenGL ES 2.x */
+#endif
+#include <EGL/egl.h>
+
+
+#define FLOAT_TO_FIXED(X) ((X) * 65535.0)
+
+
+
+static GLfloat view_rotx = 0.0, view_roty = 0.0;
+
+static GLint u_matrix = -1;
+static GLint attr_pos = 0, attr_color = 1;
+
+
+static void
+make_z_rot_matrix(GLfloat angle, GLfloat *m)
+{
+ float c = cos(angle * M_PI / 180.0);
+ float s = sin(angle * M_PI / 180.0);
+ int i;
+ for (i = 0; i < 16; i++)
+ m[i] = 0.0;
+ m[0] = m[5] = m[10] = m[15] = 1.0;
+
+ m[0] = c;
+ m[1] = s;
+ m[4] = -s;
+ m[5] = c;
+}
+
+static void
+make_scale_matrix(GLfloat xs, GLfloat ys, GLfloat zs, GLfloat *m)
+{
+ int i;
+ for (i = 0; i < 16; i++)
+ m[i] = 0.0;
+ m[0] = xs;
+ m[5] = ys;
+ m[10] = zs;
+ m[15] = 1.0;
+}
+
+
+static void
+mul_matrix(GLfloat *prod, const GLfloat *a, const GLfloat *b)
+{
+#define A(row,col) a[(col<<2)+row]
+#define B(row,col) b[(col<<2)+row]
+#define P(row,col) p[(col<<2)+row]
+ GLfloat p[16];
+ GLint i;
+ for (i = 0; i < 4; i++) {
+ const GLfloat ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3);
+ P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0);
+ P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1);
+ P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2);
+ P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3);
+ }
+ memcpy(prod, p, sizeof(p));
+#undef A
+#undef B
+#undef PROD
+}
+
+
+static void
+draw(void)
+{
+ static const GLfloat verts[3][2] = {
+ { -1, -1 },
+ { 1, -1 },
+ { 0, 1 }
+ };
+ static const GLfloat colors[3][3] = {
+ { 1, 0, 0 },
+ { 0, 1, 0 },
+ { 0, 0, 1 }
+ };
+ GLfloat mat[16], rot[16], scale[16];
+
+ /* Set modelview/projection matrix */
+ make_z_rot_matrix(view_rotx, rot);
+ make_scale_matrix(0.5, 0.5, 0.5, scale);
+ mul_matrix(mat, rot, scale);
+ glUniformMatrix4fv(u_matrix, 1, GL_FALSE, mat);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ {
+ glVertexAttribPointer(attr_pos, 2, GL_FLOAT, GL_FALSE, 0, verts);
+ glVertexAttribPointer(attr_color, 3, GL_FLOAT, GL_FALSE, 0, colors);
+ glEnableVertexAttribArray(attr_pos);
+ glEnableVertexAttribArray(attr_color);
+
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+
+ glDisableVertexAttribArray(attr_pos);
+ glDisableVertexAttribArray(attr_color);
+ }
+}
+
+
+/* new window size or exposure */
+static void
+reshape(int width, int height)
+{
+ glViewport(0, 0, (GLint) width, (GLint) height);
+}
+
+
+static void
+create_shaders(void)
+{
+ static const char *fragShaderText =
+ "varying vec4 v_color;\n"
+ "void main() {\n"
+ " gl_FragColor = v_color;\n"
+ "}\n";
+ static const char *vertShaderText =
+ "uniform mat4 modelviewProjection;\n"
+ "attribute vec4 pos;\n"
+ "attribute vec4 color;\n"
+ "varying vec4 v_color;\n"
+ "void main() {\n"
+ " gl_Position = modelviewProjection * pos;\n"
+ " v_color = color;\n"
+ "}\n";
+
+ GLuint fragShader, vertShader, program;
+ GLint stat;
+
+ fragShader = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(fragShader, 1, (const char **) &fragShaderText, NULL);
+ glCompileShader(fragShader);
+ glGetShaderiv(fragShader, GL_COMPILE_STATUS, &stat);
+ if (!stat) {
+ printf("Error: fragment shader did not compile!\n");
+ exit(1);
+ }
+
+ vertShader = glCreateShader(GL_VERTEX_SHADER);
+ glShaderSource(vertShader, 1, (const char **) &vertShaderText, NULL);
+ glCompileShader(vertShader);
+ glGetShaderiv(vertShader, GL_COMPILE_STATUS, &stat);
+ if (!stat) {
+ printf("Error: vertex shader did not compile!\n");
+ exit(1);
+ }
+
+ program = glCreateProgram();
+ glAttachShader(program, fragShader);
+ glAttachShader(program, vertShader);
+ glLinkProgram(program);
+
+ glGetProgramiv(program, GL_LINK_STATUS, &stat);
+ if (!stat) {
+ char log[1000];
+ GLsizei len;
+ glGetProgramInfoLog(program, 1000, &len, log);
+ printf("Error: linking:\n%s\n", log);
+ exit(1);
+ }
+
+ glUseProgram(program);
+
+ if (1) {
+ /* test setting attrib locations */
+ glBindAttribLocation(program, attr_pos, "pos");
+ glBindAttribLocation(program, attr_color, "color");
+ glLinkProgram(program); /* needed to put attribs into effect */
+ }
+ else {
+ /* test automatic attrib locations */
+ attr_pos = glGetAttribLocation(program, "pos");
+ attr_color = glGetAttribLocation(program, "color");
+ }
+
+ u_matrix = glGetUniformLocation(program, "modelviewProjection");
+ printf("Uniform modelviewProjection at %d\n", u_matrix);
+ printf("Attrib pos at %d\n", attr_pos);
+ printf("Attrib color at %d\n", attr_color);
+}
+
+
+static void
+init(void)
+{
+ typedef void (*proc)();
+
+#if 1 /* test code */
+ proc p = eglGetProcAddress("glMapBufferOES");
+ assert(p);
+#endif
+
+ glClearColor(0.4, 0.4, 0.4, 0.0);
+
+ create_shaders();
+}
+
+
+/*
+ * Create an RGB, double-buffered X window.
+ * Return the window and context handles.
+ */
+static void
+make_x_window(Display *x_dpy, EGLDisplay egl_dpy,
+ const char *name,
+ int x, int y, int width, int height,
+ Window *winRet,
+ EGLContext *ctxRet,
+ EGLSurface *surfRet)
+{
+ static const EGLint attribs[] = {
+ EGL_RED_SIZE, 1,
+ EGL_GREEN_SIZE, 1,
+ EGL_BLUE_SIZE, 1,
+ EGL_DEPTH_SIZE, 1,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_NONE
+ };
+#if USE_FULL_GL
+ static const EGLint ctx_attribs[] = {
+ EGL_NONE
+ };
+#else
+ static const EGLint ctx_attribs[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+#endif
+
+ int scrnum;
+ XSetWindowAttributes attr;
+ unsigned long mask;
+ Window root;
+ Window win;
+ XVisualInfo *visInfo, visTemplate;
+ int num_visuals;
+ EGLContext ctx;
+ EGLConfig config;
+ EGLint num_configs;
+ EGLint vid;
+
+ scrnum = DefaultScreen( x_dpy );
+ root = RootWindow( x_dpy, scrnum );
+
+ if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) {
+ printf("Error: couldn't get an EGL visual config\n");
+ exit(1);
+ }
+
+ assert(config);
+ assert(num_configs > 0);
+
+ if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
+ printf("Error: eglGetConfigAttrib() failed\n");
+ exit(1);
+ }
+
+ /* The X window visual must match the EGL config */
+ visTemplate.visualid = vid;
+ visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals);
+ if (!visInfo) {
+ printf("Error: couldn't get X visual\n");
+ exit(1);
+ }
+
+ /* window attributes */
+ attr.background_pixel = 0;
+ attr.border_pixel = 0;
+ attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone);
+ attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+ win = XCreateWindow( x_dpy, root, 0, 0, width, height,
+ 0, visInfo->depth, InputOutput,
+ visInfo->visual, mask, &attr );
+
+ /* set hints and properties */
+ {
+ XSizeHints sizehints;
+ sizehints.x = x;
+ sizehints.y = y;
+ sizehints.width = width;
+ sizehints.height = height;
+ sizehints.flags = USSize | USPosition;
+ XSetNormalHints(x_dpy, win, &sizehints);
+ XSetStandardProperties(x_dpy, win, name, name,
+ None, (char **)NULL, 0, &sizehints);
+ }
+
+#if USE_FULL_GL /* XXX fix this when eglBindAPI() works */
+ eglBindAPI(EGL_OPENGL_API);
+#else
+ eglBindAPI(EGL_OPENGL_ES_API);
+#endif
+
+ ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, ctx_attribs );
+ if (!ctx) {
+ printf("Error: eglCreateContext failed\n");
+ exit(1);
+ }
+
+#if !USE_FULL_GL
+ /* test eglQueryContext() */
+ {
+ EGLint val;
+ eglQueryContext(egl_dpy, ctx, EGL_CONTEXT_CLIENT_VERSION, &val);
+ assert(val == 2);
+ }
+#endif
+
+ *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL);
+ if (!*surfRet) {
+ printf("Error: eglCreateWindowSurface failed\n");
+ exit(1);
+ }
+
+ /* sanity checks */
+ {
+ EGLint val;
+ eglQuerySurface(egl_dpy, *surfRet, EGL_WIDTH, &val);
+ assert(val == width);
+ eglQuerySurface(egl_dpy, *surfRet, EGL_HEIGHT, &val);
+ assert(val == height);
+ assert(eglGetConfigAttrib(egl_dpy, config, EGL_SURFACE_TYPE, &val));
+ assert(val & EGL_WINDOW_BIT);
+ }
+
+ XFree(visInfo);
+
+ *winRet = win;
+ *ctxRet = ctx;
+}
+
+
+static void
+event_loop(Display *dpy, Window win,
+ EGLDisplay egl_dpy, EGLSurface egl_surf)
+{
+ while (1) {
+ int redraw = 0;
+ XEvent event;
+
+ XNextEvent(dpy, &event);
+
+ switch (event.type) {
+ case Expose:
+ redraw = 1;
+ break;
+ case ConfigureNotify:
+ reshape(event.xconfigure.width, event.xconfigure.height);
+ break;
+ case KeyPress:
+ {
+ char buffer[10];
+ int r, code;
+ code = XLookupKeysym(&event.xkey, 0);
+ if (code == XK_Left) {
+ view_roty += 5.0;
+ }
+ else if (code == XK_Right) {
+ view_roty -= 5.0;
+ }
+ else if (code == XK_Up) {
+ view_rotx += 5.0;
+ }
+ else if (code == XK_Down) {
+ view_rotx -= 5.0;
+ }
+ else {
+ r = XLookupString(&event.xkey, buffer, sizeof(buffer),
+ NULL, NULL);
+ if (buffer[0] == 27) {
+ /* escape */
+ return;
+ }
+ }
+ }
+ redraw = 1;
+ break;
+ default:
+ ; /*no-op*/
+ }
+
+ if (redraw) {
+ draw();
+ eglSwapBuffers(egl_dpy, egl_surf);
+ }
+ }
+}
+
+
+static void
+usage(void)
+{
+ printf("Usage:\n");
+ printf(" -display <displayname> set the display to run on\n");
+ printf(" -info display OpenGL renderer info\n");
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ const int winWidth = 300, winHeight = 300;
+ Display *x_dpy;
+ Window win;
+ EGLSurface egl_surf;
+ EGLContext egl_ctx;
+ EGLDisplay egl_dpy;
+ char *dpyName = NULL;
+ GLboolean printInfo = GL_FALSE;
+ EGLint egl_major, egl_minor;
+ int i;
+ const char *s;
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-display") == 0) {
+ dpyName = argv[i+1];
+ i++;
+ }
+ else if (strcmp(argv[i], "-info") == 0) {
+ printInfo = GL_TRUE;
+ }
+ else {
+ usage();
+ return -1;
+ }
+ }
+
+ x_dpy = XOpenDisplay(dpyName);
+ if (!x_dpy) {
+ printf("Error: couldn't open display %s\n",
+ dpyName ? dpyName : getenv("DISPLAY"));
+ return -1;
+ }
+
+ egl_dpy = eglGetDisplay(x_dpy);
+ if (!egl_dpy) {
+ printf("Error: eglGetDisplay() failed\n");
+ return -1;
+ }
+
+ if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) {
+ printf("Error: eglInitialize() failed\n");
+ return -1;
+ }
+
+ s = eglQueryString(egl_dpy, EGL_VERSION);
+ printf("EGL_VERSION = %s\n", s);
+
+ s = eglQueryString(egl_dpy, EGL_VENDOR);
+ printf("EGL_VENDOR = %s\n", s);
+
+ s = eglQueryString(egl_dpy, EGL_EXTENSIONS);
+ printf("EGL_EXTENSIONS = %s\n", s);
+
+ s = eglQueryString(egl_dpy, EGL_CLIENT_APIS);
+ printf("EGL_CLIENT_APIS = %s\n", s);
+
+ make_x_window(x_dpy, egl_dpy,
+ "OpenGL ES 2.x tri", 0, 0, winWidth, winHeight,
+ &win, &egl_ctx, &egl_surf);
+
+ XMapWindow(x_dpy, win);
+ if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) {
+ printf("Error: eglMakeCurrent() failed\n");
+ return -1;
+ }
+
+ if (printInfo) {
+ printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
+ printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
+ printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
+ printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
+ }
+
+ init();
+
+ /* Set initial projection/viewing transformation.
+ * We can't be sure we'll get a ConfigureNotify event when the window
+ * first appears.
+ */
+ reshape(winWidth, winHeight);
+
+ event_loop(x_dpy, win, egl_dpy, egl_surf);
+
+ eglDestroyContext(egl_dpy, egl_ctx);
+ eglDestroySurface(egl_dpy, egl_surf);
+ eglTerminate(egl_dpy);
+
+
+ XDestroyWindow(x_dpy, win);
+ XCloseDisplay(x_dpy);
+
+ return 0;
+}