diff options
Diffstat (limited to 'progs/egl')
67 files changed, 10930 insertions, 580 deletions
diff --git a/progs/egl/Makefile b/progs/egl/Makefile deleted file mode 100644 index c003cf3cc55..00000000000 --- a/progs/egl/Makefile +++ /dev/null @@ -1,70 +0,0 @@ -# progs/egl/Makefile - -TOP = ../.. -include $(TOP)/configs/current - - -INCLUDE_DIRS = -I$(TOP)/include - -HEADERS = $(TOP)/include/GLES/egl.h -LIB_DEP = $(TOP)/$(LIB_DIR)/libEGL.so - -LIBS = -L$(TOP)/$(LIB_DIR) -lEGL -lGL - -PROGRAMS = \ - demo1 \ - demo2 \ - demo3 \ - egltri \ - eglinfo \ - eglgears \ - eglscreen \ - peglgears \ - xeglgears \ - xeglthreads \ - xegl_tri - - -.c.o: - $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ - - - -default: $(PROGRAMS) - -demo1: demo1.o $(HEADERS) $(LIB_DEP) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB) - -demo2: demo2.o $(HEADERS) $(LIB_DEP) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB) - -demo3: demo3.o $(HEADERS) $(LIB_DEP) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB) - -egltri: egltri.o $(HEADERS) $(LIB_DEP) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB) - -eglinfo: eglinfo.o $(HEADERS) $(LIB_DEP) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) - -eglgears: eglgears.o $(HEADERS) $(LIB_DEP) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB) -lm - -eglscreen: eglscreen.o $(HEADERS) $(LIB_DEP) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB) - -peglgears: peglgears.o $(HEADERS) $(LIB_DEP) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB) -lm - -xeglgears: xeglgears.o $(HEADERS) $(LIB_DEP) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lX11 -lm - -xeglthreads: xeglthreads.o $(HEADERS) $(LIB_DEP) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lX11 -lm - -xegl_tri: xegl_tri.o $(HEADERS) $(LIB_DEP) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lX11 - -clean: - -rm -f *.o *~ - -rm -f $(PROGRAMS) diff --git a/progs/egl/egltri.c b/progs/egl/egltri.c deleted file mode 100644 index 006e06eb03e..00000000000 --- a/progs/egl/egltri.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * Copyright (C) 2008 Brian Paul All Rights Reserved. - * Copyright (C) 2008 Jakob Bornecrantz 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. - */ - -/* - * This program is based on eglgears and xegl_tri. - * Remixed by Jakob Bornecrantz - * - * No command line options. - * Program runs for 5 seconds then exits, outputing framerate to console - */ - -#define EGL_EGLEXT_PROTOTYPES - -#include <assert.h> -#include <math.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <GL/gl.h> -#include <EGL/egl.h> -#include <EGL/eglext.h> - -#define MAX_CONFIGS 10 -#define MAX_MODES 100 - - -/* XXX this probably isn't very portable */ - -#include <sys/time.h> -#include <unistd.h> - -/* return current time (in seconds) */ -static double -current_time(void) -{ - struct timeval tv; -#ifdef __VMS - (void) gettimeofday(&tv, NULL ); -#else - struct timezone tz; - (void) gettimeofday(&tv, &tz); -#endif - return (double) tv.tv_sec + tv.tv_usec / 1000000.0; -} - - -static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0; - -static void draw() -{ - 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(); -} - -static void init() -{ - glClearColor(0.4, 0.4, 0.4, 0.0); -} - -/* 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 run(EGLDisplay dpy, EGLSurface surf, int ttr) -{ - double st = current_time(); - double ct = st; - int frames = 0; - GLfloat seconds, fps; - - while (ct - st < ttr) - { - ct = current_time(); - - draw(); - - eglSwapBuffers(dpy, surf); - - frames++; - } - - seconds = ct - st; - fps = frames / seconds; - printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds, fps); -} - -int main(int argc, char *argv[]) -{ - int maj, min; - EGLContext ctx; - EGLSurface screen_surf; - EGLConfig configs[MAX_CONFIGS]; - EGLint numConfigs, i; - EGLBoolean b; - EGLDisplay d; - EGLint screenAttribs[10]; - EGLModeMESA mode[MAX_MODES]; - EGLScreenMESA screen; - EGLint count, chosenMode = 0; - GLboolean printInfo = GL_FALSE; - EGLint width = 0, height = 0; - - /* parse cmd line args */ - for (i = 1; i < argc; i++) - { - if (strcmp(argv[i], "-info") == 0) - { - printInfo = GL_TRUE; - } - else - printf("Warning: unknown parameter: %s\n", argv[i]); - } - - /* DBR : Create EGL context/surface etc */ - d = eglGetDisplay(EGL_DEFAULT_DISPLAY); - assert(d); - - if (!eglInitialize(d, &maj, &min)) { - printf("egltri: eglInitialize failed\n"); - exit(1); - } - - printf("egltri: EGL version = %d.%d\n", maj, min); - printf("egltri: EGL_VENDOR = %s\n", eglQueryString(d, EGL_VENDOR)); - - /* XXX use ChooseConfig */ - eglGetConfigs(d, configs, MAX_CONFIGS, &numConfigs); - eglGetScreensMESA(d, &screen, 1, &count); - - if (!eglGetModesMESA(d, screen, mode, MAX_MODES, &count) || count == 0) { - printf("egltri: eglGetModesMESA failed!\n"); - return 0; - } - - /* Print list of modes, and find the one to use */ - printf("egltri: Found %d modes:\n", count); - for (i = 0; i < count; i++) { - EGLint w, h; - eglGetModeAttribMESA(d, mode[i], EGL_WIDTH, &w); - eglGetModeAttribMESA(d, mode[i], EGL_HEIGHT, &h); - printf("%3d: %d x %d\n", i, w, h); - if (w > width && h > height) { - width = w; - height = h; - chosenMode = i; - } - } - printf("egltri: Using screen mode/size %d: %d x %d\n", chosenMode, width, height); - - eglBindAPI(EGL_OPENGL_API); - ctx = eglCreateContext(d, configs[0], EGL_NO_CONTEXT, NULL); - if (ctx == EGL_NO_CONTEXT) { - printf("egltri: failed to create context\n"); - return 0; - } - - /* build up screenAttribs array */ - i = 0; - screenAttribs[i++] = EGL_WIDTH; - screenAttribs[i++] = width; - screenAttribs[i++] = EGL_HEIGHT; - screenAttribs[i++] = height; - screenAttribs[i++] = EGL_NONE; - - screen_surf = eglCreateScreenSurfaceMESA(d, configs[0], screenAttribs); - if (screen_surf == EGL_NO_SURFACE) { - printf("egltri: failed to create screen surface\n"); - return 0; - } - - b = eglShowScreenSurfaceMESA(d, screen, screen_surf, mode[chosenMode]); - if (!b) { - printf("egltri: show surface failed\n"); - return 0; - } - - b = eglMakeCurrent(d, screen_surf, screen_surf, ctx); - if (!b) { - printf("egltri: make current failed\n"); - return 0; - } - - 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(); - reshape(width, height); - - glDrawBuffer( GL_BACK ); - - run(d, screen_surf, 5.0); - - eglDestroySurface(d, screen_surf); - eglDestroyContext(d, ctx); - eglTerminate(d); - - return 0; -} diff --git a/progs/egl/eglut/Makefile b/progs/egl/eglut/Makefile new file mode 100644 index 00000000000..364f5b0be3d --- /dev/null +++ b/progs/egl/eglut/Makefile @@ -0,0 +1,39 @@ +# progs/egl/eglut + +TOP = ../../.. +include $(TOP)/configs/current + +INCLUDES = \ + -I$(TOP)/include \ + $(X11_CFLAGS) + +SOURCES = \ + eglut.c \ + eglut_screen.c \ + eglut_x11.c + +EGLUT_X11_OBJECTS = eglut.o eglut_x11.o +EGLUT_SCREEN_OBJECTS = eglut.o eglut_screen.o + +default: depend libeglut-x11.a libeglut-screen.a + +libeglut-x11.a: $(EGLUT_X11_OBJECTS) + $(MKLIB) -o eglut-x11 -static $(EGLUT_X11_OBJECTS) + +libeglut-screen.a: $(EGLUT_SCREEN_OBJECTS) + $(MKLIB) -o eglut-screen -static $(EGLUT_SCREEN_OBJECTS) + +.c.o: + $(CC) -c -o $@ $< $(INCLUDES) $(DEFINES) $(CFLAGS) + +depend: $(SOURCES) + @rm -f depend + @touch depend + @$(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(SOURCES) \ + > /dev/null 2>/dev/null + +clean: + rm -f *.o *.a + rm -f depend depend.bak + +sinclude depend diff --git a/progs/egl/eglut/eglut.c b/progs/egl/eglut/eglut.c new file mode 100644 index 00000000000..b9b5e6e5a8c --- /dev/null +++ b/progs/egl/eglut/eglut.c @@ -0,0 +1,346 @@ +#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 | EGLUT_OPENGL_ES2_BIT)) + renderable_type |= EGL_OPENGL_ES_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; +} diff --git a/progs/egl/eglut/eglut.h b/progs/egl/eglut/eglut.h new file mode 100644 index 00000000000..07df4ba9f75 --- /dev/null +++ b/progs/egl/eglut/eglut.h @@ -0,0 +1,68 @@ +#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 */ diff --git a/progs/egl/eglut/eglut_screen.c b/progs/egl/eglut/eglut_screen.c new file mode 100644 index 00000000000..50549e4bcf8 --- /dev/null +++ b/progs/egl/eglut/eglut_screen.c @@ -0,0 +1,154 @@ +#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); + + 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++; + } + } +} diff --git a/progs/egl/eglut/eglut_x11.c b/progs/egl/eglut/eglut_x11.c new file mode 100644 index 00000000000..f3b2280374b --- /dev/null +++ b/progs/egl/eglut/eglut_x11.c @@ -0,0 +1,220 @@ +#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)) { + if (_eglut->idle_cb) + _eglut->idle_cb(); + return; + } + + 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); + } + } +} diff --git a/progs/egl/eglut/eglutint.h b/progs/egl/eglut/eglutint.h new file mode 100644 index 00000000000..54d329f3282 --- /dev/null +++ b/progs/egl/eglut/eglutint.h @@ -0,0 +1,78 @@ +#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_ */ diff --git a/progs/egl/.gitignore b/progs/egl/opengl/.gitignore index 7a13d4686a0..49c3a511f3c 100644 --- a/progs/egl/.gitignore +++ b/progs/egl/opengl/.gitignore @@ -1,12 +1,13 @@ demo1 demo2 demo3 -eglgears +eglgears_x11 +eglgears_screen eglinfo eglscreen -egltri +egltri_x11 +egltri_screen peglgears xeglbindtex xeglgears xeglthreads -xegl_tri diff --git a/progs/egl/opengl/Makefile b/progs/egl/opengl/Makefile new file mode 100644 index 00000000000..79cd5fc6533 --- /dev/null +++ b/progs/egl/opengl/Makefile @@ -0,0 +1,79 @@ +# progs/egl/Makefile + +TOP = ../../.. +include $(TOP)/configs/current + + +INCLUDE_DIRS = -I$(TOP)/include $(X11_CFLAGS) + +HEADERS = $(TOP)/include/GLES/egl.h +LIB_DEP = $(TOP)/$(LIB_DIR)/libEGL.so + +LIBS = -L$(TOP)/$(LIB_DIR) -lEGL -lGL -lm + +EGLUT_DIR = $(TOP)/progs/egl/eglut + +EGLUT_DEMOS = \ + eglgears \ + egltri + +EGLUT_X11_DEMOS := $(addsuffix _x11,$(EGLUT_DEMOS)) +EGLUT_SCREEN_DEMOS := $(addsuffix _screen,$(EGLUT_DEMOS)) + +PROGRAMS = \ + demo1 \ + demo2 \ + demo3 \ + eglinfo \ + eglscreen \ + peglgears \ + xeglgears \ + xeglthreads + + +.c.o: + $(CC) -c $(INCLUDE_DIRS) -I$(EGLUT_DIR) $(CFLAGS) $< -o $@ + + + +default: $(PROGRAMS) $(EGLUT_X11_DEMOS) $(EGLUT_SCREEN_DEMOS) + +demo1: demo1.o $(HEADERS) $(LIB_DEP) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB) + +demo2: demo2.o $(HEADERS) $(LIB_DEP) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB) + +demo3: demo3.o $(HEADERS) $(LIB_DEP) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB) + +eglinfo: eglinfo.o $(HEADERS) $(LIB_DEP) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) + +eglscreen: eglscreen.o $(HEADERS) $(LIB_DEP) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB) + +peglgears: peglgears.o $(HEADERS) $(LIB_DEP) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB) -lm + +xeglgears: xeglgears.o $(HEADERS) $(LIB_DEP) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lm $(X11_LIBS) + +xeglthreads: xeglthreads.o $(HEADERS) $(LIB_DEP) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lpthread -lm $(X11_LIBS) + +# define the rules for EGLUT demos +define eglut-demo-rule +$(1)_x11 $(1)_screen: $(1)_%: $(1).o $(EGLUT_DIR)/libeglut-%.a $(LIB_DEP) +endef +$(foreach demo, $(EGLUT_DEMOS), $(eval $(call eglut-demo-rule,$(demo)))) + +# build EGLUT demos +$(EGLUT_X11_DEMOS): + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -L$(EGLUT_DIR) -leglut-$* $(LIBS) $(X11_LIBS) +$(EGLUT_SCREEN_DEMOS): + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -L$(EGLUT_DIR) -leglut-$* $(LIBS) + +clean: + -rm -f *.o *~ + -rm -f $(PROGRAMS) $(EGLUT_X11_DEMOS) $(EGLUT_SCREEN_DEMOS) diff --git a/progs/egl/demo1.c b/progs/egl/opengl/demo1.c index d892734ee55..d892734ee55 100644 --- a/progs/egl/demo1.c +++ b/progs/egl/opengl/demo1.c diff --git a/progs/egl/demo2.c b/progs/egl/opengl/demo2.c index b9e92f62ac2..b9e92f62ac2 100644 --- a/progs/egl/demo2.c +++ b/progs/egl/opengl/demo2.c diff --git a/progs/egl/demo3.c b/progs/egl/opengl/demo3.c index 64b9ee652cd..64b9ee652cd 100644 --- a/progs/egl/demo3.c +++ b/progs/egl/opengl/demo3.c diff --git a/progs/egl/eglgears.c b/progs/egl/opengl/eglgears.c index 63490953aee..28da9c0ac74 100644 --- a/progs/egl/eglgears.c +++ b/progs/egl/opengl/eglgears.c @@ -27,78 +27,16 @@ * Program runs for 5 seconds then exits, outputing framerate to console */ -#define EGL_EGLEXT_PROTOTYPES - -#include <assert.h> #include <math.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> #include <GL/gl.h> #include <EGL/egl.h> -#include <EGL/eglext.h> - -#define MAX_CONFIGS 10 -#define MAX_MODES 100 - -#define BENCHMARK - -#ifdef BENCHMARK - -/* XXX this probably isn't very portable */ - -#include <sys/time.h> -#include <unistd.h> - -/* return current time (in seconds) */ -static double -current_time(void) -{ - struct timeval tv; -#ifdef __VMS - (void) gettimeofday(&tv, NULL ); -#else - struct timezone tz; - (void) gettimeofday(&tv, &tz); -#endif - return (double) tv.tv_sec + tv.tv_usec / 1000000.0; -} - -#else /*BENCHMARK*/ - -/* dummy */ -static double -current_time(void) -{ - /* update this function for other platforms! */ - static double t = 0.0; - static int warn = 1; - if (warn) { - fprintf(stderr, "Warning: current_time() not implemented!!\n"); - warn = 0; - } - return t += 1.0; -} - -#endif /*BENCHMARK*/ - - -#ifndef M_PI -#define M_PI 3.14159265 -#endif +#include "eglut.h" static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0; static GLint gear1, gear2, gear3; static GLfloat angle = 0.0; -#if 0 -static GLfloat eyesep = 5.0; /* Eye separation. */ -static GLfloat fix_point = 40.0; /* Fixation point distance. */ -static GLfloat left, right, asp; /* Stereo frustum params. */ -#endif - - /* * * Draw a gear wheel. You'll probably want to call this function when @@ -270,6 +208,22 @@ draw(void) } +static void +idle(void) +{ + static double t0 = -1.; + double dt, t = eglutGet(EGLUT_ELAPSED_TIME) / 1000.0; + if (t0 < 0.0) + t0 = t; + dt = t - t0; + t0 = t; + + angle += 70.0 * dt; /* 70 degrees per second */ + angle = fmod(angle, 360.0); /* prevents eventual overflow */ + + eglutPostRedisplay(); +} + /* new window size or exposure */ static void reshape(int width, int height) @@ -325,158 +279,23 @@ init(void) glEnable(GL_NORMALIZE); } - - - -static void run_gears(EGLDisplay dpy, EGLSurface surf, int ttr) -{ - double st = current_time(); - double ct = st; - int frames = 0; - GLfloat seconds, fps; - - while (ct - st < ttr) - { - double tt = current_time(); - double dt = tt - ct; - ct = tt; - - /* advance rotation for next frame */ - angle += 70.0 * dt; /* 70 degrees per second */ - if (angle > 3600.0) - angle -= 3600.0; - - draw(); - - eglSwapBuffers(dpy, surf); - - - frames++; - } - - seconds = ct - st; - fps = frames / seconds; - printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds, fps); - -} - - int main(int argc, char *argv[]) { - int maj, min; - EGLContext ctx; - EGLSurface screen_surf; - EGLConfig configs[MAX_CONFIGS]; - EGLint numConfigs, i; - EGLBoolean b; - EGLDisplay d; - EGLint screenAttribs[10]; - EGLModeMESA mode[MAX_MODES]; - EGLScreenMESA screen; - EGLint count; - EGLint chosenMode = 0; - GLboolean printInfo = GL_FALSE; - EGLint width = 0, height = 0; - - /* parse cmd line args */ - for (i = 1; i < argc; i++) - { - if (strcmp(argv[i], "-info") == 0) - { - printInfo = GL_TRUE; - } - else - printf("Warning: unknown parameter: %s\n", argv[i]); - } - - /* DBR : Create EGL context/surface etc */ - d = eglGetDisplay(EGL_DEFAULT_DISPLAY); - assert(d); - - if (!eglInitialize(d, &maj, &min)) { - printf("eglgears: eglInitialize failed\n"); - exit(1); - } - - printf("eglgears: EGL version = %d.%d\n", maj, min); - printf("eglgears: EGL_VENDOR = %s\n", eglQueryString(d, EGL_VENDOR)); - - /* XXX use ChooseConfig */ - eglGetConfigs(d, configs, MAX_CONFIGS, &numConfigs); - eglGetScreensMESA(d, &screen, 1, &count); - - if (!eglGetModesMESA(d, screen, mode, MAX_MODES, &count) || count == 0) { - printf("eglgears: eglGetModesMESA failed!\n"); - return 0; - } - - /* Print list of modes, and find the one to use */ - printf("eglgears: Found %d modes:\n", count); - for (i = 0; i < count; i++) { - EGLint w, h; - eglGetModeAttribMESA(d, mode[i], EGL_WIDTH, &w); - eglGetModeAttribMESA(d, mode[i], EGL_HEIGHT, &h); - printf("%3d: %d x %d\n", i, w, h); - if (w > width && h > height) { - width = w; - height = h; - chosenMode = i; - } - } - printf("eglgears: Using screen mode/size %d: %d x %d\n", chosenMode, width, height); - - eglBindAPI(EGL_OPENGL_API); - ctx = eglCreateContext(d, configs[0], EGL_NO_CONTEXT, NULL); - if (ctx == EGL_NO_CONTEXT) { - printf("eglgears: failed to create context\n"); - return 0; - } - - /* build up screenAttribs array */ - i = 0; - screenAttribs[i++] = EGL_WIDTH; - screenAttribs[i++] = width; - screenAttribs[i++] = EGL_HEIGHT; - screenAttribs[i++] = height; - screenAttribs[i++] = EGL_NONE; - - screen_surf = eglCreateScreenSurfaceMESA(d, configs[0], screenAttribs); - if (screen_surf == EGL_NO_SURFACE) { - printf("eglgears: failed to create screen surface\n"); - return 0; - } - - b = eglShowScreenSurfaceMESA(d, screen, screen_surf, mode[chosenMode]); - if (!b) { - printf("eglgears: show surface failed\n"); - return 0; - } - - b = eglMakeCurrent(d, screen_surf, screen_surf, ctx); - if (!b) { - printf("eglgears: make current failed\n"); - return 0; - } - - 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(); - reshape(width, height); + eglutInitWindowSize(300, 300); + eglutInitAPIMask(EGLUT_OPENGL_BIT); + eglutInit(argc, argv); - glDrawBuffer( GL_BACK ); + eglutCreateWindow("eglgears"); - run_gears(d, screen_surf, 5.0); - - eglDestroySurface(d, screen_surf); - eglDestroyContext(d, ctx); - eglTerminate(d); + eglutIdleFunc(idle); + eglutReshapeFunc(reshape); + eglutDisplayFunc(draw); + + init(); + glDrawBuffer(GL_BACK); - return 0; + eglutMainLoop(); + + return 0; } diff --git a/progs/egl/eglinfo.c b/progs/egl/opengl/eglinfo.c index 961fd9ccc76..961fd9ccc76 100644 --- a/progs/egl/eglinfo.c +++ b/progs/egl/opengl/eglinfo.c diff --git a/progs/egl/eglscreen.c b/progs/egl/opengl/eglscreen.c index 520f76ea036..520f76ea036 100644 --- a/progs/egl/eglscreen.c +++ b/progs/egl/opengl/eglscreen.c diff --git a/progs/egl/opengl/egltri.c b/progs/egl/opengl/egltri.c new file mode 100644 index 00000000000..fb1dde3529c --- /dev/null +++ b/progs/egl/opengl/egltri.c @@ -0,0 +1,141 @@ +/* + * 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; +} diff --git a/progs/egl/peglgears.c b/progs/egl/opengl/peglgears.c index 212d1acf692..212d1acf692 100644 --- a/progs/egl/peglgears.c +++ b/progs/egl/opengl/peglgears.c diff --git a/progs/egl/xeglgears.c b/progs/egl/opengl/xeglgears.c index a6a977d9fff..a6a977d9fff 100644 --- a/progs/egl/xeglgears.c +++ b/progs/egl/opengl/xeglgears.c diff --git a/progs/egl/xeglthreads.c b/progs/egl/opengl/xeglthreads.c index 5787faecb90..5787faecb90 100644 --- a/progs/egl/xeglthreads.c +++ b/progs/egl/opengl/xeglthreads.c diff --git a/progs/egl/opengles1/.gitignore b/progs/egl/opengles1/.gitignore new file mode 100644 index 00000000000..135e3deb35b --- /dev/null +++ b/progs/egl/opengles1/.gitignore @@ -0,0 +1,15 @@ +bindtex +drawtex_x11 +drawtex_screen +es1_info +gears_x11 +gears_screen +msaa +pbuffer +render_tex +texture_from_pixmap +torus_x11 +torus_screen +tri_x11 +tri_screen +two_win diff --git a/progs/egl/opengles1/Makefile b/progs/egl/opengles1/Makefile new file mode 100644 index 00000000000..593145d4bf2 --- /dev/null +++ b/progs/egl/opengles1/Makefile @@ -0,0 +1,99 @@ +# progs/egl/opengles1/Makefile + +TOP = ../../.. +include $(TOP)/configs/current + + +INCLUDE_DIRS = \ + -I$(TOP)/include \ + $(X11_CFLAGS) + +HEADERS = $(TOP)/include/GLES/egl.h + + +ES1_LIB_DEPS = \ + $(TOP)/$(LIB_DIR)/libEGL.so \ + $(TOP)/$(LIB_DIR)/libGLESv1_CM.so + + +ES1_LIBS = \ + -L$(TOP)/$(LIB_DIR) -lEGL \ + -L$(TOP)/$(LIB_DIR) -lGLESv1_CM $(LIBDRM_LIB) $(X11_LIBS) + +EGLUT_DIR = $(TOP)/progs/egl/eglut + +EGLUT_DEMOS = \ + drawtex \ + gears \ + torus \ + tri + +EGLUT_X11_DEMOS := $(addsuffix _x11,$(EGLUT_DEMOS)) +EGLUT_SCREEN_DEMOS := $(addsuffix _screen,$(EGLUT_DEMOS)) + +PROGRAMS = \ + bindtex \ + es1_info \ + msaa \ + pbuffer \ + render_tex \ + texture_from_pixmap \ + two_win + + +.c.o: + $(CC) -c $(INCLUDE_DIRS) -I$(EGLUT_DIR) $(CFLAGS) $< -o $@ + + + +default: $(PROGRAMS) $(EGLUT_X11_DEMOS) $(EGLUT_SCREEN_DEMOS) + + + +bindtex: bindtex.o $(ES1_LIB_DEPS) + $(CC) $(CFLAGS) bindtex.o $(ES1_LIBS) -o $@ + + +es1_info: es1_info.o $(ES1_LIB_DEPS) + $(CC) $(CFLAGS) es1_info.o $(ES1_LIBS) -o $@ + + +msaa: msaa.o $(ES1_LIB_DEPS) + $(CC) $(CFLAGS) msaa.o $(ES1_LIBS) -o $@ + + +pbuffer: pbuffer.o $(ES1_LIB_DEPS) + $(CC) $(CFLAGS) pbuffer.o $(ES1_LIBS) -o $@ + + +render_tex: render_tex.o $(ES1_LIB_DEPS) + $(CC) $(CFLAGS) render_tex.o $(ES1_LIBS) -o $@ + + +texture_from_pixmap: texture_from_pixmap.o $(ES1_LIB_DEPS) + $(CC) $(CFLAGS) texture_from_pixmap.o $(ES1_LIBS) -o $@ + +torus: torus.o $(ES1_LIB_DEPS) + $(CC) $(CFLAGS) torus.o $(ES1_LIBS) -o $@ + + +two_win: two_win.o $(ES1_LIB_DEPS) + $(CC) $(CFLAGS) two_win.o $(ES1_LIBS) -o $@ + + +# define the rules for EGLUT demos +define eglut-demo-rule +$(1)_x11 $(1)_screen: $(1)_%: $(1).o $(EGLUT_DIR)/libeglut-%.a $(ES1_LIB_DEPS) +endef +$(foreach demo, $(EGLUT_DEMOS), $(eval $(call eglut-demo-rule,$(demo)))) + +# build EGLUT demos +$(EGLUT_X11_DEMOS): + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -L$(EGLUT_DIR) -leglut-$* $(ES1_LIBS) $(X11_LIBS) +$(EGLUT_SCREEN_DEMOS): + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -L$(EGLUT_DIR) -leglut-$* $(ES1_LIBS) + + +clean: + -rm -f *.o *~ + -rm -f $(PROGRAMS) $(EGLUT_X11_DEMOS) $(EGLUT_SCREEN_DEMOS) diff --git a/progs/egl/opengles1/bindtex.c b/progs/egl/opengles1/bindtex.c new file mode 100644 index 00000000000..c243b5941b7 --- /dev/null +++ b/progs/egl/opengles1/bindtex.c @@ -0,0 +1,474 @@ +/* + * Simple demo for eglBindTexImage. Based on xegl_tri.c by + * + * 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. + */ + +/* + * The spec says that eglBindTexImage supports only OpenGL ES context, but this + * demo uses OpenGL context. Keep in mind that this is non-standard. + */ + +#include <math.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/keysym.h> +#include <GLES/gl.h> +#include <EGL/egl.h> + +static EGLDisplay dpy; +static EGLContext ctx_win, ctx_pbuf; +static EGLSurface surf_win, surf_pbuf; +static GLuint tex_pbuf; + +static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0; +static GLboolean blend = GL_TRUE; +static GLuint color_flow; + +static void +make_pbuffer(int width, int height) +{ + static const EGLint config_attribs[] = { + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE, + EGL_NONE + }; + EGLint pbuf_attribs[] = { + EGL_WIDTH, width, + EGL_HEIGHT, height, + EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB, + EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, + EGL_NONE + }; + EGLConfig config; + EGLint num_configs; + + if (!eglChooseConfig(dpy, config_attribs, &config, 1, &num_configs) || + !num_configs) { + printf("Error: couldn't get an EGL visual config for pbuffer\n"); + exit(1); + } + + ctx_pbuf = eglCreateContext(dpy, config, EGL_NO_CONTEXT, NULL ); + surf_pbuf = eglCreatePbufferSurface(dpy, config, pbuf_attribs); + if (surf_pbuf == EGL_NO_SURFACE) { + printf("failed to allocate pbuffer\n"); + exit(1); + } +} + +static void +use_pbuffer(void) +{ + static int initialized; + + eglMakeCurrent(dpy, surf_pbuf, surf_pbuf, ctx_pbuf); + if (!initialized) { + EGLint width, height; + GLfloat ar; + + initialized = 1; + + eglQuerySurface(dpy, surf_pbuf, EGL_WIDTH, &width); + eglQuerySurface(dpy, surf_pbuf, EGL_WIDTH, &height); + ar = (GLfloat) width / (GLfloat) height; + + glViewport(0, 0, (GLint) width, (GLint) height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustumf(-ar, ar, -1, 1, 1.0, 10.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + /* y-inverted */ + glScalef(1.0, -1.0, 1.0); + + glTranslatef(0.0, 0.0, -5.0); + + glClearColor(0.2, 0.2, 0.2, 0.0); + + glGenTextures(1, &tex_pbuf); + } +} + +static void +make_window(Display *x_dpy, const char *name, + int x, int y, int width, int height, + Window *winRet) +{ + static const EGLint attribs[] = { + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_DEPTH_SIZE, 8, + EGL_NONE + }; + + int scrnum; + XSetWindowAttributes attr; + unsigned long mask; + Window root; + Window win; + XVisualInfo *visInfo, visTemplate; + int num_visuals; + EGLConfig config; + EGLint num_configs, vid; + + scrnum = DefaultScreen( x_dpy ); + root = RootWindow( x_dpy, scrnum ); + + if (!eglChooseConfig(dpy, attribs, &config, 1, &num_configs) || + !num_configs) { + printf("Error: couldn't get an EGL visual config\n"); + exit(1); + } + + if (!eglGetConfigAttrib(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; + attr.override_redirect = 0; + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect; + + 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); + } + + ctx_win = eglCreateContext(dpy, config, EGL_NO_CONTEXT, NULL ); + if (!ctx_win) { + printf("Error: eglCreateContext failed\n"); + exit(1); + } + + surf_win = eglCreateWindowSurface(dpy, config, win, NULL); + + XFree(visInfo); + + *winRet = win; +} + +static void +use_window(void) +{ + static int initialized; + + eglMakeCurrent(dpy, surf_win, surf_win, ctx_win); + if (!initialized) { + initialized = 1; + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, tex_pbuf); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } +} + +static void +draw_triangle(void) +{ + static const GLfloat verts[3][2] = { + { -3, -3 }, + { 3, -3 }, + { 0, 3 } + }; + GLfloat colors[3][4] = { + { 1, 0, 0, 1 }, + { 0, 1, 0, 1 }, + { 0, 0, 1, 1 } + }; + GLint i; + + /* flow the color */ + for (i = 0; i < 3; i++) { + GLint first = (i + color_flow / 256) % 3; + GLint second = (first + 1) % 3; + GLint third = (second + 1) % 3; + GLfloat c = (color_flow % 256) / 256.0f; + + c = c * c * c; + colors[i][first] = 1.0f - c; + colors[i][second] = c; + colors[i][third] = 0.0f; + } + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glVertexPointer(2, GL_FLOAT, 0, verts); + glColorPointer(4, 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); +} + +static void +draw_textured_cube(void) +{ + static const GLfloat verts[][2] = { + { -4, -4 }, + { 4, -4 }, + { 4, 4 }, + { -4, 4 } + }; + static const GLfloat colors[][4] = { + { 1, 1, 1, 0.5 }, + { 1, 1, 1, 0.5 }, + { 1, 1, 1, 0.5 }, + { 1, 1, 1, 0.5 } + }; + static const GLfloat texs[][2] = { + { 0, 0 }, + { 1, 0 }, + { 1, 1 }, + { 0, 1 } + }; + static const GLfloat xforms[6][4] = { + { 0, 0, 1, 0 }, + { 90, 0, 1, 0 }, + { 180, 0, 1, 0 }, + { 270, 0, 1, 0 }, + { 90, 1, 0, 0 }, + { -90, 1, 0, 0 } + }; + GLint i; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (blend) { + glDisable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + } else { + glEnable(GL_DEPTH_TEST); + glDisable(GL_BLEND); + } + + glVertexPointer(2, GL_FLOAT, 0, verts); + glColorPointer(4, GL_FLOAT, 0, colors); + glTexCoordPointer(2, GL_FLOAT, 0, texs); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + for (i = 0; i < 6; i++) { + glPushMatrix(); + glRotatef(xforms[i][0], xforms[i][1], xforms[i][2], xforms[i][3]); + glTranslatef(0, 0, 4.1); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glPopMatrix(); + } + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + +static void +draw(void) +{ + use_pbuffer(); + draw_triangle(); + + use_window(); + + eglBindTexImage(dpy, surf_pbuf, EGL_BACK_BUFFER); + + glPushMatrix(); + glRotatef(view_rotx, 1, 0, 0); + glRotatef(view_roty, 0, 1, 0); + glRotatef(view_rotz, 0, 0, 1); + + draw_textured_cube(); + + glPopMatrix(); + + eglReleaseTexImage(dpy, surf_pbuf, EGL_BACK_BUFFER); +} + +/* new window size or exposure */ +static void +reshape(int width, int height) +{ + GLfloat ar = (GLfloat) width / (GLfloat) height; + + use_window(); + + glViewport(0, 0, (GLint) width, (GLint) height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustumf(-ar, ar, -1, 1, 5.0, 60.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -40.0); +} + +static void +event_loop(Display *x_dpy, Window win) +{ + while (1) { + int redraw = 1; + + if (XPending(x_dpy) > 0) { + XEvent event; + XNextEvent(x_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 if (code == XK_b) { + blend = !blend; + } + else { + r = XLookupString(&event.xkey, buffer, sizeof(buffer), + NULL, NULL); + if (buffer[0] == 27) { + /* escape */ + return; + } + } + } + redraw = 1; + break; + default: + ; /*no-op*/ + } + } + + if (redraw) { + view_rotx += 1.0; + view_roty += 2.0; + view_rotz += 1.5; + color_flow += 20; + draw(); + eglSwapBuffers(dpy, surf_win); + } + } +} + +int +main(int argc, char *argv[]) +{ + const int winWidth = 300, winHeight = 300; + Display *x_dpy; + Window win; + char *dpyName = NULL; + EGLint egl_major, egl_minor; + const char *s; + + x_dpy = XOpenDisplay(dpyName); + if (!x_dpy) { + printf("Error: couldn't open display %s\n", + dpyName ? dpyName : getenv("DISPLAY")); + return -1; + } + + dpy = eglGetDisplay(x_dpy); + if (!dpy) { + printf("Error: eglGetDisplay() failed\n"); + return -1; + } + + if (!eglInitialize(dpy, &egl_major, &egl_minor)) { + printf("Error: eglInitialize() failed\n"); + return -1; + } + + s = eglQueryString(dpy, EGL_VERSION); + printf("EGL_VERSION = %s\n", s); + + make_window(x_dpy, "color flow", 0, 0, winWidth, winHeight, &win); + make_pbuffer(winWidth, winHeight); + + XMapWindow(x_dpy, win); + + reshape(winWidth, winHeight); + event_loop(x_dpy, win); + + glDeleteTextures(1, &tex_pbuf); + + eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + eglTerminate(dpy); + + XDestroyWindow(x_dpy, win); + XCloseDisplay(x_dpy); + + return 0; +} diff --git a/progs/egl/opengles1/drawtex.c b/progs/egl/opengles1/drawtex.c new file mode 100644 index 00000000000..e9ac0153408 --- /dev/null +++ b/progs/egl/opengles1/drawtex.c @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2008 Tunsgten Graphics,Inc. All Rights Reserved. + */ + +/* + * Test GL_OES_draw_texture + * Brian Paul + * August 2008 + */ + +#define GL_GLEXT_PROTOTYPES + +#include <math.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <GLES/gl.h> +#include <GLES/glext.h> + +#include "eglut.h" + + +static GLfloat view_posx = 10.0, view_posy = 20.0; +static GLfloat width = 200, height = 200; +static GLboolean animate = GL_FALSE; +static int win; + + +static void +draw(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + + glDrawTexfOES(view_posx, view_posy, 0.0, width, height); +} + + +/* 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, -15.0); +} + + +static float +dist(GLuint i, GLuint j, float x, float y) +{ + return sqrt((i-x) * (i-x) + (j-y) * (j-y)); +} + +static void +make_smile_texture(void) +{ +#define SZ 128 + GLenum Filter = GL_LINEAR; + GLubyte image[SZ][SZ][4]; + GLuint i, j; + GLint cropRect[4]; + + for (i = 0; i < SZ; i++) { + for (j = 0; j < SZ; j++) { + GLfloat d_mouth = dist(i, j, SZ/2, SZ/2); + GLfloat d_rt_eye = dist(i, j, SZ*3/4, SZ*3/4); + GLfloat d_lt_eye = dist(i, j, SZ*3/4, SZ*1/4); + if (d_rt_eye < SZ / 8 || d_lt_eye < SZ / 8) { + image[i][j][0] = 20; + image[i][j][1] = 50; + image[i][j][2] = 255; + image[i][j][3] = 255; + } + else if (i < SZ/2 && d_mouth < SZ/3) { + image[i][j][0] = 255; + image[i][j][1] = 20; + image[i][j][2] = 20; + image[i][j][3] = 255; + } + else { + image[i][j][0] = 200; + image[i][j][1] = 200; + image[i][j][2] = 200; + image[i][j][3] = 255; + } + } + } + + glActiveTexture(GL_TEXTURE0); /* unit 0 */ + glBindTexture(GL_TEXTURE_2D, 42); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SZ, SZ, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + cropRect[0] = 0; + cropRect[1] = 0; + cropRect[2] = SZ; + cropRect[3] = SZ; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); +#undef SZ +} + + + +static void +init(void) +{ + const char *ext = (char *) glGetString(GL_EXTENSIONS); + + if (!strstr(ext, "GL_OES_draw_texture")) { + fprintf(stderr, "Sorry, this program requires GL_OES_draw_texture"); + exit(1); + } + + glClearColor(0.4, 0.4, 0.4, 0.0); + + make_smile_texture(); + glEnable(GL_TEXTURE_2D); +} + + +static void +idle(void) +{ + if (animate) { + view_posx += 1.0; + view_posy += 2.0; + eglutPostRedisplay(); + } +} + +static void +key(unsigned char key) +{ + switch (key) { + case ' ': + animate = !animate; + break; + case 'w': + width -= 1.0f; + break; + case 'W': + width += 1.0f; + break; + case 'h': + height -= 1.0f; + break; + case 'H': + height += 1.0f; + break; + case 27: + eglutDestroyWindow(win); + exit(0); + break; + default: + break; + } +} + +static void +special_key(int key) +{ + switch (key) { + case EGLUT_KEY_LEFT: + view_posx -= 1.0; + break; + case EGLUT_KEY_RIGHT: + view_posx += 1.0; + break; + case EGLUT_KEY_UP: + view_posy += 1.0; + break; + case EGLUT_KEY_DOWN: + view_posy -= 1.0; + break; + default: + break; + } +} + +int +main(int argc, char *argv[]) +{ + eglutInitWindowSize(400, 300); + eglutInitAPIMask(EGLUT_OPENGL_ES1_BIT); + eglutInit(argc, argv); + + win = eglutCreateWindow("drawtex"); + + eglutIdleFunc(idle); + eglutReshapeFunc(reshape); + eglutDisplayFunc(draw); + eglutKeyboardFunc(key); + eglutSpecialFunc(special_key); + + init(); + + eglutMainLoop(); + + return 0; +} diff --git a/progs/egl/opengles1/es1_info.c b/progs/egl/opengles1/es1_info.c new file mode 100644 index 00000000000..93816b52150 --- /dev/null +++ b/progs/egl/opengles1/es1_info.c @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2008 Tunsgten Graphics,Inc. All Rights Reserved. + */ + +/* + * List OpenGL ES extensions. + * Print ES 1 or ES 2 extensions depending on which library we're + * linked with: libGLESv1_CM.so vs libGLESv2.so + */ + +#define GL_GLEXT_PROTOTYPES + +#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> +#include <GLES/gl.h> +#include <GLES/glext.h> +#include <EGL/egl.h> + + +/* + * Print a list of extensions, with word-wrapping. + */ +static void +print_extension_list(const char *ext) +{ + const char *indentString = " "; + const int indent = 4; + const int max = 79; + int width, i, j; + + if (!ext || !ext[0]) + return; + + width = indent; + printf(indentString); + i = j = 0; + while (1) { + if (ext[j] == ' ' || ext[j] == 0) { + /* found end of an extension name */ + const int len = j - i; + if (width + len > max) { + /* start a new line */ + printf("\n"); + width = indent; + printf(indentString); + } + /* print the extension name between ext[i] and ext[j] */ + while (i < j) { + printf("%c", ext[i]); + i++; + } + /* either we're all done, or we'll continue with next extension */ + width += len + 1; + if (ext[j] == 0) { + break; + } + else { + i++; + j++; + if (ext[j] == 0) + break; + printf(", "); + width += 2; + } + } + j++; + } + printf("\n"); +} + + +static void +info(EGLDisplay egl_dpy) +{ + const char *s; + + 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); + + printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION)); + printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER)); + printf("GL_EXTENSIONS:\n"); + print_extension_list((char *) glGetString(GL_EXTENSIONS)); +} + + +/* + * 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, int es_ver, + Window *winRet, + EGLContext *ctxRet, + EGLSurface *surfRet) +{ + EGLint attribs[] = { + EGL_RENDERABLE_TYPE, 0x0, + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_NONE + }; + EGLint ctx_attribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 0, + EGL_NONE + }; + + 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 (es_ver == 1) + attribs[1] = EGL_OPENGL_ES_BIT; + else + attribs[1] = EGL_OPENGL_ES2_BIT; + ctx_attribs[1] = es_ver; + + 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); + } + + eglBindAPI(EGL_OPENGL_ES_API); + + ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, ctx_attribs ); + if (!ctx) { + printf("Error: eglCreateContext failed\n"); + exit(1); + } + + *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL); + + if (!*surfRet) { + printf("Error: eglCreateWindowSurface failed\n"); + exit(1); + } + + XFree(visInfo); + + *winRet = win; + *ctxRet = ctx; +} + + +static void +usage(void) +{ + printf("Usage:\n"); + printf(" -display <displayname> set the display to run on\n"); +} + + +int +main(int argc, char *argv[]) +{ + const int winWidth = 400, winHeight = 300; + Display *x_dpy; + Window win; + EGLSurface egl_surf; + EGLContext egl_ctx; + EGLDisplay egl_dpy; + char *dpyName = NULL; + EGLint egl_major, egl_minor, es_ver; + int i; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-display") == 0) { + dpyName = argv[i+1]; + i++; + } + 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; + } + + es_ver = 1; + /* decide the version from the executable's name */ + if (argc > 0 && argv[0] && strstr(argv[0], "es2")) + es_ver = 2; + make_x_window(x_dpy, egl_dpy, + "ES info", 0, 0, winWidth, winHeight, es_ver, + &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; + } + + info(egl_dpy); + + eglDestroyContext(egl_dpy, egl_ctx); + eglDestroySurface(egl_dpy, egl_surf); + eglTerminate(egl_dpy); + + + XDestroyWindow(x_dpy, win); + XCloseDisplay(x_dpy); + + return 0; +} diff --git a/progs/egl/opengles1/gears.c b/progs/egl/opengles1/gears.c new file mode 100644 index 00000000000..8462a4871a7 --- /dev/null +++ b/progs/egl/opengles1/gears.c @@ -0,0 +1,383 @@ +/* + * Copyright (C) 2009 Chia-I Wu <[email protected]> + * + * Based on eglgears by + * Copyright (C) 1999-2001 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. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <math.h> +#include <assert.h> + +#include <GLES/gl.h> +#include "eglut.h" + +#ifndef M_PI +#define M_PI 3.14159265 +#endif + + +struct gear { + GLuint vbo; + GLfloat *vertices; + GLsizei stride; + + GLint num_teeth; +}; + +static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0; +static struct gear gears[3]; +static GLfloat angle = 0.0; + +/* + * Initialize a gear wheel. + * + * Input: gear - gear to initialize + * inner_radius - radius of hole at center + * outer_radius - radius at center of teeth + * width - width of gear + * teeth - number of teeth + * tooth_depth - depth of tooth + */ +static void +init_gear(struct gear *gear, GLfloat inner_radius, GLfloat outer_radius, + GLfloat width, GLint teeth, GLfloat tooth_depth) +{ + GLfloat r0, r1, r2; + GLfloat a0, da; + GLint verts_per_tooth, total_verts, total_size; + GLint count, i; + GLfloat *verts; + + r0 = inner_radius; + r1 = outer_radius - tooth_depth / 2.0; + r2 = outer_radius + tooth_depth / 2.0; + + a0 = 2.0 * M_PI / teeth; + da = a0 / 4.0; + + gear->vbo = 0; + gear->vertices = NULL; + gear->stride = sizeof(GLfloat) * 6; /* XYZ + normal */ + gear->num_teeth = teeth; + + verts_per_tooth = 10 + 4; + total_verts = teeth * verts_per_tooth; + total_size = total_verts * gear->stride; + + verts = malloc(total_size); + if (!verts) { + printf("failed to allocate vertices\n"); + return; + } + +#define GEAR_VERT(r, n, sign) \ + do { \ + verts[count * 6 + 0] = (r) * vx[n]; \ + verts[count * 6 + 1] = (r) * vy[n]; \ + verts[count * 6 + 2] = (sign) * width * 0.5; \ + verts[count * 6 + 3] = normal[0]; \ + verts[count * 6 + 4] = normal[1]; \ + verts[count * 6 + 5] = normal[2]; \ + count++; \ + } while (0) + + count = 0; + for (i = 0; i < teeth; i++) { + GLfloat normal[3]; + GLfloat vx[5], vy[5]; + GLfloat u, v; + + normal[0] = 0.0; + normal[1] = 0.0; + normal[2] = 0.0; + + vx[0] = cos(i * a0 + 0 * da); + vy[0] = sin(i * a0 + 0 * da); + vx[1] = cos(i * a0 + 1 * da); + vy[1] = sin(i * a0 + 1 * da); + vx[2] = cos(i * a0 + 2 * da); + vy[2] = sin(i * a0 + 2 * da); + vx[3] = cos(i * a0 + 3 * da); + vy[3] = sin(i * a0 + 3 * da); + vx[4] = cos(i * a0 + 4 * da); + vy[4] = sin(i * a0 + 4 * da); + + /* outward faces of a tooth, 10 verts */ + normal[0] = vx[0]; + normal[1] = vy[0]; + GEAR_VERT(r1, 0, 1); + GEAR_VERT(r1, 0, -1); + + u = r2 * vx[1] - r1 * vx[0]; + v = r2 * vy[1] - r1 * vy[0]; + normal[0] = v; + normal[1] = -u; + GEAR_VERT(r2, 1, 1); + GEAR_VERT(r2, 1, -1); + + normal[0] = vx[0]; + normal[1] = vy[0]; + GEAR_VERT(r2, 2, 1); + GEAR_VERT(r2, 2, -1); + + u = r1 * vx[3] - r2 * vx[2]; + v = r1 * vy[3] - r2 * vy[2]; + normal[0] = v; + normal[1] = -u; + GEAR_VERT(r1, 3, 1); + GEAR_VERT(r1, 3, -1); + + normal[0] = vx[0]; + normal[1] = vy[0]; + GEAR_VERT(r1, 4, 1); + GEAR_VERT(r1, 4, -1); + + /* inside radius cylinder, 4 verts */ + normal[0] = -vx[4]; + normal[1] = -vy[4]; + GEAR_VERT(r0, 4, 1); + GEAR_VERT(r0, 4, -1); + + normal[0] = -vx[0]; + normal[1] = -vy[0]; + GEAR_VERT(r0, 0, 1); + GEAR_VERT(r0, 0, -1); + + assert(count % verts_per_tooth == 0); + } + assert(count == total_verts); +#undef GEAR_VERT + + gear->vertices = verts; + + /* setup VBO */ + glGenBuffers(1, &gear->vbo); + if (gear->vbo) { + glBindBuffer(GL_ARRAY_BUFFER, gear->vbo); + glBufferData(GL_ARRAY_BUFFER, total_size, verts, GL_STATIC_DRAW); + } +} + + +static void +draw_gear(const struct gear *gear) +{ + GLint i; + + if (!gear->vbo && !gear->vertices) { + printf("nothing to be drawn\n"); + return; + } + + if (gear->vbo) { + glBindBuffer(GL_ARRAY_BUFFER, gear->vbo); + glVertexPointer(3, GL_FLOAT, gear->stride, (const GLvoid *) 0); + glNormalPointer(GL_FLOAT, gear->stride, (const GLvoid *) (sizeof(GLfloat) * 3)); + } else { + glBindBuffer(GL_ARRAY_BUFFER, 0); + glVertexPointer(3, GL_FLOAT, gear->stride, gear->vertices); + glNormalPointer(GL_FLOAT, gear->stride, gear->vertices + 3); + } + + glEnableClientState(GL_VERTEX_ARRAY); + + for (i = 0; i < gear->num_teeth; i++) { + const GLint base = (10 + 4) * i; + GLushort indices[7]; + + glShadeModel(GL_FLAT); + + /* front face */ + indices[0] = base + 12; + indices[1] = base + 0; + indices[2] = base + 2; + indices[3] = base + 4; + indices[4] = base + 6; + indices[5] = base + 8; + indices[6] = base + 10; + + glNormal3f(0.0, 0.0, 1.0); + glDrawElements(GL_TRIANGLE_FAN, 7, GL_UNSIGNED_SHORT, indices); + + /* back face */ + indices[0] = base + 13; + indices[1] = base + 11; + indices[2] = base + 9; + indices[3] = base + 7; + indices[4] = base + 5; + indices[5] = base + 3; + indices[6] = base + 1; + + glNormal3f(0.0, 0.0, -1.0); + glDrawElements(GL_TRIANGLE_FAN, 7, GL_UNSIGNED_SHORT, indices); + + glEnableClientState(GL_NORMAL_ARRAY); + + /* outward face of a tooth */ + glDrawArrays(GL_TRIANGLE_STRIP, base, 10); + + /* inside radius cylinder */ + glShadeModel(GL_SMOOTH); + glDrawArrays(GL_TRIANGLE_STRIP, base + 10, 4); + + glDisableClientState(GL_NORMAL_ARRAY); + } + + glDisableClientState(GL_VERTEX_ARRAY); +} + + +static void +gears_draw(void) +{ + static const GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 }; + static const GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 }; + static const GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 }; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(view_rotx, 1.0, 0.0, 0.0); + glRotatef(view_roty, 0.0, 1.0, 0.0); + glRotatef(view_rotz, 0.0, 0.0, 1.0); + + glPushMatrix(); + glTranslatef(-3.0, -2.0, 0.0); + glRotatef(angle, 0.0, 0.0, 1.0); + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red); + draw_gear(&gears[0]); + + glPopMatrix(); + + glPushMatrix(); + glTranslatef(3.1, -2.0, 0.0); + glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0); + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, green); + draw_gear(&gears[1]); + + glPopMatrix(); + + glPushMatrix(); + glTranslatef(-3.1, 4.2, 0.0); + glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0); + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue); + draw_gear(&gears[2]); + + glPopMatrix(); + + glPopMatrix(); +} + + +static void gears_fini(void) +{ + GLint i; + for (i = 0; i < 3; i++) { + struct gear *gear = &gears[i]; + if (gear->vbo) { + glDeleteBuffers(1, &gear->vbo); + gear->vbo = 0; + } + if (gear->vertices) { + free(gear->vertices); + gear->vertices = NULL; + } + } +} + + +static void gears_init(void) +{ + static const GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 }; + + glLightfv(GL_LIGHT0, GL_POSITION, pos); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_DEPTH_TEST); + glEnable(GL_NORMALIZE); + + init_gear(&gears[0], 1.0, 4.0, 1.0, 20, 0.7); + init_gear(&gears[1], 0.5, 2.0, 2.0, 10, 0.7); + init_gear(&gears[2], 1.3, 2.0, 0.5, 10, 0.7); +} + + +/* new window size or exposure */ +static void +gears_reshape(int width, int height) +{ + GLfloat h = (GLfloat) height / (GLfloat) width; + + glViewport(0, 0, (GLint) width, (GLint) height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustumf(-1.0, 1.0, -h, h, 5.0, 60.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -40.0); +} + + +static void +gears_idle(void) +{ + static double t0 = -1.; + double dt, t = eglutGet(EGLUT_ELAPSED_TIME) / 1000.0; + if (t0 < 0.0) + t0 = t; + dt = t - t0; + t0 = t; + + angle += 70.0 * dt; /* 70 degrees per second */ + angle = fmod(angle, 360.0); /* prevents eventual overflow */ + + eglutPostRedisplay(); +} + + +int +main(int argc, char *argv[]) +{ + eglutInitWindowSize(300, 300); + eglutInitAPIMask(EGLUT_OPENGL_ES1_BIT); + eglutInit(argc, argv); + + eglutCreateWindow("gears"); + + eglutIdleFunc(gears_idle); + eglutReshapeFunc(gears_reshape); + eglutDisplayFunc(gears_draw); + + gears_init(); + + eglutMainLoop(); + + gears_fini(); + + return 0; +} diff --git a/progs/egl/xegl_tri.c b/progs/egl/opengles1/msaa.c index 1f1a005a210..b4c6c632177 100644 --- a/progs/egl/xegl_tri.c +++ b/progs/egl/opengles1/msaa.c @@ -20,11 +20,13 @@ */ /* - * Draw a triangle with X/EGL. + * Test MSAA with X/EGL and OpenGL ES 1.x * Brian Paul - * 3 June 2008 + * 15 September 2008 */ +#define USE_FULL_GL 0 + #include <assert.h> #include <math.h> @@ -34,27 +36,47 @@ #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/keysym.h> -#include <GL/gl.h> /* using full OpenGL for now */ -#include <GLES/egl.h> +#if USE_FULL_GL +#include <GL/gl.h> /* use full OpenGL */ +#else +#include <GLES/gl.h> /* use OpenGL ES 1.x */ +#include <GLES/glext.h> +#endif +#include <EGL/egl.h> + static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0; +static GLboolean AA = 0*GL_TRUE; static void draw(void) { - static const GLfloat verts[3][2] = { - { -1, -1 }, - { 1, -1 }, - { 0, 1 } + float a; + + static const GLfloat verts[4][2] = { + { -1, -.1 }, + { 1, -.1 }, + { -1, .1 }, + { 1, .1 } }; - static const GLfloat colors[3][3] = { - { 1, 0, 0 }, - { 0, 1, 0 }, - { 0, 0, 1 } + static const GLfloat colors[4][4] = { + { 1, 0, 0, 1 }, + { 0, 1, 0, 1 }, + { 0, 0, 1, 1 }, + { 1, 0, 1, 1 } }; + if (AA) { + printf("MSAA enabled\n"); + glEnable(GL_MULTISAMPLE); + } + else { + printf("MSAA disabled\n"); + glDisable(GL_MULTISAMPLE); + } + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); @@ -64,11 +86,22 @@ draw(void) { glVertexPointer(2, GL_FLOAT, 0, verts); - glColorPointer(3, GL_FLOAT, 0, colors); + glColorPointer(4, GL_FLOAT, 0, colors); + glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); - glDrawArrays(GL_TRIANGLES, 0, 3); + for (a = 0; a < 360; a += 20.0) { + glPushMatrix(); + + glRotatef(a, 0, 0, 1); + glTranslatef(1.5, 0, 0); + + /* draw triangle */ + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glPopMatrix(); + } glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); @@ -82,24 +115,30 @@ draw(void) static void reshape(int width, int height) { - GLfloat ar = (GLfloat) width / (GLfloat) height; + GLfloat ary = 3.0; + GLfloat arx = ary * (GLfloat) width / (GLfloat) height; glViewport(0, 0, (GLint) width, (GLint) height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); - glFrustum(-ar, ar, -1, 1, 5.0, 60.0); +#ifdef GL_VERSION_ES_CM_1_0 + glOrthof(-arx, arx, -ary, ary, -1.0, 1.0); +#else + glOrtho(-arx, arx, -ary, ary, -1.0, 1.0); +#endif glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - glTranslatef(0.0, 0.0, -10.0); } + static void init(void) { - glClearColor(0.4, 0.4, 0.4, 0.0); + printf("Press 'a' to toggle multisample antialiasing\n"); + printf("Press 'Esc' to exit\n"); } @@ -120,7 +159,8 @@ make_x_window(Display *x_dpy, EGLDisplay egl_dpy, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, EGL_DEPTH_SIZE, 1, - EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, + EGL_SAMPLES, 1, + EGL_SAMPLE_BUFFERS, 1, EGL_NONE }; @@ -139,14 +179,16 @@ make_x_window(Display *x_dpy, EGLDisplay egl_dpy, scrnum = DefaultScreen( x_dpy ); root = RootWindow( x_dpy, scrnum ); - if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs) || - !num_configs) { + 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 (num_configs < 1) { + printf("Error: Unable to find multisample pixel format.\n"); + printf("Try running glxinfo to see if your server supports MSAA.\n"); + exit(1); + } if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) { printf("Error: eglGetConfigAttrib() failed\n"); @@ -185,11 +227,15 @@ make_x_window(Display *x_dpy, EGLDisplay egl_dpy, None, (char **)NULL, 0, &sizehints); } +#if USE_FULL_GL eglBindAPI(EGL_OPENGL_API); +#else + eglBindAPI(EGL_OPENGL_ES_API); +#endif ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL ); if (!ctx) { - printf("Error: glXCreateContext failed\n"); + printf("Error: eglCreateContext failed\n"); exit(1); } @@ -244,7 +290,11 @@ event_loop(Display *dpy, Window win, else { r = XLookupString(&event.xkey, buffer, sizeof(buffer), NULL, NULL); - if (buffer[0] == 27) { + if (buffer[0] == 'a') { + AA = !AA; + redraw = 1; + } + else if (buffer[0] == 27) { /* escape */ return; } @@ -276,7 +326,7 @@ usage(void) int main(int argc, char *argv[]) { - const int winWidth = 300, winHeight = 300; + const int winWidth = 600, winHeight = 600; Display *x_dpy; Window win; EGLSurface egl_surf; @@ -288,6 +338,19 @@ main(int argc, char *argv[]) int i; const char *s; + static struct { + char *name; + GLenum value; + enum {GetString, GetInteger} type; + } info_items[] = { + {"GL_RENDERER", GL_RENDERER, GetString}, + {"GL_VERSION", GL_VERSION, GetString}, + {"GL_VENDOR", GL_VENDOR, GetString}, + {"GL_EXTENSIONS", GL_EXTENSIONS, GetString}, + {"GL_MAX_PALETTE_MATRICES_OES", GL_MAX_PALETTE_MATRICES_OES, GetInteger}, + {"GL_MAX_VERTEX_UNITS_OES", GL_MAX_VERTEX_UNITS_OES, GetInteger}, + }; + for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-display") == 0) { dpyName = argv[i+1]; @@ -323,8 +386,17 @@ main(int argc, char *argv[]) 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, - "xegl_tri", 0, 0, winWidth, winHeight, + "msaa", 0, 0, winWidth, winHeight, &win, &egl_ctx, &egl_surf); XMapWindow(x_dpy, win); @@ -334,11 +406,20 @@ main(int argc, char *argv[]) } 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)); - } - + for (i = 0; i < sizeof(info_items)/sizeof(info_items[0]); i++) { + switch (info_items[i].type) { + case GetString: + printf("%s = %s\n", info_items[i].name, (char *)glGetString(info_items[i].value)); + break; + case GetInteger: { + GLint rv = -1; + glGetIntegerv(info_items[i].value, &rv); + printf("%s = %d\n", info_items[i].name, rv); + break; + } + } + } + }; init(); /* Set initial projection/viewing transformation. diff --git a/progs/egl/opengles1/pbuffer.c b/progs/egl/opengles1/pbuffer.c new file mode 100644 index 00000000000..60f864445af --- /dev/null +++ b/progs/egl/opengles1/pbuffer.c @@ -0,0 +1,608 @@ +/* + * Copyright (C) 2008 Tunsgten Graphics,Inc. All Rights Reserved. + */ + +/* + * Test EGL Pbuffers + * Brian Paul + * August 2008 + */ + + +#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> +#include <GLES/gl.h> +#include <GLES/glext.h> +#include <EGL/egl.h> + + + +static int WinWidth = 300, WinHeight = 300; + +static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0; + + +static void +Normal(GLfloat *n, GLfloat nx, GLfloat ny, GLfloat nz) +{ + n[0] = nx; + n[1] = ny; + n[2] = nz; +} + +static void +Vertex(GLfloat *v, GLfloat vx, GLfloat vy, GLfloat vz) +{ + v[0] = vx; + v[1] = vy; + v[2] = vz; +} + +static void +Texcoord(GLfloat *v, GLfloat s, GLfloat t) +{ + v[0] = s; + v[1] = t; +} + + +/* Borrowed from glut, adapted */ +static void +draw_torus(GLfloat r, GLfloat R, GLint nsides, GLint rings) +{ + int i, j; + GLfloat theta, phi, theta1; + GLfloat cosTheta, sinTheta; + GLfloat cosTheta1, sinTheta1; + GLfloat ringDelta, sideDelta; + GLfloat varray[100][3], narray[100][3], tarray[100][2]; + int vcount; + + glVertexPointer(3, GL_FLOAT, 0, varray); + glNormalPointer(GL_FLOAT, 0, narray); + glTexCoordPointer(2, GL_FLOAT, 0, tarray); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + ringDelta = 2.0 * M_PI / rings; + sideDelta = 2.0 * M_PI / nsides; + + theta = 0.0; + cosTheta = 1.0; + sinTheta = 0.0; + for (i = rings - 1; i >= 0; i--) { + theta1 = theta + ringDelta; + cosTheta1 = cos(theta1); + sinTheta1 = sin(theta1); + + vcount = 0; /* glBegin(GL_QUAD_STRIP); */ + + phi = 0.0; + for (j = nsides; j >= 0; j--) { + GLfloat s0, s1, t; + GLfloat cosPhi, sinPhi, dist; + + phi += sideDelta; + cosPhi = cos(phi); + sinPhi = sin(phi); + dist = R + r * cosPhi; + + s0 = 20.0 * theta / (2.0 * M_PI); + s1 = 20.0 * theta1 / (2.0 * M_PI); + t = 8.0 * phi / (2.0 * M_PI); + + Normal(narray[vcount], cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi); + Texcoord(tarray[vcount], s1, t); + Vertex(varray[vcount], cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi); + vcount++; + + Normal(narray[vcount], cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi); + Texcoord(tarray[vcount], s0, t); + Vertex(varray[vcount], cosTheta * dist, -sinTheta * dist, r * sinPhi); + vcount++; + } + + /*glEnd();*/ + assert(vcount <= 100); + glDrawArrays(GL_TRIANGLE_STRIP, 0, vcount); + + theta = theta1; + cosTheta = cosTheta1; + sinTheta = sinTheta1; + } + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + + +static void +draw(void) +{ + 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); + glScalef(0.5, 0.5, 0.5); + + draw_torus(1.0, 3.0, 30, 60); + + glPopMatrix(); + + glFinish(); +} + + +/** + * Draw to both the window and pbuffer and compare results. + */ +static void +draw_both(EGLDisplay egl_dpy, EGLSurface egl_surf, EGLSurface egl_pbuf, + EGLContext egl_ctx) +{ + unsigned *wbuf, *pbuf; + int x = 100, y = 110; + int i, dif; + + wbuf = (unsigned *) malloc(WinWidth * WinHeight * 4); + pbuf = (unsigned *) malloc(WinWidth * WinHeight * 4); + + glPixelStorei(GL_PACK_ALIGNMENT, 1); + + /* first draw to window */ + if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) { + printf("Error: eglMakeCurrent(window) failed\n"); + return; + } + draw(); + glReadPixels(0, 0, WinWidth, WinHeight, GL_RGBA, GL_UNSIGNED_BYTE, wbuf); + printf("Window[%d,%d] = 0x%08x\n", x, y, wbuf[y*WinWidth+x]); + + eglSwapBuffers(egl_dpy, egl_surf); + + /* then draw to pbuffer */ + if (!eglMakeCurrent(egl_dpy, egl_pbuf, egl_pbuf, egl_ctx)) { + printf("Error: eglMakeCurrent(pbuffer) failed\n"); + return; + } + draw(); + glReadPixels(0, 0, WinWidth, WinHeight, GL_RGBA, GL_UNSIGNED_BYTE, pbuf); + printf("Pbuffer[%d,%d] = 0x%08x\n", x, y, pbuf[y*WinWidth+x]); + + + /* compare renderings */ + for (dif = i = 0; i < WinWidth * WinHeight; i++) { + if (wbuf[i] != pbuf[i]) { + dif = 1; + break; + } + } + + if (dif) + printf("Difference at %d: 0x%08x vs. 0x%08x\n", i, wbuf[i], pbuf[i]); + else + printf("Window rendering matches Pbuffer rendering!\n"); + + free(wbuf); + free(pbuf); +} + + +/* new window size or exposure */ +static void +reshape(int width, int height) +{ + GLfloat ar = (GLfloat) width / (GLfloat) height; + + WinWidth = width; + WinHeight = 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, -15.0); +} + + +static void +make_texture(void) +{ +#define SZ 64 + GLenum Filter = GL_LINEAR; + GLubyte image[SZ][SZ][4]; + GLuint i, j; + + for (i = 0; i < SZ; i++) { + for (j = 0; j < SZ; j++) { + GLfloat d = (i - SZ/2) * (i - SZ/2) + (j - SZ/2) * (j - SZ/2); + d = sqrt(d); + if (d < SZ/3) { + image[i][j][0] = 255; + image[i][j][1] = 255; + image[i][j][2] = 255; + image[i][j][3] = 255; + } + else { + image[i][j][0] = 127; + image[i][j][1] = 127; + image[i][j][2] = 127; + image[i][j][3] = 255; + } + } + } + + glActiveTexture(GL_TEXTURE0); /* unit 0 */ + glBindTexture(GL_TEXTURE_2D, 42); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SZ, SZ, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); +#undef SZ +} + + + +static void +init(void) +{ + static const GLfloat red[4] = {1, 0, 0, 0}; + static const GLfloat white[4] = {1.0, 1.0, 1.0, 1.0}; + static const GLfloat diffuse[4] = {0.7, 0.7, 0.7, 1.0}; + static const GLfloat specular[4] = {0.001, 0.001, 0.001, 1.0}; + static const GLfloat pos[4] = {20, 20, 50, 1}; + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 9.0); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_POSITION, pos); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); + glLightfv(GL_LIGHT0, GL_SPECULAR, specular); + + glClearColor(0.4, 0.4, 0.4, 0.0); + glEnable(GL_DEPTH_TEST); + + make_texture(); + glEnable(GL_TEXTURE_2D); +} + + +/* + * 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_NONE + }; + + 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); + } + + eglBindAPI(EGL_OPENGL_ES_API); + + ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL ); + if (!ctx) { + printf("Error: eglCreateContext failed\n"); + exit(1); + } + + *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL); + + if (!*surfRet) { + printf("Error: eglCreateWindowSurface failed\n"); + exit(1); + } + + XFree(visInfo); + + *winRet = win; + *ctxRet = ctx; +} + + +static EGLSurface +make_pbuffer(Display *x_dpy, EGLDisplay egl_dpy, int width, int height) +{ + static const EGLint config_attribs[] = { + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_DEPTH_SIZE, 1, + EGL_NONE + }; + EGLConfig config; + EGLSurface pbuf; + EGLint num_configs; + EGLint pbuf_attribs[5]; + + pbuf_attribs[0] = EGL_WIDTH; + pbuf_attribs[1] = width; + pbuf_attribs[2] = EGL_HEIGHT; + pbuf_attribs[3] = height; + pbuf_attribs[4] = EGL_NONE; + + if (!eglChooseConfig( egl_dpy, config_attribs, &config, 1, &num_configs)) { + printf("Error: couldn't get an EGL config for pbuffer\n"); + exit(1); + } + + pbuf = eglCreatePbufferSurface(egl_dpy, config, pbuf_attribs); + + return pbuf; +} + + +static void +event_loop(Display *dpy, Window win, + EGLDisplay egl_dpy, EGLSurface egl_surf, EGLSurface egl_pbuf, + EGLContext egl_ctx) +{ + int anim = 0; + + while (1) { + int redraw = 0; + + if (!anim || XPending(dpy)) { + XEvent event; + XNextEvent(dpy, &event); + + switch (event.type) { + case Expose: + redraw = 1; + break; + case ConfigureNotify: + if (event.xconfigure.window == win) + 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] == ' ') { + anim = !anim; + } + else if (buffer[0] == 27) { + /* escape */ + return; + } + } + } + redraw = 1; + break; + default: + ; /*no-op*/ + } + } + + if (anim) { + view_rotx += 1.0; + view_roty += 2.0; + redraw = 1; + } + + if (redraw) { + draw_both(egl_dpy, egl_surf, egl_pbuf, egl_ctx); + } + } +} + + +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[]) +{ + Display *x_dpy; + Window win; + EGLSurface egl_surf, egl_pbuf; + 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, + "pbuffer", 0, 0, WinWidth, WinHeight, + &win, &egl_ctx, &egl_surf); + + egl_pbuf = make_pbuffer(x_dpy, egl_dpy, WinWidth, WinHeight); + if (!egl_pbuf) { + printf("Error: eglCreatePBufferSurface() failed\n"); + return -1; + } + + 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, egl_pbuf, egl_ctx); + + eglDestroyContext(egl_dpy, egl_ctx); + eglDestroySurface(egl_dpy, egl_surf); + eglTerminate(egl_dpy); + + + XDestroyWindow(x_dpy, win); + XCloseDisplay(x_dpy); + + return 0; +} diff --git a/progs/egl/opengles1/render_tex.c b/progs/egl/opengles1/render_tex.c new file mode 100644 index 00000000000..0200fa4cb06 --- /dev/null +++ b/progs/egl/opengles1/render_tex.c @@ -0,0 +1,659 @@ +/* + * Copyright (C) 2008 Tunsgten Graphics,Inc. All Rights Reserved. + */ + +/* + * Test EGL render to texture. + * Brian Paul + * August 2008 + */ + + +#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> +#include <GLES/gl.h> +#include <GLES/glext.h> +#include <EGL/egl.h> + + +static int TexWidth = 256, TexHeight = 256; + +static int WinWidth = 300, WinHeight = 300; + +static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0; + +static GLuint DotTexture, RenderTexture; + + +static void +Normal(GLfloat *n, GLfloat nx, GLfloat ny, GLfloat nz) +{ + n[0] = nx; + n[1] = ny; + n[2] = nz; +} + +static void +Vertex(GLfloat *v, GLfloat vx, GLfloat vy, GLfloat vz) +{ + v[0] = vx; + v[1] = vy; + v[2] = vz; +} + +static void +Texcoord(GLfloat *v, GLfloat s, GLfloat t) +{ + v[0] = s; + v[1] = t; +} + + +/* Borrowed from glut, adapted */ +static void +draw_torus(GLfloat r, GLfloat R, GLint nsides, GLint rings) +{ + int i, j; + GLfloat theta, phi, theta1; + GLfloat cosTheta, sinTheta; + GLfloat cosTheta1, sinTheta1; + GLfloat ringDelta, sideDelta; + GLfloat varray[100][3], narray[100][3], tarray[100][2]; + int vcount; + + glVertexPointer(3, GL_FLOAT, 0, varray); + glNormalPointer(GL_FLOAT, 0, narray); + glTexCoordPointer(2, GL_FLOAT, 0, tarray); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + ringDelta = 2.0 * M_PI / rings; + sideDelta = 2.0 * M_PI / nsides; + + theta = 0.0; + cosTheta = 1.0; + sinTheta = 0.0; + for (i = rings - 1; i >= 0; i--) { + theta1 = theta + ringDelta; + cosTheta1 = cos(theta1); + sinTheta1 = sin(theta1); + + vcount = 0; /* glBegin(GL_QUAD_STRIP); */ + + phi = 0.0; + for (j = nsides; j >= 0; j--) { + GLfloat s0, s1, t; + GLfloat cosPhi, sinPhi, dist; + + phi += sideDelta; + cosPhi = cos(phi); + sinPhi = sin(phi); + dist = R + r * cosPhi; + + s0 = 20.0 * theta / (2.0 * M_PI); + s1 = 20.0 * theta1 / (2.0 * M_PI); + t = 8.0 * phi / (2.0 * M_PI); + + Normal(narray[vcount], cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi); + Texcoord(tarray[vcount], s1, t); + Vertex(varray[vcount], cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi); + vcount++; + + Normal(narray[vcount], cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi); + Texcoord(tarray[vcount], s0, t); + Vertex(varray[vcount], cosTheta * dist, -sinTheta * dist, r * sinPhi); + vcount++; + } + + /*glEnd();*/ + assert(vcount <= 100); + glDrawArrays(GL_TRIANGLE_STRIP, 0, vcount); + + theta = theta1; + cosTheta = cosTheta1; + sinTheta = sinTheta1; + } + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + + +static void +draw_torus_to_texture(void) +{ + glViewport(0, 0, TexWidth, TexHeight); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustumf(-1, 1, -1, 1, 5.0, 60.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -15.0); + + glClearColor(0.4, 0.4, 0.4, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindTexture(GL_TEXTURE_2D, DotTexture); + + glEnable(GL_LIGHTING); + + glPushMatrix(); + glRotatef(view_roty, 0, 1, 0); + glScalef(0.5, 0.5, 0.5); + + draw_torus(1.0, 3.0, 30, 60); + + glPopMatrix(); + + glDisable(GL_LIGHTING); + +#if 0 + glBindTexture(GL_TEXTURE_2D, RenderTexture); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, TexWidth, TexHeight); +#endif + + glFinish(); +} + + +static void +draw_textured_quad(void) +{ + GLfloat ar = (GLfloat) WinWidth / (GLfloat) WinHeight; + + glViewport(0, 0, WinWidth, WinHeight); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustumf(-ar, ar, -1, 1, 5.0, 60.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -8.0); + + glClearColor(0.4, 0.4, 1.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindTexture(GL_TEXTURE_2D, RenderTexture); + + glPushMatrix(); + glRotatef(view_rotx, 1, 0, 0); + glRotatef(view_rotz, 0, 0, 1); + + { + static const GLfloat texcoord[4][2] = { + { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 } + }; + static const GLfloat vertex[4][2] = { + { -1, -1 }, { 1, -1 }, { -1, 1 }, { 1, 1 } + }; + + glVertexPointer(2, GL_FLOAT, 0, vertex); + glTexCoordPointer(2, GL_FLOAT, 0, texcoord); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + + glPopMatrix(); +} + + + +static void +draw(EGLDisplay egl_dpy, EGLSurface egl_surf, EGLSurface egl_pbuf, + EGLContext egl_ctx) +{ + /*printf("Begin draw\n");*/ + + /* first draw torus to pbuffer /texture */ +#if 01 + if (!eglMakeCurrent(egl_dpy, egl_pbuf, egl_pbuf, egl_ctx)) { +#else + if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) { +#endif + printf("Error: eglMakeCurrent(pbuf) failed\n"); + return; + } + draw_torus_to_texture(); + + /* draw textured quad to window */ + if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) { + printf("Error: eglMakeCurrent(pbuffer) failed\n"); + return; + } + + glBindTexture(GL_TEXTURE_2D, RenderTexture); + eglBindTexImage(egl_dpy, egl_pbuf, EGL_BACK_BUFFER); + draw_textured_quad(); + eglReleaseTexImage(egl_dpy, egl_pbuf, EGL_BACK_BUFFER); + + eglSwapBuffers(egl_dpy, egl_surf); + + /*printf("End draw\n");*/ +} + + + +static void +make_dot_texture(void) +{ +#define SZ 64 + GLenum Filter = GL_LINEAR; + GLubyte image[SZ][SZ][4]; + GLuint i, j; + + for (i = 0; i < SZ; i++) { + for (j = 0; j < SZ; j++) { + GLfloat d = (i - SZ/2) * (i - SZ/2) + (j - SZ/2) * (j - SZ/2); + d = sqrt(d); + if (d < SZ/3) { + image[i][j][0] = 255; + image[i][j][1] = 255; + image[i][j][2] = 255; + image[i][j][3] = 255; + } + else { + image[i][j][0] = 127; + image[i][j][1] = 127; + image[i][j][2] = 127; + image[i][j][3] = 255; + } + } + } + + glGenTextures(1, &DotTexture); + glBindTexture(GL_TEXTURE_2D, DotTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SZ, SZ, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); +#undef SZ +} + + +static void +make_render_texture(void) +{ + GLenum Filter = GL_LINEAR; + glGenTextures(1, &RenderTexture); + glBindTexture(GL_TEXTURE_2D, RenderTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TexWidth, TexHeight, 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); +} + + +static void +init(void) +{ + static const GLfloat red[4] = {1, 0, 0, 0}; + static const GLfloat white[4] = {1.0, 1.0, 1.0, 1.0}; + static const GLfloat diffuse[4] = {0.7, 0.7, 0.7, 1.0}; + static const GLfloat specular[4] = {0.001, 0.001, 0.001, 1.0}; + static const GLfloat pos[4] = {20, 20, 50, 1}; + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 9.0); + + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_POSITION, pos); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); + glLightfv(GL_LIGHT0, GL_SPECULAR, specular); + + glEnable(GL_DEPTH_TEST); + + make_dot_texture(); + make_render_texture(); + + printf("DotTexture=%u RenderTexture=%u\n", DotTexture, RenderTexture); + + glEnable(GL_TEXTURE_2D); +} + + +/* + * 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_NONE + }; + + 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); + } + + eglBindAPI(EGL_OPENGL_ES_API); + + ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL ); + if (!ctx) { + printf("Error: eglCreateContext failed\n"); + exit(1); + } + + *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL); + + if (!*surfRet) { + printf("Error: eglCreateWindowSurface failed\n"); + exit(1); + } + + XFree(visInfo); + + *winRet = win; + *ctxRet = ctx; +} + + +static EGLSurface +make_pbuffer(Display *x_dpy, EGLDisplay egl_dpy, int width, int height) +{ + static const EGLint config_attribs[] = { + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_DEPTH_SIZE, 1, + EGL_NONE + }; + EGLConfig config; + EGLSurface pbuf; + EGLint num_configs; + EGLint pbuf_attribs[15]; + int i = 0; + + pbuf_attribs[i++] = EGL_WIDTH; + pbuf_attribs[i++] = width; + pbuf_attribs[i++] = EGL_HEIGHT; + pbuf_attribs[i++] = height; + pbuf_attribs[i++] = EGL_TEXTURE_FORMAT; + pbuf_attribs[i++] = EGL_TEXTURE_RGBA; + pbuf_attribs[i++] = EGL_TEXTURE_TARGET; + pbuf_attribs[i++] = EGL_TEXTURE_2D; + pbuf_attribs[i++] = EGL_MIPMAP_TEXTURE; + pbuf_attribs[i++] = EGL_FALSE; + pbuf_attribs[i++] = EGL_NONE; + assert(i <= 15); + + if (!eglChooseConfig( egl_dpy, config_attribs, &config, 1, &num_configs)) { + printf("Error: couldn't get an EGL config for pbuffer\n"); + exit(1); + } + + pbuf = eglCreatePbufferSurface(egl_dpy, config, pbuf_attribs); + + return pbuf; +} + + +static void +event_loop(Display *dpy, Window win, + EGLDisplay egl_dpy, EGLSurface egl_surf, EGLSurface egl_pbuf, + EGLContext egl_ctx) +{ + int anim = 0; + + while (1) { + int redraw = 0; + + if (!anim || XPending(dpy)) { + XEvent event; + XNextEvent(dpy, &event); + + switch (event.type) { + case Expose: + redraw = 1; + break; + case ConfigureNotify: + if (event.xconfigure.window == win) { + WinWidth = event.xconfigure.width; + WinHeight = 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] == ' ') { + anim = !anim; + } + else if (buffer[0] == 'z') { + view_rotz += 5.0; + } + else if (buffer[0] == 'Z') { + view_rotz -= 5.0; + } + else if (buffer[0] == 27) { + /* escape */ + return; + } + } + } + redraw = 1; + break; + default: + ; /*no-op*/ + } + } + + if (anim) { + view_rotx += 1.0; + view_roty += 2.0; + redraw = 1; + } + + if (redraw) { + draw(egl_dpy, egl_surf, egl_pbuf, egl_ctx); + } + } +} + + +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[]) +{ + Display *x_dpy; + Window win; + EGLSurface egl_surf, egl_pbuf; + 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, + "render_tex", 0, 0, WinWidth, WinHeight, + &win, &egl_ctx, &egl_surf); + + egl_pbuf = make_pbuffer(x_dpy, egl_dpy, TexWidth, TexHeight); + if (!egl_pbuf) { + printf("Error: eglCreatePBufferSurface() failed\n"); + return -1; + } + + 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(); + + event_loop(x_dpy, win, egl_dpy, egl_surf, egl_pbuf, egl_ctx); + + eglDestroyContext(egl_dpy, egl_ctx); + eglDestroySurface(egl_dpy, egl_surf); + eglTerminate(egl_dpy); + + + XDestroyWindow(x_dpy, win); + XCloseDisplay(x_dpy); + + return 0; +} diff --git a/progs/egl/opengles1/texture_from_pixmap.c b/progs/egl/opengles1/texture_from_pixmap.c new file mode 100644 index 00000000000..8e7e803d781 --- /dev/null +++ b/progs/egl/opengles1/texture_from_pixmap.c @@ -0,0 +1,579 @@ +/* + * 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 <[email protected]> + */ + +/* + * This demo uses EGL_KHR_image_pixmap and GL_OES_EGL_image to demonstrate + * texture-from-pixmap. + */ + +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> /* for usleep */ +#include <sys/time.h> /* for gettimeofday */ +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/keysym.h> +#include <GLES/gl.h> +#include <GLES/glext.h> +#include <EGL/egl.h> +#include <EGL/eglext.h> + +struct app_data { + /* native */ + Display *xdpy; + Window canvas, cube; + Pixmap pix; + unsigned int width, height, depth; + GC fg, bg; + + /* EGL */ + EGLDisplay dpy; + EGLContext ctx; + EGLSurface surf; + EGLImageKHR img; + + /* OpenGL ES */ + GLuint texture; + + PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR; + PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR; + PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES; + + /* app state */ + Bool loop; + Bool redraw, reshape; + + struct { + Bool active; + unsigned long next_frame; /* in ms */ + float view_rotx; + float view_roty; + float view_rotz; + + } animate; + + struct { + Bool active; + int x1, y1; + int x2, y2; + } paint; +}; + +static void +gl_redraw(void) +{ + const GLfloat verts[4][2] = { + { -1, -1 }, + { 1, -1 }, + { 1, 1 }, + { -1, 1 } + }; + const GLfloat texcoords[4][2] = { + { 0, 1 }, + { 1, 1 }, + { 1, 0 }, + { 0, 0 } + }; + const GLfloat faces[6][4] = { + { 0, 0, 1, 0 }, + { 90, 0, 1, 0 }, + { 180, 0, 1, 0 }, + { 270, 0, 1, 0 }, + { 90, 1, 0, 0 }, + { -90, 1, 0, 0 } + }; + GLint i; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glVertexPointer(2, GL_FLOAT, 0, verts); + glTexCoordPointer(2, GL_FLOAT, 0, texcoords); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + for (i = 0; i < 6; i++) { + glPushMatrix(); + glRotatef(faces[i][0], faces[i][1], faces[i][2], faces[i][3]); + glTranslatef(0, 0, 1.0); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glPopMatrix(); + } + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + +static void +gl_reshape(int width, int height) +{ + GLfloat ar = (GLfloat) width / (GLfloat) height; + + glViewport(0, 0, width, height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustumf(-ar, ar, -1, 1, 5.0, 60.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -10.0); +} + +static void +app_redraw(struct app_data *data) +{ + /* pixmap has changed */ + if (data->reshape || data->paint.active) { + eglWaitNative(EGL_CORE_NATIVE_ENGINE); + + if (data->reshape) { + data->glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, + (GLeglImageOES) data->img); + } + } + + XCopyArea(data->xdpy, data->pix, data->canvas, data->fg, + 0, 0, data->width, data->height, 0, 0); + + glPushMatrix(); + glRotatef(data->animate.view_rotx, 1, 0, 0); + glRotatef(data->animate.view_roty, 0, 1, 0); + glRotatef(data->animate.view_rotz, 0, 0, 1); + gl_redraw(); + glPopMatrix(); + + eglSwapBuffers(data->dpy, data->surf); +} + +static void +app_reshape(struct app_data *data) +{ + const EGLint img_attribs[] = { + EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, + EGL_NONE + }; + + XResizeWindow(data->xdpy, data->cube, data->width, data->height); + XMoveWindow(data->xdpy, data->cube, data->width, 0); + + if (data->img) + data->eglDestroyImageKHR(data->dpy, data->img); + if (data->pix) + XFreePixmap(data->xdpy, data->pix); + + data->pix = XCreatePixmap(data->xdpy, data->canvas, data->width, data->height, data->depth); + XFillRectangle(data->xdpy, data->pix, data->bg, 0, 0, data->width, data->height); + + data->img = data->eglCreateImageKHR(data->dpy, EGL_NO_CONTEXT, + EGL_NATIVE_PIXMAP_KHR, (EGLClientBuffer) data->pix, img_attribs); + + gl_reshape(data->width, data->height); +} + +static void +app_toggle_animate(struct app_data *data) +{ + data->animate.active = !data->animate.active; + + if (data->animate.active) { + struct timeval tv; + + gettimeofday(&tv, NULL); + data->animate.next_frame = tv.tv_sec * 1000 + tv.tv_usec / 1000; + } +} + +static void +app_next_event(struct app_data *data) +{ + XEvent event; + + data->reshape = False; + data->redraw = False; + data->paint.active = False; + + if (data->animate.active) { + struct timeval tv; + unsigned long now; + + gettimeofday(&tv, NULL); + now = tv.tv_sec * 1000 + tv.tv_usec / 1000; + + /* wait for next frame */ + if (!XPending(data->xdpy) && now < data->animate.next_frame) { + usleep((data->animate.next_frame - now) * 1000); + gettimeofday(&tv, NULL); + now = tv.tv_sec * 1000 + tv.tv_usec / 1000; + } + + while (now >= data->animate.next_frame) { + data->animate.view_rotx += 1.0; + data->animate.view_roty += 2.0; + data->animate.view_rotz += 1.5; + + /* 30fps */ + data->animate.next_frame += 1000 / 30; + } + + /* check again in case there were events when sleeping */ + if (!XPending(data->xdpy)) { + data->redraw = True; + return; + } + } + + XNextEvent(data->xdpy, &event); + + switch (event.type) { + case ConfigureNotify: + data->width = event.xconfigure.width / 2; + data->height = event.xconfigure.height; + data->reshape = True; + break; + case Expose: + data->redraw = True; + break; + case KeyPress: + { + int code; + + code = XLookupKeysym(&event.xkey, 0); + switch (code) { + case XK_a: + app_toggle_animate(data); + break; + case XK_Escape: + data->loop = False; + break; + default: + break; + } + } + break; + case ButtonPress: + data->paint.x1 = data->paint.x2 = event.xbutton.x; + data->paint.y1 = data->paint.y2 = event.xbutton.y; + break; + case ButtonRelease: + data->paint.active = False; + break; + case MotionNotify: + data->paint.x1 = data->paint.x2; + data->paint.y1 = data->paint.y2; + data->paint.x2 = event.xmotion.x; + data->paint.y2 = event.xmotion.y; + data->paint.active = True; + break; + default: + break; + } + + if (data->paint.active || data->reshape) + data->redraw = True; +} + +static void +app_init_gl(struct app_data *data) +{ + glClearColor(0.1, 0.1, 0.3, 0.0); + glColor4f(1.0, 1.0, 1.0, 1.0); + + glGenTextures(1, &data->texture); + + glBindTexture(GL_TEXTURE_2D, data->texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glEnable(GL_TEXTURE_2D); + glEnable(GL_DEPTH_TEST); +} + +static Bool +app_init_exts(struct app_data *data) +{ + const char *exts; + + exts = eglQueryString(data->dpy, EGL_EXTENSIONS); + data->eglCreateImageKHR = + (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress("eglCreateImageKHR"); + data->eglDestroyImageKHR = + (PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress("eglDestroyImageKHR"); + if (!exts || !strstr(exts, "EGL_KHR_image_pixmap") || + !data->eglCreateImageKHR || !data->eglDestroyImageKHR) { + printf("EGL does not support EGL_KHR_image_pixmap\n"); + return False; + } + + exts = (const char *) glGetString(GL_EXTENSIONS); + data->glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) + eglGetProcAddress("glEGLImageTargetTexture2DOES"); + if (!exts || !strstr(exts, "GL_OES_EGL_image") || + !data->glEGLImageTargetTexture2DOES) { + printf("OpenGL ES does not support GL_OES_EGL_image\n"); + return False; + } + + return True; +} + +static void +app_run(struct app_data *data) +{ + Window root; + int x, y; + unsigned int border; + + if (!eglMakeCurrent(data->dpy, data->surf, data->surf, data->ctx)) + return; + + if (!app_init_exts(data)) + return; + + printf("Draw something on the left with the mouse!\n"); + + app_init_gl(data); + + if (!XGetGeometry(data->xdpy, data->canvas, &root, &x, &y, + &data->width, &data->height, &border, &data->depth)) + return; + data->width /= 2; + + app_reshape(data); + + XMapWindow(data->xdpy, data->canvas); + XMapWindow(data->xdpy, data->cube); + + app_toggle_animate(data); + data->loop = True; + + while (data->loop) { + app_next_event(data); + + if (data->reshape) + app_reshape(data); + if (data->paint.active) { + XDrawLine(data->xdpy, data->pix, data->fg, + data->paint.x1, data->paint.y1, + data->paint.x2, data->paint.y2); + } + + if (data->redraw) + app_redraw(data); + } + + eglMakeCurrent(data->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); +} + +static Bool +make_x_window(struct app_data *data, const char *name, + int x, int y, int width, int height) +{ + 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_ES_BIT, + EGL_NONE + }; + static const EGLint ctx_attribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 1, + EGL_NONE + }; + int scrnum; + XSetWindowAttributes attr; + unsigned long mask; + Window root; + Window win; + XVisualInfo *visInfo, visTemplate; + int num_visuals; + EGLConfig config; + EGLint num_configs; + EGLint vid; + + scrnum = DefaultScreen( data->xdpy ); + root = RootWindow( data->xdpy, scrnum ); + + if (!eglChooseConfig( data->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(data->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(data->xdpy, 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( data->xdpy, root, visInfo->visual, AllocNone); + attr.event_mask = StructureNotifyMask | ExposureMask | + KeyPressMask | ButtonPressMask | ButtonMotionMask; + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + + win = XCreateWindow( data->xdpy, root, 0, 0, width * 2, 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(data->xdpy, win, &sizehints); + XSetStandardProperties(data->xdpy, win, name, name, + None, (char **)NULL, 0, &sizehints); + } + + data->canvas = win; + + attr.event_mask = 0x0; + win = XCreateWindow( data->xdpy, win, width, 0, width, height, + 0, visInfo->depth, InputOutput, + visInfo->visual, mask, &attr ); + data->cube = win; + + eglBindAPI(EGL_OPENGL_ES_API); + + data->ctx = eglCreateContext(data->dpy, config, EGL_NO_CONTEXT, ctx_attribs ); + if (!data->ctx) { + printf("Error: eglCreateContext failed\n"); + exit(1); + } + + data->surf = eglCreateWindowSurface(data->dpy, config, data->cube, NULL); + if (!data->surf) { + printf("Error: eglCreateWindowSurface failed\n"); + exit(1); + } + + XFree(visInfo); + + return (data->canvas && data->cube && data->ctx && data->surf); +} + +static void +app_fini(struct app_data *data) +{ + if (data->img) + data->eglDestroyImageKHR(data->dpy, data->img); + if (data->pix) + XFreePixmap(data->xdpy, data->pix); + + if (data->fg) + XFreeGC(data->xdpy, data->fg); + if (data->bg) + XFreeGC(data->xdpy, data->bg); + + if (data->surf) + eglDestroySurface(data->dpy, data->surf); + if (data->ctx) + eglDestroyContext(data->dpy, data->ctx); + + if (data->cube) + XDestroyWindow(data->xdpy, data->cube); + if (data->canvas) + XDestroyWindow(data->xdpy, data->canvas); + + if (data->dpy) + eglTerminate(data->dpy); + if (data->xdpy) + XCloseDisplay(data->xdpy); +} + +static Bool +app_init(struct app_data *data, int argc, char **argv) +{ + XGCValues gc_vals; + + memset(data, 0, sizeof(*data)); + + data->xdpy = XOpenDisplay(NULL); + if (!data->xdpy) + goto fail; + + data->dpy = eglGetDisplay(data->xdpy); + if (!data->dpy || !eglInitialize(data->dpy, NULL, NULL)) + goto fail; + + if (!make_x_window(data, "EGLImage TFP", 0, 0, 300, 300)) + goto fail; + + gc_vals.function = GXcopy; + gc_vals.foreground = WhitePixel(data->xdpy, DefaultScreen(data->xdpy)); + gc_vals.line_width = 3; + gc_vals.line_style = LineSolid; + gc_vals.fill_style = FillSolid; + + data->fg = XCreateGC(data->xdpy, data->canvas, + GCFunction | GCForeground | GCLineWidth | GCLineStyle | GCFillStyle, + &gc_vals); + gc_vals.foreground = BlackPixel(data->xdpy, DefaultScreen(data->xdpy)); + data->bg = XCreateGC(data->xdpy, data->canvas, + GCFunction | GCForeground | GCLineWidth | GCLineStyle | GCFillStyle, + &gc_vals); + if (!data->fg || !data->bg) + goto fail; + + return True; + +fail: + app_fini(data); + return False; +} + +int +main(int argc, char **argv) +{ + struct app_data data; + + if (app_init(&data, argc, argv)) { + app_run(&data); + app_fini(&data); + } + + return 0; +} diff --git a/progs/egl/opengles1/torus.c b/progs/egl/opengles1/torus.c new file mode 100644 index 00000000000..8f262b53d6c --- /dev/null +++ b/progs/egl/opengles1/torus.c @@ -0,0 +1,448 @@ +/* + * Copyright (C) 2008 Tunsgten Graphics,Inc. All Rights Reserved. + */ + +/* + * Draw a lit, textured torus with X/EGL and OpenGL ES 1.x + * Brian Paul + * July 2008 + */ + + +#include <assert.h> +#include <math.h> +#include <stdlib.h> +#include <stdio.h> +#include <GLES/gl.h> + +#include "eglut.h" + +static const struct { + GLenum internalFormat; + const char *name; + GLuint num_entries; + GLuint size; +} cpal_formats[] = { + { GL_PALETTE4_RGB8_OES, "GL_PALETTE4_RGB8_OES", 16, 3 }, + { GL_PALETTE4_RGBA8_OES, "GL_PALETTE4_RGBA8_OES", 16, 4 }, + { GL_PALETTE4_R5_G6_B5_OES, "GL_PALETTE4_R5_G6_B5_OES", 16, 2 }, + { GL_PALETTE4_RGBA4_OES, "GL_PALETTE4_RGBA4_OES", 16, 2 }, + { GL_PALETTE4_RGB5_A1_OES, "GL_PALETTE4_RGB5_A1_OES", 16, 2 }, + { GL_PALETTE8_RGB8_OES, "GL_PALETTE8_RGB8_OES", 256, 3 }, + { GL_PALETTE8_RGBA8_OES, "GL_PALETTE8_RGBA8_OES", 256, 4 }, + { GL_PALETTE8_R5_G6_B5_OES, "GL_PALETTE8_R5_G6_B5_OES", 256, 2 }, + { GL_PALETTE8_RGBA4_OES, "GL_PALETTE8_RGBA4_OES", 256, 2 }, + { GL_PALETTE8_RGB5_A1_OES, "GL_PALETTE8_RGB5_A1_OES", 256, 2 } +}; +#define NUM_CPAL_FORMATS (sizeof(cpal_formats) / sizeof(cpal_formats[0])) + +static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0; +static GLint tex_format = NUM_CPAL_FORMATS; +static GLboolean animate = GL_TRUE; +static int win; + + +static void +Normal(GLfloat *n, GLfloat nx, GLfloat ny, GLfloat nz) +{ + n[0] = nx; + n[1] = ny; + n[2] = nz; +} + +static void +Vertex(GLfloat *v, GLfloat vx, GLfloat vy, GLfloat vz) +{ + v[0] = vx; + v[1] = vy; + v[2] = vz; +} + +static void +Texcoord(GLfloat *v, GLfloat s, GLfloat t) +{ + v[0] = s; + v[1] = t; +} + + +/* Borrowed from glut, adapted */ +static void +draw_torus(GLfloat r, GLfloat R, GLint nsides, GLint rings) +{ + int i, j; + GLfloat theta, phi, theta1; + GLfloat cosTheta, sinTheta; + GLfloat cosTheta1, sinTheta1; + GLfloat ringDelta, sideDelta; + GLfloat varray[100][3], narray[100][3], tarray[100][2]; + int vcount; + + glVertexPointer(3, GL_FLOAT, 0, varray); + glNormalPointer(GL_FLOAT, 0, narray); + glTexCoordPointer(2, GL_FLOAT, 0, tarray); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + ringDelta = 2.0 * M_PI / rings; + sideDelta = 2.0 * M_PI / nsides; + + theta = 0.0; + cosTheta = 1.0; + sinTheta = 0.0; + for (i = rings - 1; i >= 0; i--) { + theta1 = theta + ringDelta; + cosTheta1 = cos(theta1); + sinTheta1 = sin(theta1); + + vcount = 0; /* glBegin(GL_QUAD_STRIP); */ + + phi = 0.0; + for (j = nsides; j >= 0; j--) { + GLfloat s0, s1, t; + GLfloat cosPhi, sinPhi, dist; + + phi += sideDelta; + cosPhi = cos(phi); + sinPhi = sin(phi); + dist = R + r * cosPhi; + + s0 = 20.0 * theta / (2.0 * M_PI); + s1 = 20.0 * theta1 / (2.0 * M_PI); + t = 8.0 * phi / (2.0 * M_PI); + + Normal(narray[vcount], cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi); + Texcoord(tarray[vcount], s1, t); + Vertex(varray[vcount], cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi); + vcount++; + + Normal(narray[vcount], cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi); + Texcoord(tarray[vcount], s0, t); + Vertex(varray[vcount], cosTheta * dist, -sinTheta * dist, r * sinPhi); + vcount++; + } + + /*glEnd();*/ + assert(vcount <= 100); + glDrawArrays(GL_TRIANGLE_STRIP, 0, vcount); + + theta = theta1; + cosTheta = cosTheta1; + sinTheta = sinTheta1; + } + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + + +static void +draw(void) +{ + 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); + glScalef(0.5, 0.5, 0.5); + + draw_torus(1.0, 3.0, 30, 60); + + 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, -15.0); +} + + +static GLint +make_cpal_texture(GLint idx) +{ +#define SZ 64 + GLenum internalFormat = GL_PALETTE4_RGB8_OES + idx; + GLenum Filter = GL_LINEAR; + GLubyte palette[256 * 4 + SZ * SZ]; + GLubyte *indices; + GLsizei image_size; + GLuint i, j; + GLuint packed_indices = 0; + + assert(cpal_formats[idx].internalFormat == internalFormat); + + /* init palette */ + switch (internalFormat) { + case GL_PALETTE4_RGB8_OES: + case GL_PALETTE8_RGB8_OES: + /* first entry */ + palette[0] = 255; + palette[1] = 255; + palette[2] = 255; + /* second entry */ + palette[3] = 127; + palette[4] = 127; + palette[5] = 127; + break; + case GL_PALETTE4_RGBA8_OES: + case GL_PALETTE8_RGBA8_OES: + /* first entry */ + palette[0] = 255; + palette[1] = 255; + palette[2] = 255; + palette[3] = 255; + /* second entry */ + palette[4] = 127; + palette[5] = 127; + palette[6] = 127; + palette[7] = 255; + break; + case GL_PALETTE4_R5_G6_B5_OES: + case GL_PALETTE8_R5_G6_B5_OES: + { + GLushort *pal = (GLushort *) palette; + /* first entry */ + pal[0] = (31 << 11 | 63 << 5 | 31); + /* second entry */ + pal[1] = (15 << 11 | 31 << 5 | 15); + } + break; + case GL_PALETTE4_RGBA4_OES: + case GL_PALETTE8_RGBA4_OES: + { + GLushort *pal = (GLushort *) palette; + /* first entry */ + pal[0] = (15 << 12 | 15 << 8 | 15 << 4 | 15); + /* second entry */ + pal[1] = (7 << 12 | 7 << 8 | 7 << 4 | 15); + } + break; + case GL_PALETTE4_RGB5_A1_OES: + case GL_PALETTE8_RGB5_A1_OES: + { + GLushort *pal = (GLushort *) palette; + /* first entry */ + pal[0] = (31 << 11 | 31 << 6 | 31 << 1 | 1); + /* second entry */ + pal[1] = (15 << 11 | 15 << 6 | 15 << 1 | 1); + } + break; + } + + image_size = cpal_formats[idx].size * cpal_formats[idx].num_entries; + indices = palette + image_size; + for (i = 0; i < SZ; i++) { + for (j = 0; j < SZ; j++) { + GLfloat d; + GLint index; + d = (i - SZ/2) * (i - SZ/2) + (j - SZ/2) * (j - SZ/2); + d = sqrt(d); + index = (d < SZ / 3) ? 0 : 1; + + if (cpal_formats[idx].num_entries == 16) { + /* 4-bit indices packed in GLubyte */ + packed_indices |= index << (4 * (1 - (j % 2))); + if (j % 2) { + *(indices + (i * SZ + j - 1) / 2) = packed_indices & 0xff; + packed_indices = 0; + image_size += 1; + } + } + else { + /* 8-bit indices */ + *(indices + i * SZ + j) = index; + image_size += 1; + } + } + } + + glActiveTexture(GL_TEXTURE0); /* unit 0 */ + glBindTexture(GL_TEXTURE_2D, 42); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, internalFormat, SZ, SZ, 0, + image_size, palette); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); +#undef SZ + + return image_size; +} + + +static GLint +make_texture(void) +{ +#define SZ 64 + GLenum Filter = GL_LINEAR; + GLubyte image[SZ][SZ][4]; + GLuint i, j; + + for (i = 0; i < SZ; i++) { + for (j = 0; j < SZ; j++) { + GLfloat d = (i - SZ/2) * (i - SZ/2) + (j - SZ/2) * (j - SZ/2); + d = sqrt(d); + if (d < SZ/3) { + image[i][j][0] = 255; + image[i][j][1] = 255; + image[i][j][2] = 255; + image[i][j][3] = 255; + } + else { + image[i][j][0] = 127; + image[i][j][1] = 127; + image[i][j][2] = 127; + image[i][j][3] = 255; + } + } + } + + glActiveTexture(GL_TEXTURE0); /* unit 0 */ + glBindTexture(GL_TEXTURE_2D, 42); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SZ, SZ, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); +#undef SZ + + return sizeof(image); +} + + + +static void +init(void) +{ + static const GLfloat red[4] = {1, 0, 0, 0}; + static const GLfloat white[4] = {1.0, 1.0, 1.0, 1.0}; + static const GLfloat diffuse[4] = {0.7, 0.7, 0.7, 1.0}; + static const GLfloat specular[4] = {0.001, 0.001, 0.001, 1.0}; + static const GLfloat pos[4] = {20, 20, 50, 1}; + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white); + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 9.0); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_POSITION, pos); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); + glLightfv(GL_LIGHT0, GL_SPECULAR, specular); + + glClearColor(0.4, 0.4, 0.4, 0.0); + glEnable(GL_DEPTH_TEST); + + make_texture(); + glEnable(GL_TEXTURE_2D); +} + + +static void +idle(void) +{ + if (animate) { + view_rotx += 1.0; + view_roty += 2.0; + eglutPostRedisplay(); + } +} + +static void +key(unsigned char key) +{ + switch (key) { + case ' ': + animate = !animate; + break; + case 't': + { + GLint size; + tex_format = (tex_format + 1) % (NUM_CPAL_FORMATS + 1); + if (tex_format < NUM_CPAL_FORMATS) { + size = make_cpal_texture(tex_format); + printf("Using %s (%d bytes)\n", + cpal_formats[tex_format].name, size); + } + else { + size = make_texture(); + printf("Using uncompressed texture (%d bytes)\n", size); + } + + eglutPostRedisplay(); + } + break; + case 27: + eglutDestroyWindow(win); + exit(0); + break; + default: + break; + } +} + +static void +special_key(int key) +{ + switch (key) { + 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); + + win = eglutCreateWindow("torus"); + + eglutIdleFunc(idle); + eglutReshapeFunc(reshape); + eglutDisplayFunc(draw); + eglutKeyboardFunc(key); + eglutSpecialFunc(special_key); + + init(); + + eglutMainLoop(); + + return 0; +} diff --git a/progs/egl/opengles1/tri.c b/progs/egl/opengles1/tri.c new file mode 100644 index 00000000000..01ad9bd37e4 --- /dev/null +++ b/progs/egl/opengles1/tri.c @@ -0,0 +1,211 @@ +/* + * 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; +} diff --git a/progs/egl/opengles1/two_win.c b/progs/egl/opengles1/two_win.c new file mode 100644 index 00000000000..4785e5304d3 --- /dev/null +++ b/progs/egl/opengles1/two_win.c @@ -0,0 +1,433 @@ +/* + * 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. + */ + +/* + * Test drawing to two windows. + * Brian Paul + * August 2008 + */ + + +#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> +#include <GLES/gl.h> +#include <GLES/glext.h> +#include <EGL/egl.h> + + +static int WinWidth[2] = {150, 300}, WinHeight[2] = {150, 300}; + + +static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0; + + +/* 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 +draw(int win) +{ + 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 } + }; + + assert(win == 0 || win == 1); + + reshape(WinWidth[win], WinHeight[win]); + + 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); + + /* draw triangle */ + { + glVertexPointer(2, GL_FLOAT, 0, verts); + glColorPointer(4, 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(); +} + + +static void +init(void) +{ + glClearColor(0.4, 0.4, 0.4, 0.0); +} + + +/* + * 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_NONE + }; + + 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, x, y, 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 + eglBindAPI(EGL_OPENGL_API); +#else + eglBindAPI(EGL_OPENGL_ES_API); +#endif + + if (ctxRet) { + ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL ); + if (!ctx) { + printf("Error: eglCreateContext failed\n"); + exit(1); + } + *ctxRet = ctx; + } + + *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL); + + if (!*surfRet) { + printf("Error: eglCreateWindowSurface failed\n"); + exit(1); + } + + XFree(visInfo); + + *winRet = win; +} + + +static void +event_loop(Display *dpy, Window win1, Window win2, + EGLDisplay egl_dpy, EGLSurface egl_surf1, EGLSurface egl_surf2, + EGLContext egl_ctx) +{ + while (1) { + int redraw = 0; + int win; + XEvent event; + + XNextEvent(dpy, &event); + + switch (event.type) { + case Expose: + redraw = 1; + break; + case ConfigureNotify: + if (event.xconfigure.window == win1) + win = 0; + else + win = 1; + WinWidth[win] = event.xconfigure.width; + WinHeight[win] = 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) { + /* win 1 */ + if (!eglMakeCurrent(egl_dpy, egl_surf1, egl_surf1, egl_ctx)) { + printf("Error: eglMakeCurrent(1) failed\n"); + return; + } + draw(0); + eglSwapBuffers(egl_dpy, egl_surf1); + + /* win 2 */ + if (!eglMakeCurrent(egl_dpy, egl_surf2, egl_surf2, egl_ctx)) { + printf("Error: eglMakeCurrent(2) failed\n"); + return; + } + draw(1); + eglSwapBuffers(egl_dpy, egl_surf2); + } + } +} + + +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[]) +{ + Display *x_dpy; + Window win1, win2; + EGLSurface egl_surf1, egl_surf2; + EGLContext egl_ctx; + EGLDisplay egl_dpy; + char *dpyName = NULL; + GLboolean printInfo = GL_FALSE; + EGLint egl_major, egl_minor; + int i; + const char *s; + + static struct { + char *name; + GLenum value; + enum {GetString, GetInteger} type; + } info_items[] = { + {"GL_RENDERER", GL_RENDERER, GetString}, + {"GL_VERSION", GL_VERSION, GetString}, + {"GL_VENDOR", GL_VENDOR, GetString}, + {"GL_EXTENSIONS", GL_EXTENSIONS, GetString}, + {"GL_MAX_PALETTE_MATRICES_OES", GL_MAX_PALETTE_MATRICES_OES, GetInteger}, + {"GL_MAX_VERTEX_UNITS_OES", GL_MAX_VERTEX_UNITS_OES, GetInteger}, + }; + + 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, + "xegl_two_win #1", 0, 0, WinWidth[0], WinHeight[0], + &win1, &egl_ctx, &egl_surf1); + + make_x_window(x_dpy, egl_dpy, + "xegl_two_win #2", WinWidth[0] + 50, 0, + WinWidth[1], WinHeight[1], + &win2, NULL, &egl_surf2); + + XMapWindow(x_dpy, win1); + + XMapWindow(x_dpy, win2); + + if (!eglMakeCurrent(egl_dpy, egl_surf1, egl_surf1, egl_ctx)) { + printf("Error: eglMakeCurrent() failed\n"); + return -1; + } + + if (printInfo) { + for (i = 0; i < sizeof(info_items)/sizeof(info_items[0]); i++) { + switch (info_items[i].type) { + case GetString: + printf("%s = %s\n", info_items[i].name, (char *)glGetString(info_items[i].value)); + break; + case GetInteger: { + GLint rv = -1; + glGetIntegerv(info_items[i].value, &rv); + printf("%s = %d\n", info_items[i].name, rv); + break; + } + } + } + }; + + init(); + + event_loop(x_dpy, win1, win2, egl_dpy, egl_surf1, egl_surf2, egl_ctx); + + eglDestroyContext(egl_dpy, egl_ctx); + eglDestroySurface(egl_dpy, egl_surf1); + eglDestroySurface(egl_dpy, egl_surf2); + eglTerminate(egl_dpy); + + XDestroyWindow(x_dpy, win1); + XDestroyWindow(x_dpy, win2); + XCloseDisplay(x_dpy); + + return 0; +} diff --git a/progs/egl/opengles2/.gitignore b/progs/egl/opengles2/.gitignore new file mode 100644 index 00000000000..6158cc6e680 --- /dev/null +++ b/progs/egl/opengles2/.gitignore @@ -0,0 +1,3 @@ +es2_info.c +es2_info +tri diff --git a/progs/egl/opengles2/Makefile b/progs/egl/opengles2/Makefile new file mode 100644 index 00000000000..1ee2af24127 --- /dev/null +++ b/progs/egl/opengles2/Makefile @@ -0,0 +1,52 @@ +# progs/egl/opengles2/Makefile + +TOP = ../../.. +include $(TOP)/configs/current + + +INCLUDE_DIRS = \ + -I$(TOP)/include \ + $(X11_CFLAGS) + +HEADERS = $(TOP)/include/GLES/egl.h + + +ES2_LIB_DEPS = \ + $(TOP)/$(LIB_DIR)/libEGL.so \ + $(TOP)/$(LIB_DIR)/libGLESv2.so + + +ES2_LIBS = \ + -L$(TOP)/$(LIB_DIR) -lEGL \ + -L$(TOP)/$(LIB_DIR) -lGLESv2 $(LIBDRM_LIB) $(X11_LIBS) + +PROGRAMS = \ + es2_info \ + tri + + +.c.o: + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ + + + +default: $(PROGRAMS) + + + +es2_info.c: ../opengles1/es1_info.c + cp -f $^ $@ + +es2_info: es2_info.o $(ES2_LIB_DEPS) + $(CC) $(CFLAGS) es2_info.o $(ES2_LIBS) -o $@ + +tri: tri.o $(ES2_LIB_DEPS) + $(CC) $(CFLAGS) tri.o $(ES2_LIBS) -o $@ + + + +clean: + rm -f *.o *~ + rm -f $(PROGRAMS) + rm -f es2_info.c + diff --git a/progs/egl/opengles2/tri.c b/progs/egl/opengles2/tri.c new file mode 100644 index 00000000000..8981d8a7e21 --- /dev/null +++ b/progs/egl/opengles2/tri.c @@ -0,0 +1,516 @@ +/************************************************************************** + * + * 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 + }; + static const EGLint ctx_attribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; + 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); + } + + /* test eglQueryContext() */ + { + EGLint val; + eglQueryContext(egl_dpy, ctx, EGL_CONTEXT_CLIENT_VERSION, &val); + assert(val == 2); + } + + *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; +} diff --git a/progs/egl/openvg/.gitignore b/progs/egl/openvg/.gitignore new file mode 100644 index 00000000000..3e1733c8c83 --- /dev/null +++ b/progs/egl/openvg/.gitignore @@ -0,0 +1,26 @@ +lion_x11 +lion_screen +sp_x11 +sp_screen +trivial/arc +trivial/cap +trivial/clear +trivial/coord +trivial/dash +trivial/ellipse +trivial/filter +trivial/gradorigin +trivial/lineto +trivial/lingrad +trivial/lookup +trivial/mask4 +trivial/mask +trivial/path3 +trivial/radialgrad +trivial/readpixels +trivial/roundedrect +trivial/star-nonzero +trivial/star-oddeven +trivial/stroke2 +trivial/stroke +trivial/vguarc diff --git a/progs/egl/openvg/Makefile b/progs/egl/openvg/Makefile new file mode 100644 index 00000000000..3b11933db26 --- /dev/null +++ b/progs/egl/openvg/Makefile @@ -0,0 +1,51 @@ +# progs/egl/openvg/Makefile + +TOP = ../../.. +include $(TOP)/configs/current + +VG_LIBS=-lm -lEGL -lOpenVG -L$(TOP)/lib -L$(TOP)/lib/gallium +INCLUDE_DIRS = -I$(TOP)/include $(X11_CFLAGS) + +EGLUT_DIR = $(TOP)/progs/egl/eglut + +EGLUT_DEMOS = \ + sp + +EGLUT_X11_DEMOS := $(addsuffix _x11,$(EGLUT_DEMOS)) +EGLUT_SCREEN_DEMOS := $(addsuffix _screen,$(EGLUT_DEMOS)) + +PROGRAMS = \ + lion_x11 \ + lion_screen + +.c.o: + $(CC) -c $(INCLUDE_DIRS) -I$(EGLUT_DIR) $(CFLAGS) $< -o $@ + + + +default: $(PROGRAMS) $(EGLUT_X11_DEMOS) $(EGLUT_SCREEN_DEMOS) + +lion_x11: lion.o lion-render.o $(EGLUT_DIR)/libeglut-x11.a + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ lion.o lion-render.o \ + -L$(EGLUT_DIR) -leglut-x11 $(VG_LIBS) $(X11_LIBS) + +lion_screen: lion.o lion-render.o $(EGLUT_DIR)/libeglut-screen.a + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ lion.o lion-render.o \ + -L$(EGLUT_DIR) -leglut-screen $(VG_LIBS) + + +# define the rules for EGLUT demos +define eglut-demo-rule +$(1)_x11 $(1)_screen: $(1)_%: $(1).o $(EGLUT_DIR)/libeglut-%.a +endef +$(foreach demo, $(EGLUT_DEMOS), $(eval $(call eglut-demo-rule,$(demo)))) + +# build EGLUT demos +$(EGLUT_X11_DEMOS): + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -L$(EGLUT_DIR) -leglut-$* $(VG_LIBS) $(X11_LIBS) +$(EGLUT_SCREEN_DEMOS): + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -L$(EGLUT_DIR) -leglut-$* $(VG_LIBS) + +clean: + rm -f *.o *~ + rm -f $(EGLUT_X11_DEMOS) $(EGLUT_SCREEN_DEMOS) diff --git a/progs/egl/openvg/lion-render.c b/progs/egl/openvg/lion-render.c new file mode 100644 index 00000000000..f3f151f5522 --- /dev/null +++ b/progs/egl/openvg/lion-render.c @@ -0,0 +1,1573 @@ +#include "lion-render.h" + +#include <stdlib.h> +#include <stdio.h> + +#define ELEMENTS(x) (sizeof(x)/sizeof((x)[0])) + +static void init(struct lion *l, int i, VGint hexColor, const VGfloat *coords, int elems) +{ + static VGubyte cmds[128]; + VGfloat color[4]; + VGint j; + + color[0] = ((hexColor >> 16) & 0xff) / 255.f; + color[1] = ((hexColor >> 8) & 0xff) / 255.f; + color[2] = ((hexColor >> 0) & 0xff) / 255.f; + color[3] = 1.0; + + l->paths[i] = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0f, 0.0f, + 0, 0, (unsigned int)VG_PATH_CAPABILITY_ALL); + l->fills[i] = vgCreatePaint(); + vgSetParameterfv(l->fills[i], VG_PAINT_COLOR, 4, color); + + cmds[0] = VG_MOVE_TO_ABS; + for (j = 1; j < elems; ++j) { + cmds[j] = VG_LINE_TO_ABS; + } + + vgAppendPathData(l->paths[i], elems, cmds, coords); +} + +static void poly0(struct lion *l) +{ + VGfloat color = 0xf2cc99; + static const VGfloat coords[] = {69,18, 82,8, 99,3, 118,5, 135,12, 149,21, 156,13, 165,9, 177,13, 183,28, + 180,50, 164,91, 155,107, 154,114, 151,121, 141,127, 139,136, 155,206, 157,251, 126,342, + 133,357, 128,376, 83,376, 75,368, 67,350, 61,350, 53,369, 4,369, 2,361, 5,354, + 12,342, 16,321, 4,257, 4,244, 7,218, 9,179, 26,127, 43,93, 32,77, 30,70, + 24,67, 16,49, 17,35, 18,23, 30,12, 40,7, 53,7, 62,12 + }; + + init(l, 0, color, coords, ELEMENTS(coords)/2); +} + +static void poly1(struct lion *l) +{ + VGfloat color = 0xe5b27f; + static const VGfloat coords[] = {142,79, 136,74, 138,82, 133,78, 133,84, 127,78, 128,85, + 124,80, 125,87, 119,82, 119,90, 125,99, 125,96, 128,100, 128,94, + 131,98, 132,93, 135,97, 136,93, 138,97, 139,94, 141,98, 143,94, + 144,85 + }; + + init(l, 1, color, coords, ELEMENTS(coords)/2); +} + +static void poly2(struct lion *l) +{ + VGfloat color = 0xeb8080; + static const VGfloat coords[] = {127,101, 132,100, 137,99, 144,101, 143,105, 135,110 + }; + + init(l, 2, color, coords, ELEMENTS(coords)/2); +} + +static void poly3(struct lion *l) +{ + VGfloat color = 0xf2cc99; + static const VGfloat coords[] = {178,229, 157,248, 139,296, 126,349, 137,356, + 158,357, 183,342, 212,332, 235,288, 235,261, + 228,252, 212,250, 188,251 + }; + + init(l, 3, color, coords, ELEMENTS(coords)/2); +} + +static void poly4(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {56,229, 48,241, 48,250, 57,281, 63,325, 71,338, + 81,315, 76,321, 79,311, 83,301, 75,308, 80,298, + 73,303, 76,296, 71,298, 74,292, 69,293, 74,284, + 78,278, 71,278, 74,274, 68,273, 70,268, 66,267, + 68,261, 60,266, 62,259, 65,253, 57,258, 59,251, + 55,254, 55,248, 60,237, 54,240, 58,234, 54,236 + }; + + init(l, 4, color, coords, ELEMENTS(coords)/2); +} + +static void poly5(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {74,363, 79,368, 81,368, 85,362, 89,363, 92,370, 96,373, + 101,372, 108,361, 110,371, 113,373, 116,371, 120,358, 122,363, + 123,371, 126,371, 129,367, 132,357, 135,361, 130,376, 127,377, + 94,378, 84,376, 76,371 + }; + + init(l, 5, color, coords, ELEMENTS(coords)/2); +} + +static void poly6(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {212,250, 219,251, 228,258, 236,270, 235,287, 225,304, + 205,332, 177,343, 171,352, 158,357, 166,352, 168,346, + 168,339, 165,333, 155,327, 155,323, 161,320, 165,316, + 169,316, 167,312, 171,313, 168,308, 173,309, 170,306, + 177,306, 175,308, 177,311, 174,311, 176,316, 171,315, + 174,319, 168,320, 168,323, 175,327, 179,332, 183,326, + 184,332, 189,323, 190,328, 194,320, 194,325, 199,316, + 201,320, 204,313, 206,316, 208,310, 211,305, 219,298, + 226,288, 229,279, 228,266, 224,259, 217,253 + }; + + init(l, 6, color, coords, ELEMENTS(coords)/2); +} + +static void poly7(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {151,205, 151,238, 149,252, 141,268, 128,282, 121,301, + 130,300, 126,313, 118,324, 116,337, 120,346, 133,352, + 133,340, 137,333, 145,329, 156,327, 153,319, 153,291, + 157,271, 170,259, 178,277, 193,250, 174,216 + }; + + init(l, 7, color, coords, ELEMENTS(coords)/2); +} + +static void poly8(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {78,127, 90,142, 95,155, 108,164, 125,167, 139,175, + 150,206, 152,191, 141,140, 121,148, 100,136 + }; + + init(l, 8, color, coords, ELEMENTS(coords)/2); +} + +static void poly9(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {21,58, 35,63, 38,68, 32,69, 42,74, 40,79, 47,80, 54,83, + 45,94, 34,81, 32,73, 24,66 + }; + + init(l, 9, color, coords, ELEMENTS(coords)/2); +} + +static void poly10(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {71,34, 67,34, 66,27, 59,24, 54,17, 48,17, 39,22, + 30,26, 28,31, 31,39, 38,46, 29,45, 36,54, 41,61, + 41,70, 50,69, 54,71, 55,58, 67,52, 76,43, 76,39, + 68,44 + }; + + init(l, 10, color, coords, ELEMENTS(coords)/2); +} + +static void poly11(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {139,74, 141,83, 143,89, 144,104, 148,104, 155,106, + 154,86, 157,77, 155,72, 150,77, 144,77 + }; + + init(l, 11, color, coords, ELEMENTS(coords)/2); +} + +static void poly12(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {105,44, 102,53, 108,58, 111,62, 112,55 + }; + + init(l, 12, color, coords, ELEMENTS(coords)/2); +} + +static void poly13(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {141,48, 141,54, 144,58, 139,62, 137,66, 136,59, 137,52 + }; + + init(l, 13, color, coords, ELEMENTS(coords)/2); +} + +static void poly14(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {98,135, 104,130, 105,134, 108,132, 108,135, 112,134, + 113,137, 116,136, 116,139, 119,139, 124,141, 128,140, + 133,138, 140,133, 139,140, 126,146, 104,144 + }; + + init(l, 14, color, coords, ELEMENTS(coords)/2); +} + +static void poly15(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {97,116, 103,119, 103,116, 111,118, 116,117, 122,114, + 127,107, 135,111, 142,107, 141,114, 145,118, 149,121, + 145,125, 140,124, 127,121, 113,125, 100,124 + }; + + init(l, 15, color, coords, ELEMENTS(coords)/2); +} + +static void poly16(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {147,33, 152,35, 157,34, 153,31, 160,31, 156,28, 161,28, + 159,24, 163,25, 163,21, 165,22, 170,23, 167,17, 172,21, + 174,18, 175,23, 176,22, 177,28, 177,33, 174,37, 176,39, + 174,44, 171,49, 168,53, 164,57, 159,68, 156,70, 154,60, + 150,51, 146,43, 144,35 + }; + + init(l, 16, color, coords, ELEMENTS(coords)/2); +} + +static void poly17(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {85,72, 89,74, 93,75, 100,76, 105,75, 102,79, 94,79, 88,76 + }; + + init(l, 17, color, coords, ELEMENTS(coords)/2); +} + +static void poly18(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {86,214, 79,221, 76,232, 82,225, 78,239, 82,234, 78,245, + 81,243, 79,255, 84,250, 84,267, 87,254, 90,271, 90,257, + 95,271, 93,256, 95,249, 92,252, 93,243, 89,253, 89,241, + 86,250, 87,236, 83,245, 87,231, 82,231, 90,219, 84,221 + }; + + init(l, 18, color, coords, ELEMENTS(coords)/2); +} + +static void poly19(struct lion *l) +{ + VGfloat color = 0xffcc7f; + static const VGfloat coords[] = {93,68, 96,72, 100,73, 106,72, 108,66, 105,63, 100,62 + }; + + init(l, 19, color, coords, ELEMENTS(coords)/2); +} + +static void poly20(struct lion *l) +{ + VGfloat color = 0xffcc7f; + static const VGfloat coords[] = {144,64, 142,68, 142,73, 146,74, 150,73, 154,64, 149,62 + }; + + init(l, 20, color, coords, ELEMENTS(coords)/2); +} + +static void poly21(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {57,91, 42,111, 52,105, 41,117, 53,112, 46,120, 53,116, + 50,124, 57,119, 55,127, 61,122, 60,130, 67,126, 66,134, + 71,129, 72,136, 77,130, 76,137, 80,133, 82,138, 86,135, + 96,135, 94,129, 86,124, 83,117, 77,123, 79,117, 73,120, + 75,112, 68,116, 71,111, 65,114, 69,107, 63,110, 68,102, + 61,107, 66,98, 61,103, 63,97, 57,99 + }; + + init(l, 21, color, coords, ELEMENTS(coords)/2); +} + +static void poly22(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {83,79, 76,79, 67,82, 75,83, 65,88, 76,87, 65,92, 76,91, + 68,96, 77,95, 70,99, 80,98, 72,104, 80,102, 76,108, 85,103, + 92,101, 87,98, 93,96, 86,94, 91,93, 85,91, 93,89, 99,89, 105,93, + 107,85, 102,82, 92,80 + }; + + init(l, 22, color, coords, ELEMENTS(coords)/2); +} + +static void poly23(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {109,77, 111,83, 109,89, 113,94, 117,90, 117,81, 114,78 + }; + + init(l, 23, color, coords, ELEMENTS(coords)/2); +} + +static void poly24(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {122,128, 127,126, 134,127, 136,129, 134,130, 130,128, 124,129 + }; + + init(l, 24, color, coords, ELEMENTS(coords)/2); +} + +static void poly25(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {78,27, 82,32, 80,33, 82,36, 78,37, 82,40, 78,42, 81,46, 76,47, + 78,49, 74,50, 82,52, 87,50, 83,48, 91,46, 86,45, 91,42, 88,40, + 92,37, 86,34, 90,31, 86,29, 89,26 + }; + + init(l, 25, color, coords, ELEMENTS(coords)/2); +} + +static void poly26(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {82,17, 92,20, 79,21, 90,25, 81,25, 94,28, 93,26, 101,30, + 101,26, 107,33, 108,28, 111,40, 113,34, 115,45, 117,39, + 119,54, 121,46, 124,58, 126,47, 129,59, 130,49, 134,58, + 133,44, 137,48, 133,37, 137,40, 133,32, 126,20, 135,26, + 132,19, 138,23, 135,17, 142,18, 132,11, 116,6, 94,6, 78,11, + 92,12, 80,14, 90,16 + }; + + init(l, 26, color, coords, ELEMENTS(coords)/2); +} + +static void poly27(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {142,234, 132,227, 124,223, 115,220, 110,225, 118,224, 127,229, + 135,236, 122,234, 115,237, 113,242, 121,238, 139,243, 121,245, + 111,254, 95,254, 102,244, 104,235, 110,229, 100,231, 104,224, + 113,216, 122,215, 132,217, 141,224, 145,230, 149,240 + }; + + init(l, 27, color, coords, ELEMENTS(coords)/2); +} + +static void poly28(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {115,252, 125,248, 137,249, 143,258, 134,255, 125,254 + }; + + init(l, 28, color, coords, ELEMENTS(coords)/2); +} + +static void poly29(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {114,212, 130,213, 140,219, 147,225, 144,214, 137,209, 128,207 + }; + + init(l, 29, color, coords, ELEMENTS(coords)/2); +} + +static void poly30(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {102,263, 108,258, 117,257, 131,258, 116,260, 109,265 + }; + + init(l, 30, color, coords, ELEMENTS(coords)/2); +} + +static void poly31(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {51,241, 35,224, 40,238, 23,224, 31,242, 19,239, 28,247, 17,246, + 25,250, 37,254, 39,263, 44,271, 47,294, 48,317, 51,328, 60,351, + 60,323, 53,262, 47,246 + }; + + init(l, 31, color, coords, ELEMENTS(coords)/2); +} + +static void poly32(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {2,364, 9,367, 14,366, 18,355, 20,364, 26,366, 31,357, 35,364, + 39,364, 42,357, 47,363, 53,360, 59,357, 54,369, 7,373 + }; + + init(l, 32, color, coords, ELEMENTS(coords)/2); +} + +static void poly33(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {7,349, 19,345, 25,339, 18,341, 23,333, 28,326, 23,326, 27,320, + 23,316, 25,311, 20,298, 15,277, 12,264, 9,249, 10,223, 3,248, + 5,261, 15,307, 17,326, 11,343 + }; + + init(l, 33, color, coords, ELEMENTS(coords)/2); +} + +static void poly34(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {11,226, 15,231, 25,236, 18,227 + }; + + init(l, 34, color, coords, ELEMENTS(coords)/2); +} + +static void poly35(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {13,214, 19,217, 32,227, 23,214, 16,208, 15,190, 24,148, + 31,121, 24,137, 14,170, 8,189 + }; + + init(l, 35, color, coords, ELEMENTS(coords)/2); +} + +static void poly36(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {202,254, 195,258, 199,260, 193,263, 197,263, 190,268, + 196,268, 191,273, 188,282, 200,272, 194,272, 201,266, + 197,265, 204,262, 200,258, 204,256 + }; + + init(l, 36, color, coords, ELEMENTS(coords)/2); +} + +static void poly37(struct lion *l) +{ + VGfloat color = 0x845433; + static const VGfloat coords[] = {151,213, 165,212, 179,225, 189,246, 187,262, 179,275, + 176,263, 177,247, 171,233, 163,230, 165,251, 157,264, + 146,298, 145,321, 133,326, 143,285, 154,260, 153,240 + }; + + init(l, 37, color, coords, ELEMENTS(coords)/2); +} + +static void poly38(struct lion *l) +{ + VGfloat color = 0x845433; + static const VGfloat coords[] = {91,132, 95,145, 97,154, 104,148, 107,155, 109,150, 111,158, + 115,152, 118,159, 120,153, 125,161, 126,155, 133,164, 132,154, + 137,163, 137,152, 142,163, 147,186, 152,192, 148,167, 141,143, + 124,145, 105,143 + }; + + init(l, 38, color, coords, ELEMENTS(coords)/2); +} + +static void poly39(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {31,57, 23,52, 26,51, 20,44, 23,42, 21,36, 22,29, 25,23, + 24,32, 30,43, 26,41, 30,50, 26,48 + }; + + init(l, 39, color, coords, ELEMENTS(coords)/2); +} + +static void poly40(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {147,21, 149,28, 155,21, 161,16, 167,14, 175,15, 173,11, 161,9 + }; + + init(l, 40, color, coords, ELEMENTS(coords)/2); +} + +static void poly41(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {181,39, 175,51, 169,57, 171,65, 165,68, 165,75, 160,76, + 162,91, 171,71, 180,51 + }; + + init(l, 41, color, coords, ELEMENTS(coords)/2); +} + +static void poly42(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {132,346, 139,348, 141,346, 142,341, 147,342, 143,355, 133,350 + }; + + init(l, 42, color, coords, ELEMENTS(coords)/2); +} + +static void poly43(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {146,355, 151,352, 155,348, 157,343, 160,349, 151,356, 147,357 + }; + + init(l, 43, color, coords, ELEMENTS(coords)/2); +} + +static void poly44(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {99,266, 100,281, 94,305, 86,322, 78,332, 72,346, 73,331, 91,291 + }; + + init(l, 44, color, coords, ELEMENTS(coords)/2); +} + +static void poly45(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {20,347, 32,342, 45,340, 54,345, 45,350, 42,353, 38,350, + 31,353, 29,356, 23,350, 19,353, 15,349 + }; + + init(l, 45, color, coords, ELEMENTS(coords)/2); +} + +static void poly46(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {78,344, 86,344, 92,349, 88,358, 84,352 + }; + + init(l, 46, color, coords, ELEMENTS(coords)/2); +} + +static void poly47(struct lion *l) +{ + VGfloat color = 0x9c826b; + static const VGfloat coords[] = {93,347, 104,344, 117,345, 124,354, 121,357, 116,351, + 112,351, 108,355, 102,351 + }; + + init(l, 47, color, coords, ELEMENTS(coords)/2); +} + +static void poly48(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {105,12, 111,18, 113,24, 113,29, 119,34, 116,23, 112,16 + }; + + init(l, 48, color, coords, ELEMENTS(coords)/2); +} + +static void poly49(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {122,27, 125,34, 127,43, 128,34, 125,29 + }; + + init(l, 49, color, coords, ELEMENTS(coords)/2); +} + +static void poly50(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {115,13, 122,19, 122,15, 113,10 + }; + + init(l, 50, color, coords, ELEMENTS(coords)/2); +} + +static void poly51(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {116,172, 107,182, 98,193, 98,183, 90,199, 89,189, 84,207, + 88,206, 87,215, 95,206, 93,219, 91,230, 98,216, 97,226, + 104,214, 112,209, 104,208, 113,202, 126,200, 139,207, 132,198, + 142,203, 134,192, 142,195, 134,187, 140,185, 130,181, 136,177, + 126,177, 125,171, 116,180 + }; + + init(l, 51, color, coords, ELEMENTS(coords)/2); +} + +static void poly52(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {74,220, 67,230, 67,221, 59,235, 63,233, 60,248, 70,232, 65,249, + 71,243, 67,256, 73,250, 69,262, 73,259, 71,267, 76,262, 72,271, + 78,270, 76,275, 82,274, 78,290, 86,279, 86,289, 92,274, 88,275, + 87,264, 82,270, 82,258, 77,257, 78,247, 73,246, 77,233, 72,236 + }; + + init(l, 52, color, coords, ELEMENTS(coords)/2); +} + +static void poly53(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {133,230, 147,242, 148,250, 145,254, 138,247, 129,246, 142,245, + 138,241, 128,237, 137,238 + }; + + init(l, 53, color, coords, ELEMENTS(coords)/2); +} + +static void poly54(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {133,261, 125,261, 116,263, 111,267, 125,265 + }; + + init(l, 54, color, coords, ELEMENTS(coords)/2); +} + +static void poly55(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {121,271, 109,273, 103,279, 99,305, 92,316, 85,327, 83,335, + 89,340, 97,341, 94,336, 101,336, 96,331, 103,330, 97,327, 108,325, + 99,322, 109,321, 100,318, 110,317, 105,314, 110,312, 107,310, 113,308, + 105,306, 114,303, 105,301, 115,298, 107,295, 115,294, 108,293, 117,291, + 109,289, 117,286, 109,286, 118,283, 112,281, 118,279, 114,278, + 119,276, 115,274 + }; + + init(l, 55, color, coords, ELEMENTS(coords)/2); +} + +static void poly56(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {79,364, 74,359, 74,353, 76,347, 80,351, 83,356, 82,360 + }; + + init(l, 56, color, coords, ELEMENTS(coords)/2); +} + +static void poly57(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {91,363, 93,356, 97,353, 103,355, 105,360, 103,366, 99,371, 94,368 + }; + + init(l, 57, color, coords, ELEMENTS(coords)/2); +} + +static void poly58(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {110,355, 114,353, 118,357, 117,363, 113,369, 111,362 + }; + + init(l, 58, color, coords, ELEMENTS(coords)/2); +} + +static void poly59(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {126,354, 123,358, 124,367, 126,369, 129,361, 129,357 + }; + + init(l, 59, color, coords, ELEMENTS(coords)/2); +} + +static void poly60(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {30,154, 24,166, 20,182, 23,194, 29,208, 37,218, 41,210, 41,223, + 46,214, 46,227, 52,216, 52,227, 61,216, 59,225, 68,213, 73,219, + 70,207, 77,212, 69,200, 77,202, 70,194, 78,197, 68,187, 76,182, + 64,182, 58,175, 58,185, 53,177, 50,186, 46,171, 44,182, 39,167, + 36,172, 36,162, 30,166 + }; + + init(l, 60, color, coords, ELEMENTS(coords)/2); +} + +static void poly61(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {44,130, 41,137, 45,136, 43,150, 48,142, 48,157, 53,150, + 52,164, 60,156, 61,169, 64,165, 66,175, 70,167, 74,176, + 77,168, 80,183, 85,172, 90,182, 93,174, 98,181, 99,173, + 104,175, 105,169, 114,168, 102,163, 95,157, 94,166, 90,154, + 87,162, 82,149, 75,159, 72,148, 68,155, 67,143, 62,148, 62,138, + 58,145, 56,133, 52,142, 52,128, 49,134, 47,125 + }; + + init(l, 61, color, coords, ELEMENTS(coords)/2); +} + +static void poly62(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {13,216, 19,219, 36,231, 22,223, 16,222, 22,227, 12,224, 13,220, 16,220 + }; + + init(l, 62, color, coords, ELEMENTS(coords)/2); +} + +static void poly63(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {10,231, 14,236, 25,239, 27,237, 19,234 + }; + + init(l, 63, color, coords, ELEMENTS(coords)/2); +} + +static void poly64(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {9,245, 14,242, 25,245, 13,245 + }; + + init(l, 64, color, coords, ELEMENTS(coords)/2); +} + +static void poly65(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {33,255, 26,253, 18,254, 25,256, 18,258, 27,260, 18,263, + 27,265, 19,267, 29,270, 21,272, 29,276, 21,278, 30,281, + 22,283, 31,287, 24,288, 32,292, 23,293, 34,298, 26,299, + 37,303, 32,305, 39,309, 33,309, 39,314, 34,314, 40,318, + 34,317, 40,321, 34,321, 41,326, 33,326, 40,330, 33,332, + 39,333, 33,337, 42,337, 54,341, 49,337, 52,335, 47,330, + 50,330, 45,325, 49,325, 45,321, 48,321, 45,316, 46,306, + 45,286, 43,274, 36,261 + }; + + init(l, 65, color, coords, ELEMENTS(coords)/2); +} + +static void poly66(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {7,358, 9,351, 14,351, 17,359, 11,364 + }; + + init(l, 66, color, coords, ELEMENTS(coords)/2); +} + +static void poly67(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {44,354, 49,351, 52,355, 49,361 + }; + + init(l, 67, color, coords, ELEMENTS(coords)/2); +} + +static void poly68(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {32,357, 37,353, 40,358, 36,361 + }; + + init(l, 68, color, coords, ELEMENTS(coords)/2); +} + +static void poly69(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {139,334, 145,330, 154,330, 158,334, 154,341, 152,348, + 145,350, 149,340, 147,336, 141,339, 139,345, 136,342, + 136,339 + }; + + init(l, 69, color, coords, ELEMENTS(coords)/2); +} + +static void poly70(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {208,259, 215,259, 212,255, 220,259, 224,263, 225,274, 224,283, + 220,292, 208,300, 206,308, 203,304, 199,315, 197,309, 195,318, + 193,313, 190,322, 190,316, 185,325, 182,318, 180,325, 172,321, + 178,320, 176,313, 186,312, 180,307, 188,307, 184,303, 191,302, + 186,299, 195,294, 187,290, 197,288, 192,286, 201,283, 194,280, + 203,277, 198,275, 207,271, 200,269, 209,265, 204,265, 212,262 + }; + + init(l, 70, color, coords, ELEMENTS(coords)/2); +} + +static void poly71(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {106,126, 106,131, 109,132, 111,134, 115,132, 115,135, 119,133, 118,137, + 123,137, 128,137, 133,134, 136,130, 136,127, 132,124, 118,128, 112,128, + 106,126, 106,126, 106,126 + }; + + init(l, 71, color, coords, ELEMENTS(coords)/2); +} + +static void poly72(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {107,114, 101,110, 98,102, 105,97, 111,98, 119,102, 121,108, 118,112, 113,115 + }; + + init(l, 72, color, coords, ELEMENTS(coords)/2); +} + +static void poly73(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {148,106, 145,110, 146,116, 150,118, 152,111, 151,107 + }; + + init(l, 73, color, coords, ELEMENTS(coords)/2); +} + +static void poly74(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {80,55, 70,52, 75,58, 63,57, 72,61, 57,61, 67,66, 57,67, 62,69, 54,71, + 61,73, 54,77, 63,78, 53,85, 60,84, 56,90, 69,84, 63,82, 75,76, 70,75, + 77,72, 72,71, 78,69, 72,66, 81,67, 78,64, 82,63, 80,60, 86,62 + }; + + init(l, 74, color, coords, ELEMENTS(coords)/2); +} + +static void poly75(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {87,56, 91,52, 96,50, 102,56, 98,56, 92,60 + }; + + init(l, 75, color, coords, ELEMENTS(coords)/2); +} + +static void poly76(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {85,68, 89,73, 98,76, 106,74, 96,73, 91,70 + }; + + init(l, 76, color, coords, ELEMENTS(coords)/2); +} + +static void poly77(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {115,57, 114,64, 111,64, 115,75, 122,81, 122,74, 126,79, + 126,74, 131,78, 130,72, 133,77, 131,68, 126,61, 119,57 + }; + + init(l, 77, color, coords, ELEMENTS(coords)/2); +} + +static void poly78(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {145,48, 143,53, 147,59, 151,59, 150,55 + }; + + init(l, 78, color, coords, ELEMENTS(coords)/2); +} + +static void poly79(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {26,22, 34,15, 43,10, 52,10, 59,16, 47,15, 32,22 + }; + + init(l, 79, color, coords, ELEMENTS(coords)/2); +} + +static void poly80(struct lion *l) +{ + VGfloat color = 0xffe5b2; + static const VGfloat coords[] = {160,19, 152,26, 149,34, 154,33, 152,30, 157,30, 155,26, 158,27, + 157,23, 161,23 + }; + + init(l, 80, color, coords, ELEMENTS(coords)/2); +} + +static void poly81(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {98,117, 105,122, 109,122, 105,117, 113,120, 121,120, 130,112, 128,108, + 123,103, 123,99, 128,101, 132,106, 135,109, 142,105, 142,101, 145,101, + 145,91, 148,101, 145,105, 136,112, 135,116, 143,124, 148,120, 150,122, + 142,128, 133,122, 121,125, 112,126, 103,125, 100,129, 96,124 + }; + + init(l, 81, color, coords, ELEMENTS(coords)/2); +} + +static void poly82(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {146,118, 152,118, 152,115, 149,115 + }; + + init(l, 82, color, coords, ELEMENTS(coords)/2); +} + +static void poly83(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {148,112, 154,111, 154,109, 149,109 + }; + + init(l, 83, color, coords, ELEMENTS(coords)/2); +} + +static void poly84(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {106,112, 108,115, 114,116, 118,114 + }; + + init(l, 84, color, coords, ELEMENTS(coords)/2); +} + +static void poly85(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {108,108, 111,110, 116,110, 119,108 + }; + + init(l, 85, color, coords, ELEMENTS(coords)/2); +} + +static void poly86(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {106,104, 109,105, 117,106, 115,104 + }; + + init(l, 86, color, coords, ELEMENTS(coords)/2); +} + +static void poly87(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {50,25, 41,26, 34,33, 39,43, 49,58, 36,51, 47,68, 55,69, 54,59, + 61,57, 74,46, 60,52, 67,42, 57,48, 61,40, 54,45, 60,36, 59,29, + 48,38, 52,30, 47,32 + }; + + init(l, 87, color, coords, ELEMENTS(coords)/2); +} + +static void poly88(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {147,34, 152,41, 155,49, 161,53, 157,47, 164,47, 158,43, 168,44, + 159,40, 164,37, 169,37, 164,33, 169,34, 165,28, 170,30, 170,25, + 173,29, 175,27, 176,32, 173,36, 175,39, 172,42, 172,46, 168,49, + 170,55, 162,57, 158,63, 155,58, 153,50, 149,46 + }; + + init(l, 88, color, coords, ELEMENTS(coords)/2); +} + +static void poly89(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {155,71, 159,80, 157,93, 157,102, 155,108, 150,101, 149,93, + 154,101, 152,91, 151,83, 155,79 + }; + + init(l, 89, color, coords, ELEMENTS(coords)/2); +} + +static void poly90(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {112,78, 115,81, 114,91, 112,87, 113,82 + }; + + init(l, 90, color, coords, ELEMENTS(coords)/2); +} + +static void poly91(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {78,28, 64,17, 58,11, 47,9, 36,10, 28,16, 21,26, 18,41, + 20,51, 23,61, 33,65, 28,68, 37,74, 36,81, 43,87, 48,90, + 43,100, 40,98, 39,90, 31,80, 30,72, 22,71, 17,61, 14,46, + 16,28, 23,17, 33,9, 45,6, 54,6, 65,12 + }; + + init(l, 91, color, coords, ELEMENTS(coords)/2); +} + +static void poly92(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {67,18, 76,9, 87,5, 101,2, 118,3, 135,8, 149,20, 149,26, + 144,19, 132,12, 121,9, 105,7, 89,8, 76,14, 70,20 + }; + + init(l, 92, color, coords, ELEMENTS(coords)/2); +} + +static void poly93(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {56,98, 48,106, 56,103, 47,112, 56,110, 52,115, 57,113, 52,121, 62,115, + 58,123, 65,119, 63,125, 69,121, 68,127, 74,125, 74,129, 79,128, 83,132, + 94,135, 93,129, 85,127, 81,122, 76,126, 75,121, 71,124, 71,117, 66,121, + 66,117, 62,117, 64,112, 60,113, 60,110, 57,111, 61,105, 57,107, 60,101, + 55,102 + }; + + init(l, 93, color, coords, ELEMENTS(coords)/2); +} + +static void poly94(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {101,132, 103,138, 106,134, 106,139, 112,136, 111,142, 115,139, + 114,143, 119,142, 125,145, 131,142, 135,138, 140,134, 140,129, + 143,135, 145,149, 150,171, 149,184, 145,165, 141,150, 136,147, + 132,151, 131,149, 126,152, 125,150, 121,152, 117,148, 111,152, + 110,148, 105,149, 104,145, 98,150, 96,138, 94,132, 94,130, 98,132 + }; + + init(l, 94, color, coords, ELEMENTS(coords)/2); +} + +static void poly95(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {41,94, 32,110, 23,132, 12,163, 6,190, 7,217, 5,236, + 3,247, 9,230, 12,211, 12,185, 18,160, 26,134, 35,110, + 43,99 + }; + + init(l, 95, color, coords, ELEMENTS(coords)/2); +} + +static void poly96(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {32,246, 41,250, 50,257, 52,267, 53,295, 53,323, 59,350, + 54,363, 51,365, 44,366, 42,360, 40,372, 54,372, 59,366, + 62,353, 71,352, 75,335, 73,330, 66,318, 68,302, 64,294, + 67,288, 63,286, 63,279, 59,275, 58,267, 56,262, 50,247, + 42,235, 44,246, 32,236, 35,244 + }; + + init(l, 96, color, coords, ELEMENTS(coords)/2); +} + +static void poly97(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {134,324, 146,320, 159,322, 173,327, 179,337, 179,349, + 172,355, 158,357, 170,350, 174,343, 170,333, 163,328, 152,326, + 134,329 + }; + + init(l, 97, color, coords, ELEMENTS(coords)/2); +} + +static void poly98(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {173,339, 183,334, 184,338, 191,329, 194,332, 199,323, 202,325, + 206,318, 209,320, 213,309, 221,303, 228,296, 232,289, 234,279, + 233,269, 230,262, 225,256, 219,253, 208,252, 198,252, 210,249, + 223,250, 232,257, 237,265, 238,277, 238,291, 232,305, 221,323, + 218,335, 212,342, 200,349, 178,348 + }; + + init(l, 98, color, coords, ELEMENTS(coords)/2); +} + +static void poly99(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {165,296, 158,301, 156,310, 156,323, 162,324, 159,318, + 162,308, 162,304 + }; + + init(l, 99, color, coords, ELEMENTS(coords)/2); +} + +static void poly100(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {99,252, 105,244, 107,234, 115,228, 121,228, 131,235, + 122,233, 113,235, 109,246, 121,239, 133,243, 121,243, + 110,251 + }; + + init(l, 100, color, coords, ELEMENTS(coords)/2); +} + +static void poly101(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {117,252, 124,247, 134,249, 136,253, 126,252 + }; + + init(l, 101, color, coords, ELEMENTS(coords)/2); +} + +static void poly102(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {117,218, 132,224, 144,233, 140,225, 132,219, 117,218, + 117,218, 117,218 + }; + + init(l, 102, color, coords, ELEMENTS(coords)/2); +} + +static void poly103(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {122,212, 134,214, 143,221, 141,213, 132,210 + }; + + init(l, 103, color, coords, ELEMENTS(coords)/2); +} + +static void poly104(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {69,352, 70,363, 76,373, 86,378, 97,379, 108,379, 120,377, + 128,378, 132,373, 135,361, 133,358, 132,366, 127,375, 121,374, + 121,362, 119,367, 117,374, 110,376, 110,362, 107,357, 106,371, + 104,375, 97,376, 90,375, 90,368, 86,362, 83,364, 86,369, 85,373, + 78,370, 73,362, 71,351 + }; + + init(l, 104, color, coords, ELEMENTS(coords)/2); +} + +static void poly105(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {100,360, 96,363, 99,369, 102,364 + }; + + init(l, 105, color, coords, ELEMENTS(coords)/2); +} + +static void poly106(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {115,360, 112,363, 114,369, 117,364 + }; + + init(l, 106, color, coords, ELEMENTS(coords)/2); +} + +static void poly107(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {127,362, 125,364, 126,369, 128,365 + }; + + init(l, 107, color, coords, ELEMENTS(coords)/2); +} + +static void poly108(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {5,255, 7,276, 11,304, 15,320, 13,334, 6,348, 2,353, 0,363, + 5,372, 12,374, 25,372, 38,372, 44,369, 42,367, 36,368, 31,369, + 30,360, 27,368, 20,370, 16,361, 15,368, 10,369, 3,366, 3,359, 6,352, + 11,348, 17,331, 19,316, 12,291, 9,274 + }; + + init(l, 108, color, coords, ELEMENTS(coords)/2); +} + +static void poly109(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {10,358, 7,362, 10,366, 11,362 + }; + + init(l, 109, color, coords, ELEMENTS(coords)/2); +} + +static void poly110(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {25,357, 22,360, 24,366, 27,360 + }; + + init(l, 110, color, coords, ELEMENTS(coords)/2); +} + +static void poly111(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {37,357, 34,361, 36,365, 38,361 + }; + + init(l, 111, color, coords, ELEMENTS(coords)/2); +} + +static void poly112(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {49,356, 46,359, 47,364, 50,360 + }; + + init(l, 112, color, coords, ELEMENTS(coords)/2); +} + +static void poly113(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {130,101, 132,102, 135,101, 139,102, 143,103, + 142,101, 137,100, 133,100 + }; + + init(l, 113, color, coords, ELEMENTS(coords)/2); +} + +static void poly114(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {106,48, 105,52, 108,56, 109,52 + }; + + init(l, 114, color, coords, ELEMENTS(coords)/2); +} + +static void poly115(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {139,52, 139,56, 140,60, 142,58, 141,56 + }; + + init(l, 115, color, coords, ELEMENTS(coords)/2); +} + +static void poly116(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {25,349, 29,351, 30,355, 33,350, 37,348, 42,351, 45,347, + 49,345, 44,343, 36,345 + }; + + init(l, 116, color, coords, ELEMENTS(coords)/2); +} + +static void poly117(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {98,347, 105,351, 107,354, 109,349, 115,349, 120,353, 118,349, + 113,346, 104,346 + }; + + init(l, 117, color, coords, ELEMENTS(coords)/2); +} + +static void poly118(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {83,348, 87,352, 87,357, 89,351, 87,348 + }; + + init(l, 118, color, coords, ELEMENTS(coords)/2); +} + +static void poly119(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {155,107, 163,107, 170,107, 186,108, 175,109, 155,109 + }; + + init(l, 119, color, coords, ELEMENTS(coords)/2); +} + +static void poly120(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {153,114, 162,113, 175,112, 192,114, 173,114, 154,115 + }; + + init(l, 120, color, coords, ELEMENTS(coords)/2); +} + +static void poly121(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {152,118, 164,120, 180,123, 197,129, 169,123, 151,120 + }; + + init(l, 121, color, coords, ELEMENTS(coords)/2); +} + +static void poly122(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {68,109, 87,106, 107,106, 106,108, 88,108 + }; + + init(l, 122, color, coords, ELEMENTS(coords)/2); +} + +static void poly123(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {105,111, 95,112, 79,114, 71,116, 85,115, 102,113 + }; + + init(l, 123, color, coords, ELEMENTS(coords)/2); +} + +static void poly124(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {108,101, 98,99, 87,99, 78,99, 93,100, 105,102 + }; + + init(l, 124, color, coords, ELEMENTS(coords)/2); +} + +static void poly125(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {85,63, 91,63, 97,60, 104,60, 108,62, 111,69, 112,75, + 110,74, 108,71, 103,73, 106,69, 105,65, 103,64, 103,67, + 102,70, 99,70, 97,66, 94,67, 97,72, 88,67, 84,66 + }; + + init(l, 125, color, coords, ELEMENTS(coords)/2); +} + +static void poly126(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {140,74, 141,66, 144,61, 150,61, 156,62, 153,70, 150,73, + 152,65, 150,65, 151,68, 149,71, 146,71, 144,66, 143,70, + 143,74 + }; + + init(l, 126, color, coords, ELEMENTS(coords)/2); +} + +static void poly127(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {146,20, 156,11, 163,9, 172,9, 178,14, 182,18, 184,32, 182,42, + 182,52, 177,58, 176,67, 171,76, 165,90, 157,105, 160,92, 164,85, + 168,78, 167,73, 173,66, 172,62, 175,59, 174,55, 177,53, 180,46, + 181,29, 179,21, 173,13, 166,11, 159,13, 153,18, 148,23 + }; + + init(l, 127, color, coords, ELEMENTS(coords)/2); +} + +static void poly128(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {150,187, 148,211, 150,233, 153,247, 148,267, 135,283, 125,299, + 136,292, 131,313, 122,328, 122,345, 129,352, 133,359, 133,367, + 137,359, 148,356, 140,350, 131,347, 129,340, 132,332, 140,328, + 137,322, 140,304, 154,265, 157,244, 155,223, 161,220, 175,229, + 186,247, 185,260, 176,275, 178,287, 185,277, 188,261, 196,253, + 189,236, 174,213 + }; + + init(l, 128, color, coords, ELEMENTS(coords)/2); +} + +static void poly129(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {147,338, 142,341, 143,345, 141,354, 147,343 + }; + + init(l, 129, color, coords, ELEMENTS(coords)/2); +} + +static void poly130(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {157,342, 156,349, 150,356, 157,353, 163,346, 162,342 + }; + + init(l, 130, color, coords, ELEMENTS(coords)/2); +} + +static void poly131(struct lion *l) +{ + VGfloat color = 0x000000; + static const VGfloat coords[] = {99,265, 96,284, 92,299, 73,339, 73,333, 87,300 + }; + + init(l, 131, color, coords, ELEMENTS(coords)/2); +} + + +struct lion * lion_create(void) +{ + struct lion *l = calloc(1, sizeof(struct lion)); + + poly0(l); + poly1(l); + poly2(l); + poly3(l); + poly4(l); + poly5(l); + poly6(l); + poly7(l); + poly8(l); + poly9(l); + + poly10(l); + poly11(l); + poly12(l); + poly13(l); + poly14(l); + poly15(l); + poly16(l); + poly17(l); + poly18(l); + poly19(l); + + poly20(l); + poly21(l); + poly22(l); + poly23(l); + poly24(l); + poly25(l); + poly26(l); + poly27(l); + poly28(l); + poly29(l); + + poly30(l); + poly31(l); + poly32(l); + poly33(l); + poly34(l); + poly35(l); + poly36(l); + poly37(l); + poly38(l); + poly39(l); + + poly40(l); + poly41(l); + poly42(l); + poly43(l); + poly44(l); + poly45(l); + poly46(l); + poly47(l); + poly48(l); + poly49(l); + + poly50(l); + poly51(l); + poly52(l); + poly53(l); + poly54(l); + poly55(l); + poly56(l); + poly57(l); + poly58(l); + poly59(l); + + poly60(l); + poly61(l); + poly62(l); + poly63(l); + poly64(l); + poly65(l); + poly66(l); + poly67(l); + poly68(l); + poly69(l); + + poly70(l); + poly71(l); + poly72(l); + poly73(l); + poly74(l); + poly75(l); + poly76(l); + poly77(l); + poly78(l); + poly79(l); + + poly80(l); + poly81(l); + poly82(l); + poly83(l); + poly84(l); + poly85(l); + poly86(l); + poly87(l); + poly88(l); + poly89(l); + + poly90(l); + poly91(l); + poly92(l); + poly93(l); + poly94(l); + poly95(l); + poly96(l); + poly97(l); + poly98(l); + poly99(l); + + poly100(l); + poly101(l); + poly102(l); + poly103(l); + poly104(l); + poly105(l); + poly106(l); + poly107(l); + poly108(l); + poly109(l); + + poly110(l); + poly111(l); + poly112(l); + poly113(l); + poly114(l); + poly115(l); + poly116(l); + poly117(l); + poly118(l); + poly119(l); + + poly120(l); + poly121(l); + poly122(l); + poly123(l); + poly124(l); + poly125(l); + poly126(l); + poly127(l); + poly128(l); + poly129(l); + + poly130(l); + poly131(l); + + return l; +} + +void lion_render(struct lion *l) +{ + VGint i; + + for (i = 0; i < LION_SIZE; ++i) { + vgSetPaint(l->fills[i], VG_FILL_PATH); + vgDrawPath(l->paths[i], VG_FILL_PATH); + } +} + +void lion_destroy(struct lion *l) +{ + VGint i; + for (i = 0; i < LION_SIZE; ++i) { + vgDestroyPaint(l->fills[i]); + vgDestroyPath(l->paths[i]); + } + free(l); +} diff --git a/progs/egl/openvg/lion-render.h b/progs/egl/openvg/lion-render.h new file mode 100644 index 00000000000..c4c020b7edd --- /dev/null +++ b/progs/egl/openvg/lion-render.h @@ -0,0 +1,16 @@ +#ifndef LION_RENDER_H +#define LION_RENDER_H + +#include <VG/openvg.h> + +#define LION_SIZE 132 +struct lion { + VGPath paths[LION_SIZE]; + VGPaint fills[LION_SIZE]; +}; + +struct lion *lion_create(void); +void lion_render(struct lion *l); +void lion_destroy(struct lion *l); + +#endif diff --git a/progs/egl/openvg/lion.c b/progs/egl/openvg/lion.c new file mode 100644 index 00000000000..c5dba4fcead --- /dev/null +++ b/progs/egl/openvg/lion.c @@ -0,0 +1,65 @@ +#include <VG/openvg.h> +#include <EGL/egl.h> + +#include "lion-render.h" +#include "eglut.h" + +static VGint width, height; +struct lion *lion = 0; +VGfloat angle = 0; + +static void +draw(void) +{ + vgClear(0, 0, width, height); + + vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); + vgLoadIdentity(); + vgTranslate(width/2, height/2); + vgRotate(angle); + vgTranslate(-width/2, -height/2); + + lion_render(lion); + + ++angle; + eglutPostRedisplay(); +} + + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ + width = w; + height = h; +} + + +static void +init(void) +{ + float clear_color[4] = {1.0, 1.0, 1.0, 1.0}; + vgSetfv(VG_CLEAR_COLOR, 4, clear_color); + + lion = lion_create(); +} + + +int +main(int argc, char *argv[]) +{ + eglutInitWindowSize(350, 450); + eglutInitAPIMask(EGLUT_OPENVG_BIT); + eglutInit(argc, argv); + + eglutCreateWindow("Lion Example"); + + eglutReshapeFunc(reshape); + eglutDisplayFunc(draw); + + init(); + + eglutMainLoop(); + + return 0; +} diff --git a/progs/egl/openvg/sp.c b/progs/egl/openvg/sp.c new file mode 100644 index 00000000000..a20c0a3b4ef --- /dev/null +++ b/progs/egl/openvg/sp.c @@ -0,0 +1,522 @@ +#include <VG/openvg.h> +#include <VG/vgu.h> +#include <math.h> +#include <string.h> + +#include "eglut.h" + +#define ELEMENTS(x) (sizeof(x)/sizeof((x)[0])) + +struct object { + VGPath path; + VGPaint fill; + VGPaint stroke; + VGint draw_mode; + VGfloat matrix[9]; + VGfloat stroke_width; +}; + +struct character { + struct object objects[32]; + VGint num_objects; +}; +VGfloat identity_matrix[] = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + +struct character cartman; + +static void add_object_fill(const VGubyte *segments, VGint num_segments, + const VGfloat *coords, + VGuint color) +{ + struct object object; + + object.path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, + 1, 0, 0, 0, VG_PATH_CAPABILITY_ALL); + vgAppendPathData(object.path, num_segments, segments, coords); + + object.fill = vgCreatePaint(); + vgSetColor(object.fill, color); + memcpy(object.matrix, identity_matrix, 9 * sizeof(VGfloat)); + object.draw_mode = VG_FILL_PATH; + + cartman.objects[cartman.num_objects] = object; + ++cartman.num_objects; +} + + +static void add_object_stroke(const VGubyte *segments, VGint num_segments, + const VGfloat *coords, + VGuint color, VGfloat width) +{ + struct object object; + + object.path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, + 1, 0, 0, 0, VG_PATH_CAPABILITY_ALL); + vgAppendPathData(object.path, num_segments, segments, coords); + + object.stroke = vgCreatePaint(); + vgSetColor(object.stroke, color); + memcpy(object.matrix, identity_matrix, 9 * sizeof(VGfloat)); + object.draw_mode = VG_STROKE_PATH; + object.stroke_width = width; + + cartman.objects[cartman.num_objects] = object; + ++cartman.num_objects; +} + + +static void add_object_fillm(const VGubyte *segments, VGint num_segments, + const VGfloat *coords, + VGuint color, + VGfloat *matrix) +{ + struct object object; + + object.path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, + 1, 0, 0, 0, VG_PATH_CAPABILITY_ALL); + vgAppendPathData(object.path, num_segments, segments, coords); + + object.fill = vgCreatePaint(); + vgSetColor(object.fill, color); + memcpy(object.matrix, matrix, 9 * sizeof(VGfloat)); + object.draw_mode = VG_FILL_PATH; + + cartman.objects[cartman.num_objects] = object; + ++cartman.num_objects; +} + + +static void add_object_m(const VGubyte *segments, VGint num_segments, + const VGfloat *coords, + VGuint fill_color, + VGuint stroke_color, VGfloat stroke_width, + VGfloat *matrix) +{ + struct object object; + + object.path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, + 1, 0, 0, 0, VG_PATH_CAPABILITY_ALL); + vgAppendPathData(object.path, num_segments, segments, coords); + memcpy(object.matrix, matrix, 9 * sizeof(VGfloat)); + + object.fill = vgCreatePaint(); + vgSetColor(object.fill, fill_color); + object.draw_mode = VG_FILL_PATH | VG_STROKE_PATH; + + object.stroke = vgCreatePaint(); + vgSetColor(object.stroke, stroke_color); + object.stroke_width = stroke_width; + + cartman.objects[cartman.num_objects] = object; + ++cartman.num_objects; +} + +static void init_character() +{ + { + const VGubyte segments[] = {VG_MOVE_TO_ABS, + VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, + VG_CLOSE_PATH}; + const VGfloat coords[] = {181.83267, 102.60408, + 181.83267,102.60408, 185.53793,114.5749, 186.5355,115.00243, + 187.53306,115.42996, 286.0073,115.00243, 286.0073,115.00243, + 286.0073,115.00243, 292.70526,103.45914, 290.85263,101.03648, + 289.00001,98.61381, 181.54765,102.31906, 181.83267,102.60408 + }; + VGuint color = 0x7c4e32ff; + add_object_fill(segments, ELEMENTS(segments), + coords, color); + } + { + const VGubyte segments[] = { + VG_MOVE_TO_ABS, + VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, + VG_LINE_TO_ABS, + VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, + VG_CLOSE_PATH + }; + const VGfloat coords[] = {188.62208,50.604156, + 188.62208,50.604156, 176.73127,60.479579, 170.68509,69.548844, + 164.63892,78.618109, 175.11895,79.827344, 175.11895,79.827344, + 176.52973,98.368952, + 176.52973,98.368952, 189.83131,110.05823, 208.97754,110.25976, + 228.12377,110.46131, 244.24691,111.67054, 247.06846,110.25976, + 249.89,108.849, 258.95927,106.8336, 260.16851,105.01975, + 261.37774,103.2059, 296.84865,106.43053, 297.05019,91.919698, + 297.25172,77.408874, 306.11945,64.308824, 282.13628,51.611853, + 258.15311,38.914882, 189.2267,49.999539, 188.62208,50.604156 + }; + + VGuint color = 0xe30000ff; + add_object_fill(segments, ELEMENTS(segments), + coords, color); + } + { + const VGubyte segments[] = { + VG_MOVE_TO_ABS, + VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, + VG_CLOSE_PATH + }; + const VGfloat coords[] = { + 68.25, 78.875, + 68.25,93.296, 54.642,105, 37.875,105, + 21.108,105, 7.5,93.296, 7.5,78.875, + 7.5,64.454, 21.108,52.75, 37.875,52.75, + 54.642,52.75, 68.25,64.454, 68.25,78.875 + }; + + VGuint color = 0xffe1c4ff; + VGfloat matrix[] = { + 1.6529, 0, 0, + 0, 1.582037, 0, + 172.9649,-90.0116, 1 + }; + add_object_fillm(segments, ELEMENTS(segments), + coords, color, matrix); + } + { + const VGubyte segments[] = { + VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CLOSE_PATH + }; + const VGfloat coords[] = { + 170.14687,71.536958, + 173.53626,68.814326, 176.70232,68.971782, 180.55009,71.679467, + 184.39785,74.387153, 199.19294,80.036105, 191.52334,86.500482, + 189.02942,88.6025, 183.97032,85.787933, 180.26507,86.928011, + 178.8737,87.356121, 174.71827,89.783259, 171.8028,87.494856, + 166.95426,83.689139, 163.51779,76.861986, 170.14687,71.536958 + }; + + VGuint color = 0xfff200ff; + add_object_fill(segments, ELEMENTS(segments), + coords, color); + } + { + const VGubyte segments[] = { + VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, VG_CLOSE_PATH + }; + const VGfloat coords[] = { + 299.83075,66.834136, + 299.83075,66.834136, 287.85993,64.69649, 284.15467,72.962055, + 280.44942,81.227621, 280.1644,78.234916, 280.1644,79.374994, + 280.1644,80.515072, 278.16927,84.077816, 284.86722,83.792796, + 291.56518,83.507777, 291.99271,86.785501, 294.84291,86.642991, + 297.6931,86.500482, 303.536,85.645423, 303.67851,80.657582, + 303.82102,75.66974, 302.68094,65.551548, 299.83075,66.834136 + }; + + VGuint color = 0xfff200ff; + add_object_fill(segments, ELEMENTS(segments), + coords, color); + } + { + const VGubyte segments[] = { + VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS + }; + const VGfloat coords[] = { + 240.83171,75.81225, + 240.83171,75.81225, 241.54426,88.495618, 242.25681,91.488323, + 242.96936,94.481028, 240.6892,108.01945, 240.83171,110.01459, + 240.97422,112.00973, 240.97422,111.01216, 240.97422,111.01216 + }; + VGuint color = 0x000000ff; + VGfloat swidth = 1.14007807; + add_object_stroke(segments, ELEMENTS(segments), coords, color, swidth); + } + { + const VGubyte segments[] = { + VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, VG_LINE_TO_ABS, VG_LINE_TO_ABS, VG_CLOSE_PATH + }; + const VGfloat coords[] = { + 83.375, 95.5, + 83.375,96.121, 83.067,96.625, 82.6875,96.625, + 82.308,96.625, 82,96.121, 82,95.5, + 82,94.879, 82.308,94.375, 82.6875,94.375, + 83.066677,94.375, 83.374492,94.878024, 83.374999,95.498494, + 82.6875,95.5, + 83.375,95.5 + }; + VGuint fill_color = 0x000000ff; + VGuint stroke_color = 0x000000ff; + VGfloat swidth = 0.60000002; + VGfloat matrix1[] = { + 1.140078, 0, 0, + 0, 1.140078, 0, + 145.4927, -15.10897, 1 + }; + VGfloat matrix2[] = { + 1.140078,0, 0, + 0,1.140078, 0, + 144.2814,-27.93485, 1 + }; + VGfloat matrix3[] = { + 1.140078,0, 0, + 0,1.140078, 0, + 144.1388,-3.70819, 1 + }; + add_object_m(segments, ELEMENTS(segments), coords, + fill_color, stroke_color, swidth, matrix1); + add_object_m(segments, ELEMENTS(segments), coords, + fill_color, stroke_color, swidth, matrix2); + add_object_m(segments, ELEMENTS(segments), coords, + fill_color, stroke_color, swidth, matrix3); + } + { + const VGubyte segments[] = { + VG_MOVE_TO_ABS, + VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, + VG_LINE_TO_ABS, VG_CLOSE_PATH + }; + const VGfloat coords[] = { + 179.41001,115.28745, + 179.41001,115.28745, 207.48443,109.30204, 236.84144,115.14494, + 236.84144,115.14494, 274.74903,109.87208, 291.8502,115.42996, + 179.41001,115.28745 + }; + + VGuint color = 0x000000ff; + add_object_fill(segments, ELEMENTS(segments), + coords, color); + } + { + const VGubyte segments[] = { + VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, VG_LINE_TO_ABS, VG_LINE_TO_ABS, VG_CLOSE_PATH + }; + const VGfloat coords[] = { + 83.792156,68.157364, + 83.792156,69.669865, 82.72301,70.897403, 81.40567,70.897403, + 80.08833,70.897403, 79.019185,69.669865, 79.019185,68.157364, + 79.019185,66.644862, 80.08833,65.417325, 81.40567,65.417325, + 82.721887,65.417325, 83.790391,66.642485, 83.792153,68.153696, + 81.40567,68.157364, + 83.792156,68.157364 + }; + VGuint fill_color = 0x000000ff; + VGuint stroke_color = 0x000000ff; + VGfloat swidth = 0.52891117; + VGfloat matrix1[] = { + 1.140078,0, 0, + 0,1.140078, 0, + 145.2489,-15.58714, 1 + }; + add_object_m(segments, ELEMENTS(segments), coords, + fill_color, stroke_color, swidth, matrix1); + } + { + const VGubyte segments[] = { + VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS + }; + const VGfloat coords[] = { + 232.28113,66.976646, + 232.28113,66.976646, 237.98152,70.539389, 245.39202,66.549116 + }; + VGuint color = 0x000000ff; + VGfloat swidth = 0.60299999; + add_object_stroke(segments, ELEMENTS(segments), coords, color, swidth); + } + { + const VGubyte segments[] = { + VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CLOSE_PATH + }; + const VGfloat coords[] = { + 185.96908,30.061986, + 185.96908,30.061986, 187.76995,14.508377, 203.23909,3.7427917, + 209.95028,-0.92779696, 219.37764,-4.9841866, 232.1078,-6.00046, + 246.13578,-7.1203411, 256.92106,-2.8560739, 264.81774,1.9451947, + 280.60485,11.543934, 284.31582,25.937274, 284.08015,26.526452, + 283.7266,27.410336, 240.83461,1.9346323, 185.96908,30.061986 + }; + VGuint color = 0x8ed8f8ff; + add_object_fill(segments, ELEMENTS(segments), coords, color); + } + { + const VGubyte segments[] = { + VG_MOVE_TO_ABS, VG_LINE_TO_ABS, VG_CUBIC_TO_ABS, + VG_LINE_TO_ABS, VG_CUBIC_TO_ABS, VG_CLOSE_PATH + }; + const VGfloat coords[] = { + 185.39542,32.061757, + 185.82295,29.211562, + 185.82295,29.211562, 234.70379,2.277219, 284.01217,25.078779, + 284.86722,27.643954, + 284.86722,27.643954, 236.69893,4.5573746, 185.39542,32.061757 + }; + VGuint color = 0xfff200ff; + add_object_fill(segments, ELEMENTS(segments), coords, color); + } + + { + const VGubyte segments[] = { + VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, VG_CLOSE_PATH + }; + const VGfloat coords[] = { + 219.74027,-5.917093, + 220.49206,-8.44929, 225.15564,-10.904934, 230.21473,-11.189954, + 235.27383,-11.474973, 243.27521,-13.287236, 249.21385,-5.724198, + 249.89961,-4.850868, 249.28247,-4.332166, 248.62298,-3.971398, + 247.79117,-3.516361, 247.13703,-3.392737, 246.16222,-3.408047, + 243.63973,-3.447664, 242.54183,-3.850701, 242.54183,-3.850701, + 242.54183,-3.850701, 238.78367,-1.737343, 236.20014,-3.565682, + 233.88436,-5.204544, 234.27626,-4.56325, 234.27626,-4.56325, + 234.27626,-4.56325, 232.33303,-2.975658, 230.85603,-2.995643, + 228.59433,-3.025282, 227.73672,-4.501857, 227.21966,-4.93027, + 226.76318,-4.932008, 226.50948,-4.491995, 226.50948,-4.491995, + 226.50948,-4.491995, 224.53199,-2.085883, 222.51431,-2.467064, + 221.48814,-2.66093, 218.91968,-3.15318, 219.74027,-5.917093 + }; + VGuint color = 0xfff200ff; + add_object_fill(segments, ELEMENTS(segments), coords, color); + } + { + const VGubyte segments[] = { + VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CLOSE_PATH + }; + const VGfloat coords[] = { + 178.97347,166.06432, + 178.97347,181.2154, 168.0245,193.51193, 154.53381,193.51193, + 141.04312,193.51193, 130.09416,181.2154, 130.09416,166.06432, + 130.09416,150.91323, 141.04312,138.6167, 154.53381,138.6167, + 168.0245,138.6167, 178.97347,150.91323, 178.97347,166.06432 + }; + VGuint color = 0xffffffff; + VGfloat matrix1[] = { + 0.466614,-0.23492, 0, + 0.108683,0.436638, 0, + 134.5504,-0.901632, 1 + }; + VGfloat matrix2[] = { + -0.466614,-0.23492, 0, + -0.108683,0.436638, 0, + 338.4496,-0.512182, 1 + }; + add_object_fillm(segments, ELEMENTS(segments), coords, color, matrix1); + add_object_fillm(segments, ELEMENTS(segments), coords, color, matrix2); + } + { + const VGubyte segments[] = { + VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, + VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS, VG_CLOSE_PATH + }; + const VGfloat coords[] = { + 123.82758,165.06168, + 123.82758,166.79125, 122.59232,168.19497, 121.07029,168.19497, + 119.54826,168.19497, 118.313,166.79125, 118.313,165.06168, + 118.313,163.3321, 119.54826,161.92839, 121.07029,161.92839, + 122.59232,161.92839, 123.82758,163.3321, 123.82758,165.06168 + }; + VGuint color = 0x000000ff; + VGfloat matrix1[] = { + 0.525719,0, 0, + 0,0.479931, 0, + 178.9702,-43.3532, 1 + }; + VGfloat matrix2[] = { + 0.525719,0, 0, + 0,0.479931, 0, + 165.258,-43.46162, 1 + }; + add_object_fillm(segments, ELEMENTS(segments), coords, color, matrix1); + add_object_fillm(segments, ELEMENTS(segments), coords, color, matrix2); + } + { + const VGubyte segments[] = { + VG_MOVE_TO_ABS, VG_CUBIC_TO_ABS, VG_CUBIC_TO_ABS + }; + const VGfloat coords[] = { + 197.25,54.5, + 197.25,54.5, 211.75,71.5, 229.25,71.5, + 246.75,71.5, 261.74147,71.132714, 277.75,50.75 + }; + VGuint color = 0x000000ff; + VGfloat swidth = 0.60299999; + add_object_stroke(segments, ELEMENTS(segments), coords, color, swidth); + } +} + + +static void +init(void) +{ + float clear_color[4] = {1.0, 1.0, 1.0, 1.0}; + vgSetfv(VG_CLEAR_COLOR, 4, clear_color); + + init_character(); +} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ +} + +static void +draw(void) +{ + VGint i; + VGfloat save_matrix[9]; + + vgClear(0, 0, eglutGetWindowWidth(), eglutGetWindowHeight()); + + vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); + vgLoadIdentity(); + vgScale(2, 2); + vgTranslate(160, 60); + vgRotate(180); + vgTranslate(-160, -100); + vgGetMatrix(save_matrix); + for (i = 0; i < cartman.num_objects; ++i) { + struct object object = cartman.objects[i]; + if ((object.draw_mode & VG_STROKE_PATH)) { + vgSetf(VG_STROKE_LINE_WIDTH, object.stroke_width); + vgSetPaint(object.stroke, VG_STROKE_PATH); + } + if ((object.draw_mode & VG_FILL_PATH)) + vgSetPaint(object.fill, VG_FILL_PATH); + vgMultMatrix(object.matrix); + vgDrawPath(object.path, object.draw_mode); + vgLoadMatrix(save_matrix); + } + + vgFlush(); +} + + +int main(int argc, char **argv) +{ + eglutInitWindowSize(400, 400); + eglutInitAPIMask(EGLUT_OPENVG_BIT); + eglutInit(argc, argv); + + eglutCreateWindow("sp"); + + eglutReshapeFunc(reshape); + eglutDisplayFunc(draw); + + init(); + + eglutMainLoop(); + + return 0; +} diff --git a/progs/egl/openvg/trivial/Makefile b/progs/egl/openvg/trivial/Makefile new file mode 100644 index 00000000000..8f6d7abe89a --- /dev/null +++ b/progs/egl/openvg/trivial/Makefile @@ -0,0 +1,128 @@ +# progs/egl/openvg/trivial/Makefile +# These programs aren't intended to be included with the normal distro. +# They're not too interesting but they're good for testing. + +TOP = ../../../.. +include $(TOP)/configs/current + +INCLUDES = -I. -I$(TOP)/include +LIBS=-L$(TOP)/$(LIB_DIR) -lm -lX11 -lEGL -lOpenVG -lpthread +CFLAGS += $(INCLUDES) + +HEADERS=eglcommon.h + +PROGRAMS = \ + arc \ + cap \ + clear \ + coord \ + dash \ + ellipse \ + filter \ + gradorigin \ + lineto \ + lingrad \ + lookup \ + mask4 \ + mask \ + path3 \ + radialgrad \ + readpixels \ + roundedrect \ + star-nonzero \ + star-oddeven \ + stroke2 \ + stroke \ + vguarc + + +.c.o: + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ + + + +default: $(PROGRAMS) + + +arc: arc.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +cap: cap.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +clear: clear.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +coord: coord.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +dash: dash.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +ellipse: ellipse.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +filter: filter.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +gradorigin: gradorigin.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +image: image.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +lineto: lineto.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +lingrad: lingrad.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +lookup: lookup.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +mask: mask.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +mask4: mask4.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +path3: path3.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +pattern: pattern.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +radialgrad: radialgrad.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +readpixels: readpixels.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +roundedrect: roundedrect.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +star-nonzero: star-nonzero.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +star-oddeven: star-oddeven.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +stroke: stroke.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +stroke2: stroke2.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + +vguarc: vguarc.c eglcommon.o + $(CC) $(CFLAGS) $^ $(LIBS) $(APP_LIB_DEPS) -o $@ + + + +eglcommon.o: eglcommon.c $(HEADERS) + $(CC) -c $(CFLAGS) eglcommon.c + + +clean: + rm -f *.o *~ + rm -f *.so + rm -f $(PROGRAMS) diff --git a/progs/egl/openvg/trivial/arc.c b/progs/egl/openvg/trivial/arc.c new file mode 100644 index 00000000000..db686bea6b0 --- /dev/null +++ b/progs/egl/openvg/trivial/arc.c @@ -0,0 +1,139 @@ +#include "eglcommon.h" + +#include <VG/openvg.h> +#include <math.h> + +const VGfloat clear_color[4] = {1.0, 1.0, 1.0, 1.0}; +const VGfloat color[4] = {1.0, 1.0, 1.0, 0.5}; + +VGPath vgPath; + +static void ellipse(VGPath vgPath, VGfloat rx, VGfloat ry, VGfloat angle) +{ + static const VGubyte cmd[] = + { VG_MOVE_TO_ABS, VG_SCCWARC_TO_REL, VG_SCCWARC_TO_REL, VG_CLOSE_PATH }; + + VGfloat val[12]; + VGfloat c = cos(angle) * rx; + VGfloat s = sin(angle) * rx; + + val[0] = c; + val[1] = s; + val[2] = rx; + val[3] = ry; + val[4] = angle; + val[5] = -2.0f * c; + val[6] = -2.0f * s; + val[7] = rx; + val[8] = ry; + val[9] = angle; + val[10] = 2.0f * c; + val[11] = 2.0f * s; + + vgClearPath(vgPath, VG_PATH_CAPABILITY_ALL); + vgAppendPathData(vgPath, sizeof(cmd), cmd, val); + vgDrawPath(vgPath, VG_FILL_PATH | VG_STROKE_PATH); +} + +static void +init(void) +{ + VGPaint vgPaint; + + vgSetfv(VG_CLEAR_COLOR, 4, clear_color); + vgPath = vgCreatePath(VG_PATH_FORMAT_STANDARD, + VG_PATH_DATATYPE_F, 1.0f, 0.0f, 0, 0, + VG_PATH_CAPABILITY_ALL); + + vgPaint = vgCreatePaint(); + vgSetParameteri(vgPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR); + vgSetColor(vgPaint, 0x00ff00ff); + vgSetPaint(vgPaint, VG_FILL_PATH); + + vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_NONANTIALIASED); + vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER); + vgSetf(VG_STROKE_LINE_WIDTH, 2.0f); + vgSeti(VG_STROKE_CAP_STYLE, VG_CAP_SQUARE); + vgSeti(VG_STROKE_JOIN_STYLE, VG_JOIN_MITER); + vgSetf(VG_STROKE_MITER_LIMIT, 4.0f); + vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); +} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ +} + +static void +draw(void) +{ + vgClear(0, 0, window_width(), window_height()); + +#if 0 + vgLoadIdentity(); + vgTranslate(40.0f, 24.0f); + vgScale(0.61804f, 0.61804f); + vgShear(-1.0f, 0.0f); + vgDrawPath(vgPath, VG_FILL_PATH | VG_STROKE_PATH); +#else + + /* row 1, col 1: Identity transform. */ + + vgLoadIdentity(); + vgTranslate(8.0f, 8.0f); + ellipse(vgPath, 4.0f, 4.0f, 0.0f); + + /* row 1, col 2: 10^3 horizontal squeeze. */ + + vgLoadIdentity(); + vgTranslate(24.0f, 8.0f); + vgScale(1.0e-3f, 1.0f); + ellipse(vgPath, 4.0e3f, 4.0f, 0.0f); + + /* row 1, col 3: 10^6 horizontal squeeze. */ + + vgLoadIdentity(); + vgTranslate(40.0f, 8.0f); + vgScale(1.0e-6f, 1.0f); + ellipse(vgPath, 4.0e6f, 4.0f, 0.0f); + + /* row 1, col 4: 10^9 horizontal squeeze. */ + + vgLoadIdentity(); + vgTranslate(56.0f, 8.0f); + vgScale(1.0e-9f, 1.0f); + ellipse(vgPath, 4.0e9f, 4.0f, 0.0f); + + /* row 2, col 1: 10^3 vertical squeeze. */ + + vgLoadIdentity(); + vgTranslate(8.0f, 24.0f); + vgScale(1.0f, 1.0e-3f); + ellipse(vgPath, 4.0f, 4.0e3f, 0.0f); + + /* row 2, col 2: Shear 0. */ + + vgLoadIdentity(); + vgTranslate(24.0f, 24.0f); + vgShear(0.0f, 0.0f); + ellipse(vgPath, 4.0f, 4.0f, 0.0f); + + /* row 2, col 3: Horizontal shear -1. */ + + vgLoadIdentity(); + vgTranslate(40.0f, 24.0f); + vgScale(0.61804f, 0.61804f); + vgShear(-1.0f, 0.0f); + ellipse(vgPath, 10.47213f, 4.0f, 31.717f); +#endif + vgFlush(); +} + + +int main(int argc, char **argv) +{ + set_window_size(64, 64); + return run(argc, argv, init, reshape, + draw, 0); +} diff --git a/progs/egl/openvg/trivial/cap.c b/progs/egl/openvg/trivial/cap.c new file mode 100644 index 00000000000..cd84fe3ac00 --- /dev/null +++ b/progs/egl/openvg/trivial/cap.c @@ -0,0 +1,75 @@ +#include "eglcommon.h" + +#include <VG/openvg.h> + +#include <math.h> +#include <stdlib.h> +#include <stdio.h> + +static void +init(void) +{ + +} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ +} + +const int subtest = 0; +static void +draw(void) +{ + VGPath line; + VGPaint fillPaint; + VGubyte lineCommands[3] = {VG_MOVE_TO_ABS, VG_LINE_TO_ABS, VG_LINE_TO_ABS}; + VGfloat lineCoords[] = {-2.0f,-1.0f, 0.0f,0.0f, -1.0f, -2.0f}; + VGfloat clearColor[] = {0.0f, 0.0f, 0.0f, 1.0f};/* black color */ + VGfloat fillColor[] = {1.0f, 1.0f, 1.0f, 1.0f};/* white color */ + //VGfloat testRadius = 60.0f; + VGfloat testRadius = 10.0f; + int WINDSIZEX = window_width(); + int WINDSIZEY = window_height(); + + line = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, + 1.0f, 0.0f, 0, 0, VG_PATH_CAPABILITY_ALL); + fillPaint = vgCreatePaint(); + + vgSetf(VG_STROKE_LINE_WIDTH, 1.0f); + //vgSeti(VG_STROKE_CAP_STYLE, VG_CAP_ROUND); + vgSeti(VG_STROKE_CAP_STYLE, VG_CAP_BUTT); + vgSeti(VG_STROKE_JOIN_STYLE, VG_JOIN_ROUND); + //vgSeti(VG_STROKE_JOIN_STYLE, VG_JOIN_BEVEL); + + vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_BETTER); + + vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); + vgLoadIdentity(); + vgTranslate(60, 60); + vgScale(testRadius * 2, testRadius * 2); + + vgAppendPathData(line, 3, lineCommands, lineCoords); + + vgSetfv(VG_CLEAR_COLOR, 4, clearColor); + + vgSetPaint(fillPaint, VG_STROKE_PATH); + + vgSetParameterfv(fillPaint, VG_PAINT_COLOR, 4, fillColor); + vgSetParameteri( fillPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR); + + vgClear(0, 0, WINDSIZEX, WINDSIZEY); + vgDrawPath(line, VG_STROKE_PATH); + + vgDestroyPath(line); + vgDestroyPaint(fillPaint); +} + + +int main(int argc, char **argv) +{ + set_window_size(100, 100); + return run(argc, argv, init, reshape, + draw, 0); +} diff --git a/progs/egl/openvg/trivial/clear.c b/progs/egl/openvg/trivial/clear.c new file mode 100644 index 00000000000..efb6bf41820 --- /dev/null +++ b/progs/egl/openvg/trivial/clear.c @@ -0,0 +1,42 @@ +#include "eglcommon.h" + +#include <VG/openvg.h> +#include <stdio.h> + +float red_color[4] = {1.0, 0.0, 0.0, 1.0}; +float blue_color[4] = {0.0, 0.0, 1.0, 1.0}; + +static void +init(void) +{ +} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ + vgLoadIdentity(); +} + +static void +draw(void) +{ + VGint scissor[4] = {100, 100, 25, 25}; + vgSetfv(VG_CLEAR_COLOR, 4, red_color); + vgClear(0, 0, window_width(), window_height()); + + vgSetfv(VG_CLEAR_COLOR, 4, blue_color); + vgClear(50, 50, 50, 50); + + //vgSetiv(VG_SCISSOR_RECTS, 4, scissor); + //vgSeti(VG_SCISSORING, VG_TRUE); + vgCopyPixels(100, 100, 50, 50, 50, 50); + vgClear(150, 150, 50, 50); +} + + +int main(int argc, char **argv) +{ + return run(argc, argv, init, reshape, + draw, 0); +} diff --git a/progs/egl/openvg/trivial/coord.c b/progs/egl/openvg/trivial/coord.c new file mode 100644 index 00000000000..81f7cb6fc9e --- /dev/null +++ b/progs/egl/openvg/trivial/coord.c @@ -0,0 +1,66 @@ +#include "eglcommon.h" + +#include <VG/openvg.h> + +const VGfloat white_color[4] = {1.0, 1.0, 1.0, 1.0}; +const VGfloat color[4] = {0.4, 0.1, 1.0, 1.0}; + +VGPath path; +VGPaint fill; + + +static void +init(void) +{ + /* Absent VG_CLOSE_PATH */ + VGubyte commands[] = {VG_MOVE_TO_ABS, VG_LINE_TO_ABS, VG_LINE_TO_ABS, VG_LINE_TO_ABS, + VG_MOVE_TO_ABS, VG_LINE_TO_ABS, VG_LINE_TO_ABS, VG_LINE_TO_ABS}; + VGfloat clearColor[] = {1.0f, 1.0f, 1.0f, 1.0f};/* white color */ + VGfloat fillColor[] = {1.0f, 0.0f, 0.0f, 1.0f};/* red color */ + VGfloat coords[] = {-16.0f, -16.0f, 0.0f, -16.0f, 0.0f, 0.0f, -16.0f, 0.0f, + 0.0f, 0.0f, 16.0f, 0.0f, 16.0f, 16.0f, 0.0f, 16.0f}; + + vgSetfv(VG_CLEAR_COLOR, 4, clearColor); + vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_NONANTIALIASED); + + vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); + vgLoadIdentity(); + vgTranslate(32.0f, 32.0f); + + path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1.0f, 0.0f, 0, 0, + VG_PATH_CAPABILITY_ALL); + if (path == VG_INVALID_HANDLE) + return; + fill = vgCreatePaint(); + if (fill == VG_INVALID_HANDLE) { + vgDestroyPath(path); + return; + } + vgAppendPathData(path, 8, commands, coords); + vgSetPaint(fill, VG_FILL_PATH); + vgSetParameterfv(fill, VG_PAINT_COLOR, 4, fillColor); + vgSetParameteri(fill, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR); +} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ +} + +static void +draw(void) +{ + vgClear(0, 0, window_width(), window_height()); + vgDrawPath(path, VG_FILL_PATH); + + vgFlush(); +} + + +int main(int argc, char **argv) +{ + set_window_size(64, 64); + return run(argc, argv, init, reshape, + draw, 0); +} diff --git a/progs/egl/openvg/trivial/dash.c b/progs/egl/openvg/trivial/dash.c new file mode 100644 index 00000000000..2e84ddbd4ea --- /dev/null +++ b/progs/egl/openvg/trivial/dash.c @@ -0,0 +1,95 @@ +#include "eglcommon.h" + +#include <VG/openvg.h> +#include <X11/keysym.h> +#include <stdio.h> + +const VGfloat white_color[4] = {1.0, 1.0, 1.0, 1.0}; +const VGfloat color[4] = {0.4, 0.1, 1.0, 1.0}; + +VGPath path; +VGPaint fill; + +VGint cap_style = VG_CAP_BUTT; + +static void +init(void) +{ + static const VGubyte cmds[] = {VG_MOVE_TO_ABS, + VG_LINE_TO_ABS, + VG_LINE_TO_ABS + }; +#if 1 + static const VGfloat coords[] = {100, 100, 150, 100, + 150, 200 + }; +#else + static const VGfloat coords[] = {100, 20, 100, 220, + }; +#endif + VGfloat dash_pattern[2] = { 20.f, 20.f }; + path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0, + VG_PATH_CAPABILITY_APPEND_TO); + vgAppendPathData(path, 3, cmds, coords); + + fill = vgCreatePaint(); + vgSetParameterfv(fill, VG_PAINT_COLOR, 4, color); + vgSetPaint(fill, VG_FILL_PATH); + + vgSetfv(VG_CLEAR_COLOR, 4, white_color); + vgSetf(VG_STROKE_LINE_WIDTH, 20); + vgSeti(VG_STROKE_CAP_STYLE, cap_style); + vgSeti(VG_STROKE_JOIN_STYLE, VG_JOIN_ROUND); + vgSetfv(VG_STROKE_DASH_PATTERN, 2, dash_pattern); + vgSetf(VG_STROKE_DASH_PHASE, 0.0f); +} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ + vgLoadIdentity(); +} + +static void +draw(void) +{ + vgClear(0, 0, window_width(), window_height()); + vgDrawPath(path, VG_STROKE_PATH); + + vgFlush(); +} + +static int key_press(unsigned key) +{ + switch(key) { + case XK_c: + case XK_C: + ++cap_style; + if (cap_style > VG_CAP_SQUARE) + cap_style = VG_CAP_BUTT; + switch(cap_style) { + case VG_CAP_BUTT: + fprintf(stderr, "Cap style 'butt'\n"); + break; + case VG_CAP_ROUND: + fprintf(stderr, "Cap style 'round'\n"); + break; + case VG_CAP_SQUARE: + fprintf(stderr, "Cap style 'square'\n"); + break; + } + vgSeti(VG_STROKE_CAP_STYLE, cap_style); + break; + default: + break; + } + + return VG_TRUE; +} + +int main(int argc, char **argv) +{ + return run(argc, argv, init, reshape, + draw, key_press); +} diff --git a/progs/egl/openvg/trivial/eglcommon.c b/progs/egl/openvg/trivial/eglcommon.c new file mode 100644 index 00000000000..0316e596c69 --- /dev/null +++ b/progs/egl/openvg/trivial/eglcommon.c @@ -0,0 +1,289 @@ +#include "eglcommon.h" + + +#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> +#include <VG/openvg.h> /* using full OpenGL for now */ +#include <GLES/egl.h> + + +static init_func init = 0; +static draw_func draw = 0; +static reshape_func reshape = 0; +static key_func keyPress = 0; +static VGint width = 300, height = 300; + + +void set_window_size(int w, int h) +{ + width = w; + height = h; +} + +/* + * 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_RENDERABLE_TYPE, EGL_OPENVG_BIT, + EGL_NONE + }; + + 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) || + !num_configs) { + printf("Error: couldn't get an EGL visual config\n"); + exit(1); + } + + assert(config); + + 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); + } + + eglBindAPI(EGL_OPENVG_API); + + ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, NULL ); + if (!ctx) { + printf("Error: eglCreateContext failed\n"); + exit(1); + } + + *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL); + + if (!*surfRet) { + printf("Error: eglCreateWindowSurface failed\n"); + exit(1); + } + + 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: + if (reshape) { + width = event.xconfigure.width; + height = event.xconfigure.height; + reshape(event.xconfigure.width, event.xconfigure.height); + } + break; + case KeyPress: + { + char buffer[10]; + int r, code; + code = XLookupKeysym(&event.xkey, 0); + if (!keyPress || !keyPress(code)) { + 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); + } + } +} + +int window_width(void) +{ + return width; +} + +int window_height(void) +{ + return height; +} + +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 run(int argc, char **argv, + init_func init_f, + reshape_func resh_f, + draw_func draw_f, + key_func key_f) +{ + const int winWidth = width, winHeight = height; + 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; + + init = init_f; + draw = draw_f; + reshape = resh_f; + keyPress = key_f; + + 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; + } + } + + 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); + + make_x_window(x_dpy, egl_dpy, + "OpenVG Example", 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("VG_RENDERER = %s\n", (char *) vgGetString(VG_RENDERER)); + printf("VG_VERSION = %s\n", (char *) vgGetString(VG_VERSION)); + printf("VG_VENDOR = %s\n", (char *) vgGetString(VG_VENDOR)); + } + + if (init) + init(); + + /* Set initial projection/viewing transformation. + * We can't be sure we'll get a ConfigureNotify event when the window + * first appears. + */ + if (reshape) + reshape(winWidth, winHeight); + + event_loop(x_dpy, win, egl_dpy, egl_surf); + + eglMakeCurrent(egl_dpy, 0, 0, 0); + eglDestroyContext(egl_dpy, egl_ctx); + eglDestroySurface(egl_dpy, egl_surf); + eglTerminate(egl_dpy); + + + XDestroyWindow(x_dpy, win); + XCloseDisplay(x_dpy); + + return 0; +} + diff --git a/progs/egl/openvg/trivial/eglcommon.h b/progs/egl/openvg/trivial/eglcommon.h new file mode 100644 index 00000000000..958dae9f98d --- /dev/null +++ b/progs/egl/openvg/trivial/eglcommon.h @@ -0,0 +1,20 @@ +#ifndef EGLCOMMON_H +#define EGLCOMMON_H + +typedef void (*init_func)(); +typedef void (*reshape_func)(int, int); +typedef void (*draw_func)(); +typedef int (*key_func)(unsigned key); + + +void set_window_size(int width, int height); +int window_width(void); +int window_height(void); + +int run(int argc, char **argv, + init_func init, + reshape_func resh, + draw_func draw, + key_func key); + +#endif diff --git a/progs/egl/openvg/trivial/ellipse.c b/progs/egl/openvg/trivial/ellipse.c new file mode 100644 index 00000000000..4c7d4904f81 --- /dev/null +++ b/progs/egl/openvg/trivial/ellipse.c @@ -0,0 +1,84 @@ +#include "eglcommon.h" + +#include <VG/openvg.h> + +#include <math.h> +#include <stdlib.h> + +const VGfloat white_color[4] = {1.0, 1.0, 1.0, 1.0}; +const VGfloat color[4] = {0.0, 0.0, 0.0, 1.0}; + +VGPath path; +VGPaint paint; + +static void +init(void) +{ + VGfloat clearColor[] = {1.0f, 1.0f, 1.0f, 1.0f};/* white color */ + VGfloat fillColor[] = {1.0f, 0.0f, 0.0f, 1.0f};/* red color */ + static const VGubyte segments[4] = {VG_MOVE_TO_ABS, + VG_SCCWARC_TO_ABS, + VG_SCCWARC_TO_ABS, + VG_CLOSE_PATH}; + VGfloat data[12]; + const VGfloat cx = 0, cy=29, width=80, height=40; + const VGfloat hw = width * 0.5f; + const VGfloat hh = height * 0.5f; + + data[0] = cx + hw; + data[1] = cy; + data[2] = hw; + data[3] = hh; + data[4] = 0; + data[5] = cx - hw; + data[6] = cy; + data[7] = hw; + data[8] = hh; + data[9] = 0; + data[10] = data[0]; + data[11] = cy; + + vgSetfv(VG_CLEAR_COLOR, 4, clearColor); + vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_NONANTIALIASED); + + + path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, + 1.0f, 0.0f, 0, 0, VG_PATH_CAPABILITY_ALL); + if (path == VG_INVALID_HANDLE) { + return; + } + paint = vgCreatePaint(); + if (paint == VG_INVALID_HANDLE) { + vgDestroyPath(path); + return; + } + + vgAppendPathData(path, 4, segments, data); + vgSetParameterfv(paint, VG_PAINT_COLOR, 4, fillColor); + vgSetParameteri( paint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR); + vgSetPaint(paint, VG_FILL_PATH); +} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ +} + +static void +draw(void) +{ + vgClear(0, 0, window_width(), window_height()); + vgLoadIdentity(); + vgTranslate(50, 21); + vgDrawPath(path, VG_FILL_PATH); + vgFlush(); +} + + +int main(int argc, char **argv) +{ + set_window_size(100, 100); + return run(argc, argv, init, reshape, + draw, 0); +} diff --git a/progs/egl/openvg/trivial/filter.c b/progs/egl/openvg/trivial/filter.c new file mode 100644 index 00000000000..d96257a9335 --- /dev/null +++ b/progs/egl/openvg/trivial/filter.c @@ -0,0 +1,107 @@ +#include "eglcommon.h" + +#include <VG/openvg.h> + +#include <math.h> +#include <stdlib.h> +#include <stdio.h> + +const VGfloat white_color[4] = {1.0, 1.0, 1.0, 1.0}; +const VGfloat color[4] = {1.0, 1.0, 1.0, 0.5}; + +VGImage srcImg; +VGImage dstImg; + +VGPaint fill; + +VGfloat bgCol[4] = {0.906f, 0.914f, 0.761f, 1.0f}; + +static void +init(void) +{ + VGfloat red[4]; + VGfloat grey[4]; + VGfloat orange[4]; + VGfloat blue[4]; + VGfloat black[4]; + VGfloat white[4]; + VGshort transKernel[49] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + red[0] = 0.6710f; + red[1] = 0.1060f; + red[2] = 0.1330f; + red[3] = 1.0f; + + grey[0] = 0.6347f; + grey[1] = 0.6561f; + grey[2] = 0.6057f; + grey[3] = 1.0f; + + orange[0] = 1.0000f; + orange[1] = 0.8227f; + orange[2] = 0.5057f; + orange[3] = 1.0f; + + blue[0] = 0.0000f; + blue[1] = 0.6908f; + blue[2] = 0.8595f; + blue[3] = 1.0f; + + black[0] = 0; + black[1] = 0; + black[2] = 0; + black[3] = 1.0f; + + white[0] = 1; + white[1] = 1; + white[2] = 1; + white[3] = 1.0f; + + vgSetfv(VG_TILE_FILL_COLOR, 4, blue); + + vgSeti(VG_FILTER_CHANNEL_MASK, 14); + + /* Setup images */ + srcImg = vgCreateImage(VG_sRGBA_8888, 32, 32, + VG_IMAGE_QUALITY_NONANTIALIASED); + dstImg = vgCreateImage(VG_sRGBA_8888, 32, 32, + VG_IMAGE_QUALITY_NONANTIALIASED); + + vgSetfv(VG_CLEAR_COLOR, 4, black); + vgClearImage(srcImg, 0, 0, 32, 32); + vgSetfv(VG_CLEAR_COLOR, 4, red); + vgClearImage(srcImg, 3, 3, 27, 27); + + vgSetfv(VG_CLEAR_COLOR, 4, orange); + vgClearImage(dstImg, 0, 0, 32, 32); + + transKernel[8] = 1; + vgConvolve(dstImg, srcImg, 3, 3, 3, 0, transKernel, + 1, 0, VG_TILE_FILL); +} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ +} + +static void +draw(void) +{ + vgSetfv(VG_CLEAR_COLOR, 4, bgCol); + vgClear(0, 0, window_width(), window_height()); + vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE); + vgLoadIdentity(); + vgTranslate(10, 10); + vgDrawImage(dstImg); + vgFlush(); +} + + +int main(int argc, char **argv) +{ + set_window_size(64, 64); + return run(argc, argv, init, reshape, + draw, 0); +} diff --git a/progs/egl/openvg/trivial/gradorigin.c b/progs/egl/openvg/trivial/gradorigin.c new file mode 100644 index 00000000000..b376263fe5c --- /dev/null +++ b/progs/egl/openvg/trivial/gradorigin.c @@ -0,0 +1,98 @@ +#include "eglcommon.h" + +#include <VG/openvg.h> + +#include <stdio.h> +#include <string.h> + +static const VGfloat white_color[4] = {1.0, 1.0, 1.0, 1.0}; + +static VGPath path; +static VGPaint fill; + +VGColorRampSpreadMode spread = VG_COLOR_RAMP_SPREAD_PAD; + +static void +init(void) +{ + VGubyte commands[5] = {VG_MOVE_TO_ABS, VG_LINE_TO_ABS, VG_LINE_TO_ABS, VG_LINE_TO_ABS, VG_CLOSE_PATH}; + VGfloat coords[8] = {0.0f,0.0f, 32.0f,0.0f, 32.0f,32.0f, 0.0f,32.0f }; + + VGfloat rampStop[20] = {-0.5f, 1.0f, 1.0f, 1.0f, 1.0f, + 0.25f, 1.0f, 0.0f, 0.0f, 1.0f, + 0.75f, 0.0f, 0.0f, 1.0f, 1.0f, + 1.5f, 0.0f, 0.0f, 0.0f, 0.0f}; + + VGfloat defaultColor[] = {1.0f, 1.0f, 1.0f, 1.0f}; + VGfloat linearGradient[4] = {0.0f, 0.0f, 0.0f, 32.0f}; + + path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, + 1.0f, 0.0f, 0, 0, VG_PATH_CAPABILITY_ALL); + if (path == VG_INVALID_HANDLE) + return; + + fill = vgCreatePaint(); + if (fill == VG_INVALID_HANDLE) { + vgDestroyPath(path); + return; + } + + vgSetfv(VG_CLEAR_COLOR, 4, defaultColor); + vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_NONANTIALIASED); + + vgAppendPathData(path, 5, commands, coords); + + vgSetPaint(fill, VG_FILL_PATH); + vgSetParameteri(fill, VG_PAINT_TYPE, VG_PAINT_TYPE_LINEAR_GRADIENT); + vgSetParameteri(fill, VG_PAINT_COLOR_RAMP_SPREAD_MODE, + VG_COLOR_RAMP_SPREAD_REPEAT); + vgSetParameterfv(fill, VG_PAINT_LINEAR_GRADIENT, 4, linearGradient); + vgSetParameterfv(fill, VG_PAINT_COLOR_RAMP_STOPS, 20, rampStop); +} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ + vgLoadIdentity(); +} + +static void +draw(void) +{ + vgClear(0, 0, window_width(), window_height()); + + vgDrawPath(path, VG_FILL_PATH); + + vgFlush(); +} + + +int main(int argc, char **argv) +{ + if (argc > 1) { + const char *arg = argv[1]; + if (!strcmp("-pad", arg)) + spread = VG_COLOR_RAMP_SPREAD_PAD; + else if (!strcmp("-repeat", arg)) + spread = VG_COLOR_RAMP_SPREAD_REPEAT; + else if (!strcmp("-reflect", arg)) + spread = VG_COLOR_RAMP_SPREAD_REFLECT; + } + + switch(spread) { + case VG_COLOR_RAMP_SPREAD_PAD: + printf("Using spread mode: pad\n"); + break; + case VG_COLOR_RAMP_SPREAD_REPEAT: + printf("Using spread mode: repeat\n"); + break; + case VG_COLOR_RAMP_SPREAD_REFLECT: + printf("Using spread mode: reflect\n"); + } + + set_window_size(200, 200); + + return run(argc, argv, init, reshape, + draw, 0); +} diff --git a/progs/egl/openvg/trivial/lineto.c b/progs/egl/openvg/trivial/lineto.c new file mode 100644 index 00000000000..94e29818116 --- /dev/null +++ b/progs/egl/openvg/trivial/lineto.c @@ -0,0 +1,56 @@ +#include "eglcommon.h" + +#include <VG/openvg.h> + +const VGfloat white_color[4] = {1.0, 1.0, 1.0, 1.0}; +const VGfloat color[4] = {0.4, 0.1, 1.0, 1.0}; + +VGPath path; +VGPaint fill; + + +static void +init(void) +{ + static const VGubyte sqrCmds[5] = {VG_MOVE_TO_ABS, VG_HLINE_TO_ABS, VG_VLINE_TO_ABS, VG_HLINE_TO_ABS, VG_CLOSE_PATH}; + static const VGfloat sqrCoords[5] = {50.0f, 50.0f, 250.0f, 250.0f, 50.0f}; + path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0, + VG_PATH_CAPABILITY_APPEND_TO); + vgAppendPathData(path, 5, sqrCmds, sqrCoords); + + fill = vgCreatePaint(); + vgSetParameterfv(fill, VG_PAINT_COLOR, 4, color); + vgSetPaint(fill, VG_FILL_PATH); + + vgSetfv(VG_CLEAR_COLOR, 4, white_color); + vgSetf(VG_STROKE_LINE_WIDTH, 10); + vgSeti(VG_STROKE_CAP_STYLE, VG_CAP_BUTT); + vgSeti(VG_STROKE_JOIN_STYLE, VG_JOIN_ROUND); + vgSetf(VG_STROKE_MITER_LIMIT, 4.0f); +} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ + vgLoadIdentity(); +} + +static void +draw(void) +{ + vgClear(0, 0, window_width(), window_height()); + vgSeti(VG_MATRIX_MODE, VG_MATRIX_STROKE_PAINT_TO_USER); + vgLoadIdentity(); + vgScale(2.25, 2.25); + vgDrawPath(path, VG_STROKE_PATH); + + vgFlush(); +} + + +int main(int argc, char **argv) +{ + return run(argc, argv, init, reshape, + draw, 0); +} diff --git a/progs/egl/openvg/trivial/lingrad.c b/progs/egl/openvg/trivial/lingrad.c new file mode 100644 index 00000000000..bcaad1f1015 --- /dev/null +++ b/progs/egl/openvg/trivial/lingrad.c @@ -0,0 +1,87 @@ +#include "eglcommon.h" + +#include <VG/openvg.h> + +#include <stdio.h> +#include <string.h> + +static const VGfloat white_color[4] = {1.0, 1.0, 1.0, 1.0}; + +static VGPath path; +static VGPaint fill; + +VGColorRampSpreadMode spread = VG_COLOR_RAMP_SPREAD_PAD; + +static void +init(void) +{ + static const VGubyte sqrCmds[5] = {VG_MOVE_TO_ABS, VG_HLINE_TO_ABS, VG_VLINE_TO_ABS, VG_HLINE_TO_ABS, VG_CLOSE_PATH}; + static const VGfloat sqrCoords[5] = {0.0f, 0.0f, 400.0f, 400.0f, 0.0f}; + + VGfloat rampStop[] = {0.00f, 1.0f, 1.0f, 1.0f, 1.0f, + 0.33f, 1.0f, 0.0f, 0.0f, 1.0f, + 0.66f, 0.0f, 1.0f, 0.0f, 1.0f, + 1.00f, 0.0f, 0.0f, 1.0f, 1.0f}; + VGfloat linearGradient[4] = {100.0f, 100.0f, 300.0f, 300.0f}; + + path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0, + VG_PATH_CAPABILITY_APPEND_TO); + vgAppendPathData(path, 5, sqrCmds, sqrCoords); + + fill = vgCreatePaint(); + vgSetPaint(fill, VG_FILL_PATH); + + vgSetParameteri(fill, VG_PAINT_TYPE, VG_PAINT_TYPE_LINEAR_GRADIENT); + vgSetParameteri(fill, VG_PAINT_COLOR_RAMP_SPREAD_MODE, spread); + vgSetParameterfv(fill, VG_PAINT_LINEAR_GRADIENT, 4, linearGradient); + vgSetParameterfv(fill, VG_PAINT_COLOR_RAMP_STOPS, 20, rampStop); + + vgSetfv(VG_CLEAR_COLOR, 4, white_color); +} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ + vgLoadIdentity(); +} + +static void +draw(void) +{ + vgClear(0, 0, window_width(), window_height()); + + vgDrawPath(path, VG_FILL_PATH); + + vgFlush(); +} + + +int main(int argc, char **argv) +{ + if (argc > 1) { + const char *arg = argv[1]; + if (!strcmp("-pad", arg)) + spread = VG_COLOR_RAMP_SPREAD_PAD; + else if (!strcmp("-repeat", arg)) + spread = VG_COLOR_RAMP_SPREAD_REPEAT; + else if (!strcmp("-reflect", arg)) + spread = VG_COLOR_RAMP_SPREAD_REFLECT; + } + + switch(spread) { + case VG_COLOR_RAMP_SPREAD_PAD: + printf("Using spread mode: pad\n"); + break; + case VG_COLOR_RAMP_SPREAD_REPEAT: + printf("Using spread mode: repeat\n"); + break; + case VG_COLOR_RAMP_SPREAD_REFLECT: + printf("Using spread mode: reflect\n"); + } + + set_window_size(400, 400); + + return run(argc, argv, init, reshape, + draw, 0); +} diff --git a/progs/egl/openvg/trivial/lookup.c b/progs/egl/openvg/trivial/lookup.c new file mode 100644 index 00000000000..a103ba44888 --- /dev/null +++ b/progs/egl/openvg/trivial/lookup.c @@ -0,0 +1,71 @@ +#include "eglcommon.h" + +#include <VG/openvg.h> + +#include <math.h> +#include <stdlib.h> +#include <stdio.h> + +const VGfloat white_color[4] = {1.0, 1.0, 1.0, 1.0}; +const VGfloat color[4] = {1.0, 1.0, 1.0, 0.5}; +VGfloat clearColor[] = {1.0f, 0.0f, 0.0f, 1.0f};/* red color */ +VGImage parent; + +VGPaint fill; + +static void +init(void) +{ + VGImage child1, child2; + VGubyte *data; + VGuint LUT[256]; + VGint i; + + data = (VGubyte *)malloc(sizeof(VGubyte)*window_width()*window_height()); + + for (i=0;i<window_width()*window_height();i++) { + data[i] = 0x00; + } + + for (i=0; i<256; i++) { + if ( i == 0 ) + LUT[0] = 0xFFFFFFFF; + else + LUT[i] = 0xFF00FFFF; + } + + parent = vgCreateImage( VG_A_8, 64, 64, VG_IMAGE_QUALITY_NONANTIALIASED ); + + vgImageSubData(parent, data, window_width(), VG_A_8, 0, 0, + window_width(), window_height()); + child1 = vgChildImage(parent, 0, 0, 32, 64); + child2 = vgChildImage(parent, 32, 0, 32, 64); + + vgLookupSingle(child2, child1, LUT, VG_GREEN, VG_FALSE, VG_TRUE); +} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ +} + +static void +draw(void) +{ + vgSetfv(VG_CLEAR_COLOR, 4, clearColor); + vgClear(0, 0, window_width(), window_height()); + //vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE); + //vgLoadIdentity(); + //vgTranslate(10, 10); + vgDrawImage(parent); + vgFlush(); +} + + +int main(int argc, char **argv) +{ + set_window_size(64, 64); + return run(argc, argv, init, reshape, + draw, 0); +} diff --git a/progs/egl/openvg/trivial/mask.c b/progs/egl/openvg/trivial/mask.c new file mode 100644 index 00000000000..e5c00c56996 --- /dev/null +++ b/progs/egl/openvg/trivial/mask.c @@ -0,0 +1,58 @@ +#include "eglcommon.h" + +#include <VG/openvg.h> + +const VGfloat white_color[4] = {1.0, 1.0, 1.0, 1.0}; +const VGfloat color[4] = {0.4, 0.1, 1.0, 1.0}; + +VGPath path; +VGPaint fill; + + +static void +init(void) +{ + static const VGubyte sqrCmds[5] = {VG_MOVE_TO_ABS, VG_HLINE_TO_ABS, VG_VLINE_TO_ABS, VG_HLINE_TO_ABS, VG_CLOSE_PATH}; + static const VGfloat sqrCoords[5] = {50.0f, 50.0f, 250.0f, 250.0f, 50.0f}; + path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0, + VG_PATH_CAPABILITY_APPEND_TO); + vgAppendPathData(path, 5, sqrCmds, sqrCoords); + + fill = vgCreatePaint(); + vgSetParameterfv(fill, VG_PAINT_COLOR, 4, color); + vgSetPaint(fill, VG_FILL_PATH); + + vgSetfv(VG_CLEAR_COLOR, 4, white_color); + vgSetf(VG_STROKE_LINE_WIDTH, 10); + vgSeti(VG_STROKE_CAP_STYLE, VG_CAP_BUTT); + vgSeti(VG_STROKE_JOIN_STYLE, VG_JOIN_ROUND); + vgSetf(VG_STROKE_MITER_LIMIT, 4.0f); + + vgSeti(VG_MASKING, VG_TRUE); + + vgMask(VG_INVALID_HANDLE, VG_CLEAR_MASK, + 25, 25, 100, 100); +} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ + vgLoadIdentity(); +} + +static void +draw(void) +{ + vgClear(0, 0, window_width(), window_height()); + vgDrawPath(path, VG_FILL_PATH); + + vgFlush(); +} + + +int main(int argc, char **argv) +{ + return run(argc, argv, init, reshape, + draw, 0); +} diff --git a/progs/egl/openvg/trivial/mask4.c b/progs/egl/openvg/trivial/mask4.c new file mode 100644 index 00000000000..fe6db39648c --- /dev/null +++ b/progs/egl/openvg/trivial/mask4.c @@ -0,0 +1,132 @@ +#include "eglcommon.h" + +#include <VG/openvg.h> +#include <VG/vgu.h> +#include <stdio.h> +#include <math.h> +#include <stdlib.h> + +#include <X11/keysym.h> + +//VGint x_pos = -10, y_pos = -10; +VGint x_pos = 0, y_pos = 4; +VGint img_width = 120, img_height = 120; + +static void RectToPath(VGPath path, VGfloat x, VGfloat y, VGfloat width, VGfloat height) +{ + static const VGubyte segments[5] = {VG_MOVE_TO_ABS, + VG_HLINE_TO_ABS, + VG_VLINE_TO_ABS, + VG_HLINE_TO_ABS, + VG_CLOSE_PATH}; + VGfloat data[5]; + + data[0] = x; + data[1] = y; + data[2] = x + width; + data[3] = y + height; + data[4] = x; + + vgAppendPathData(path, 5, segments, data); +} + +static void +init(void) +{ +} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ +} + +int key_press(unsigned key) +{ + switch(key) { + case XK_Right: + x_pos +=1; + break; + case XK_Left: + x_pos -=1; + break; + case XK_Up: + y_pos +=1; + break; + case XK_Down: + y_pos -=1; + break; + case 'a': + img_width -= 5; + img_height -= 5; + break; + case 's': + img_width += 5; + img_height += 5; + break; + default: + break; + } + fprintf(stderr, "Posi = %dx%d\n", x_pos, y_pos); + fprintf(stderr, "Size = %dx%d\n", img_width, img_height); + return VG_FALSE; +} + +static void +draw(void) +{ + VGint WINDSIZEX = window_width(); + VGint WINDSIZEY = window_height(); + + VGPaint fill; + VGPath box; + VGfloat color[4] = {1.f, 0.f, 0.f, 1.f}; + VGfloat bgCol[4] = {0.7f, 0.7f, 0.7f, 1.0f}; + VGfloat transCol[4] = {0.f, 0.f, 0.f, 0.f}; + VGImage image = vgCreateImage(VG_sRGBA_8888, img_width, img_height, + VG_IMAGE_QUALITY_NONANTIALIASED); + + /* Background clear */ + fill = vgCreatePaint(); + vgSetParameterfv(fill, VG_PAINT_COLOR, 4, color); + vgSetPaint(fill, VG_FILL_PATH); + + box = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, + 1, 0, 0, 0, VG_PATH_CAPABILITY_ALL); + /* Rectangle to cover completely 16x16 pixel area. */ + RectToPath(box, 0, 0, 64, 64); + + vgSetfv(VG_CLEAR_COLOR, 4, transCol); + vgClearImage(image, 0, 0, img_width, img_height); + vgSetfv(VG_CLEAR_COLOR, 4, color); + vgClearImage(image, 10, 10, 12, 12); + //vgImageSubData(image, pukki_64x64_data, pukki_64x64_stride, + // VG_sRGBA_8888, 0, 0, 32, 32); + vgSeti(VG_MASKING, VG_TRUE); + vgLoadIdentity(); + + vgSetfv(VG_CLEAR_COLOR, 4, bgCol); + vgClear(0, 0, WINDSIZEX, WINDSIZEY); + + + vgMask(image, VG_FILL_MASK, 0, 0, window_width(), window_height()); + vgMask(image, VG_SET_MASK, x_pos, y_pos, 100, 100); + + vgDrawPath(box, VG_FILL_PATH); + + //vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE); + //vgTranslate(-10, -10); + //vgDrawImage(image); + + + vgDestroyPaint(fill); + vgDestroyPath(box); +} + + +int main(int argc, char **argv) +{ + set_window_size(64, 64); + return run(argc, argv, init, reshape, + draw, key_press); +} diff --git a/progs/egl/openvg/trivial/path3.c b/progs/egl/openvg/trivial/path3.c new file mode 100644 index 00000000000..5ce600f65aa --- /dev/null +++ b/progs/egl/openvg/trivial/path3.c @@ -0,0 +1,77 @@ +#include "eglcommon.h" + +#include <VG/openvg.h> +#include <VG/vgu.h> +#include <stdio.h> +#include <math.h> +#include <stdlib.h> + +static void +init(void) +{ +} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ +} + + +static void +draw(void) +{ + VGint WINDSIZEX = window_width(); + VGint WINDSIZEY = window_height(); + VGPath path; + VGPaint paint; + + VGfloat clearColor[] = {1.0f, 1.0f, 1.0f, 0.0f};/* white color */ + VGfloat fillColor[] = {1.0f, 0.0f, 0.0f, 1.0f};/* red color */ + +#if 1 + VGubyte commands[4] = {VG_MOVE_TO_ABS, VG_LCWARC_TO_ABS, VG_SCWARC_TO_ABS, VG_CLOSE_PATH}; +#else + VGubyte commands[4] = {VG_MOVE_TO_ABS, VG_SCCWARC_TO_ABS, VG_LCCWARC_TO_ABS,VG_CLOSE_PATH}; +#endif + VGfloat coords[] = {32.0f, 0.0f, + -32.0f, -32.0f, 0.0f, 64.0f, 32.0f, + -32.0f, -32.0f, 0.0f, 32.0f, 0.0f}; + + + vgSetfv(VG_CLEAR_COLOR, 4, clearColor); + vgClear(0, 0, WINDSIZEX, WINDSIZEY); + vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_NONANTIALIASED); + + vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); + vgLoadIdentity(); + //vgTranslate(32.0f, 32.0f); + + path = vgCreatePath( VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, + 1.0f, 0.0f, 0, 0, VG_PATH_CAPABILITY_ALL ); + if ( path == VG_INVALID_HANDLE ) { + return; + } + paint = vgCreatePaint(); + if ( paint == VG_INVALID_HANDLE ) { + vgDestroyPath(path); + return; + } + + vgAppendPathData(path, 4, commands, coords); + vgSetParameterfv(paint, VG_PAINT_COLOR, 4, fillColor); + vgSetParameteri( paint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR); + vgSetPaint(paint, VG_FILL_PATH); + vgDrawPath(path, VG_FILL_PATH); + + vgDestroyPath(path); + vgDestroyPaint(paint); +} + + +int main(int argc, char **argv) +{ + set_window_size(64, 64); + return run(argc, argv, init, reshape, + draw, 0); +} diff --git a/progs/egl/openvg/trivial/radialgrad.c b/progs/egl/openvg/trivial/radialgrad.c new file mode 100644 index 00000000000..cf3b1d522de --- /dev/null +++ b/progs/egl/openvg/trivial/radialgrad.c @@ -0,0 +1,99 @@ +#include "eglcommon.h" + +#include <VG/openvg.h> + +#include <stdio.h> +#include <string.h> + +static const VGfloat white_color[4] = {1.0, 1.0, 1.0, 1.0}; + +static VGPath path; +static VGPaint fill; + + +VGfloat centeredGradient[5] = {200.0f, 200.0f, 200.0f, 200.0f, 100}; +VGfloat noncenteredGradient[5] = {200.0f, 200.0f, 250.0f, 250.0f, 100}; +VGfloat *radialGradient = centeredGradient; + +VGColorRampSpreadMode spread = VG_COLOR_RAMP_SPREAD_PAD; + +static void +init(void) +{ + static const VGubyte sqrCmds[5] = {VG_MOVE_TO_ABS, VG_HLINE_TO_ABS, VG_VLINE_TO_ABS, VG_HLINE_TO_ABS, VG_CLOSE_PATH}; + static const VGfloat sqrCoords[5] = {0.0f, 0.0f, 400.0f, 400.0f, 0.0f}; + + VGfloat rampStop[] = {0.00f, 1.0f, 1.0f, 1.0f, 1.0f, + 0.33f, 1.0f, 0.0f, 0.0f, 1.0f, + 0.66f, 0.0f, 1.0f, 0.0f, 1.0f, + 1.00f, 0.0f, 0.0f, 1.0f, 1.0f}; + + path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0, + VG_PATH_CAPABILITY_APPEND_TO); + vgAppendPathData(path, 5, sqrCmds, sqrCoords); + + fill = vgCreatePaint(); + vgSetPaint(fill, VG_FILL_PATH); + + vgSetParameteri(fill, VG_PAINT_TYPE, VG_PAINT_TYPE_RADIAL_GRADIENT); + vgSetParameteri(fill, VG_PAINT_COLOR_RAMP_SPREAD_MODE, spread); + vgSetParameterfv(fill, VG_PAINT_RADIAL_GRADIENT, 5, radialGradient); + vgSetParameterfv(fill, VG_PAINT_COLOR_RAMP_STOPS, 20, rampStop); + + vgSetfv(VG_CLEAR_COLOR, 4, white_color); +} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ + vgLoadIdentity(); +} + +static void +draw(void) +{ + vgClear(0, 0, window_width(), window_height()); + + vgDrawPath(path, VG_FILL_PATH); + + vgFlush(); +} + + +int main(int argc, char **argv) +{ + VGint i; + for (i = 1; i < argc; ++i) { + const char *arg = argv[i]; + if (!strcmp("-pad", arg)) + spread = VG_COLOR_RAMP_SPREAD_PAD; + else if (!strcmp("-repeat", arg)) + spread = VG_COLOR_RAMP_SPREAD_REPEAT; + else if (!strcmp("-reflect", arg)) + spread = VG_COLOR_RAMP_SPREAD_REFLECT; + else if (!strcmp("-center", arg)) { + printf("Centered radial gradient\n"); + radialGradient = centeredGradient; + } else if (!strcmp("-noncenter", arg)) { + printf("Non centered radial gradient\n"); + radialGradient = noncenteredGradient; + } + } + + switch(spread) { + case VG_COLOR_RAMP_SPREAD_PAD: + printf("Using spread mode: pad\n"); + break; + case VG_COLOR_RAMP_SPREAD_REPEAT: + printf("Using spread mode: repeat\n"); + break; + case VG_COLOR_RAMP_SPREAD_REFLECT: + printf("Using spread mode: reflect\n"); + } + + set_window_size(400, 400); + + return run(argc, argv, init, reshape, + draw, 0); +} diff --git a/progs/egl/openvg/trivial/readpixels.c b/progs/egl/openvg/trivial/readpixels.c new file mode 100644 index 00000000000..c8e286db9ab --- /dev/null +++ b/progs/egl/openvg/trivial/readpixels.c @@ -0,0 +1,75 @@ +#include "eglcommon.h" + +#include <VG/openvg.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +float red_color[4] = {1.0, 0.0, 0.0, 1.0}; +float blue_color[4] = {0.0, 0.0, 1.0, 1.0}; +VGint *data; + +static void +init(void) +{ + data = malloc(sizeof(VGint)*2048*2048); +} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ + vgLoadIdentity(); +} + +static void +draw(void) +{ + static const VGint red_pixel = 255 << 24 | 255 << 16 | 0 << 8 | 0; + static const VGint blue_pixel = 255 << 24 | 0 << 16 | 0 << 8 | 255; + VGint i; + + vgSetfv(VG_CLEAR_COLOR, 4, red_color); + vgClear(0, 0, window_width(), window_height()); + vgFlush(); + + memset(data, 0, window_width() * window_height() * sizeof(VGint)); + + vgReadPixels(data, window_width() * sizeof(VGint), + VG_lARGB_8888, + 0, 0, window_width(), window_height()); + + fprintf(stderr, "Red 0 = 0x%x and at 600 = 0x%x\n", + data[0], data[600]); + for (i = 0; i < window_width() * window_height(); ++i) { + assert(data[i] == red_pixel); + } + + vgSetfv(VG_CLEAR_COLOR, 4, blue_color); + vgClear(50, 50, 50, 50); + vgFlush(); + + memset(data, 0, window_width() * window_height() * sizeof(VGint)); + + vgReadPixels(data, 50 * sizeof(VGint), + VG_lARGB_8888, + 50, 50, 50, 50); + + fprintf(stderr, "Blue 0 = 0x%x and at 100 = 0x%x\n", + data[0], data[100]); + for (i = 0; i < 50 * 50; ++i) { + assert(data[i] == blue_pixel); + } +} + + +int main(int argc, char **argv) +{ + int ret = run(argc, argv, init, reshape, + draw, 0); + + free(data); + return ret; +} diff --git a/progs/egl/openvg/trivial/roundedrect.c b/progs/egl/openvg/trivial/roundedrect.c new file mode 100644 index 00000000000..c80a4ed2995 --- /dev/null +++ b/progs/egl/openvg/trivial/roundedrect.c @@ -0,0 +1,67 @@ +#include "eglcommon.h" + +#include <VG/openvg.h> + +const VGfloat white_color[4] = {1.0, 1.0, 1.0, 1.0}; +const VGfloat color[4] = {0.9, 0.1, 0.1, 0.8}; + +VGPath path; +VGPaint fill; + + +static void +init(void) +{ + static const VGubyte sqrCmds[10] = {VG_MOVE_TO_ABS, + VG_LINE_TO_ABS, + VG_CUBIC_TO_ABS, + VG_LINE_TO_ABS, + VG_CUBIC_TO_ABS, + VG_LINE_TO_ABS, + VG_CUBIC_TO_ABS, + VG_LINE_TO_ABS, + VG_CUBIC_TO_ABS, + VG_CLOSE_PATH}; + static const VGfloat sqrCoords[] = { + 45.885571, 62.857143, + 154.11442, 62.857143, + 162.1236, 62.857143, 168.57142, 70.260744, 168.57142, 79.457144, + 168.57142, 123.4, + 168.57142, 132.5964, 162.1236, 140, 154.11442, 140, + 45.885571, 140, + 37.876394, 140, 31.428572, 132.5964, 31.428572, 123.4, + 31.428572, 79.457144, + 31.428572, 70.260744, 37.876394,62.857143, 45.885571,62.857143 + }; + path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0, + VG_PATH_CAPABILITY_APPEND_TO); + vgAppendPathData(path, 10, sqrCmds, sqrCoords); + + fill = vgCreatePaint(); + vgSetParameterfv(fill, VG_PAINT_COLOR, 4, color); + vgSetPaint(fill, VG_FILL_PATH); + + vgSetfv(VG_CLEAR_COLOR, 4, white_color); + vgSetf(VG_STROKE_LINE_WIDTH, 6); +} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ + vgLoadIdentity(); +} + +static void +draw(void) +{ + vgClear(0, 0, window_width(), window_height()); + vgDrawPath(path, VG_STROKE_PATH); +} + + +int main(int argc, char **argv) +{ + return run(argc, argv, init, reshape, + draw, 0); +} diff --git a/progs/egl/openvg/trivial/star-nonzero.c b/progs/egl/openvg/trivial/star-nonzero.c new file mode 100644 index 00000000000..012fbd39294 --- /dev/null +++ b/progs/egl/openvg/trivial/star-nonzero.c @@ -0,0 +1,55 @@ +#include "eglcommon.h" + +#include <VG/openvg.h> + +const VGfloat white_color[4] = {1.0, 1.0, 1.0, 1.0}; +const VGfloat green_color[4] = {0.0, 1.0, 0.0, 0.8}; + +VGPath path; +VGPaint fill; + + +static void +init(void) +{ + static const VGubyte cmds[6] = {VG_MOVE_TO_ABS, VG_LINE_TO_ABS, VG_LINE_TO_ABS, VG_LINE_TO_ABS, + VG_LINE_TO_ABS, VG_CLOSE_PATH}; + static const VGfloat coords[] = { 0, 200, + 300, 200, + 50, 0, + 150, 300, + 250, 0}; + path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0, + VG_PATH_CAPABILITY_APPEND_TO); + vgAppendPathData(path, 6, cmds, coords); + + fill = vgCreatePaint(); + vgSetParameterfv(fill, VG_PAINT_COLOR, 4, green_color); + vgSetPaint(fill, VG_FILL_PATH); + + vgSetfv(VG_CLEAR_COLOR, 4, white_color); + vgSeti(VG_FILL_RULE, VG_NON_ZERO); +} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ + vgLoadIdentity(); +} + +static void +draw(void) +{ + vgClear(0, 0, window_width(), window_height()); + vgDrawPath(path, VG_FILL_PATH | VG_STROKE_PATH); + + vgFlush(); +} + + +int main(int argc, char **argv) +{ + return run(argc, argv, init, reshape, + draw, 0); +} diff --git a/progs/egl/openvg/trivial/star-oddeven.c b/progs/egl/openvg/trivial/star-oddeven.c new file mode 100644 index 00000000000..17311cf720a --- /dev/null +++ b/progs/egl/openvg/trivial/star-oddeven.c @@ -0,0 +1,102 @@ +#include "eglcommon.h" + +#include <VG/openvg.h> + +const VGfloat white_color[4] = {1.0, 1.0, 1.0, 1.0}; +const VGfloat green_color[4] = {0.0, 1.0, 0.0, 0.8}; +const VGfloat black_color[4] = {0.0, 0.0, 0.0, 1.0}; + +VGPath path; +VGPaint fill; + + +static void draw_point(VGfloat x, VGfloat y) +{ + + static const VGubyte cmds[] = {VG_MOVE_TO_ABS, VG_LINE_TO_ABS, VG_LINE_TO_ABS, + VG_LINE_TO_ABS, VG_CLOSE_PATH}; + const VGfloat coords[] = { x - 2, y - 2, + x + 2, y - 2, + x + 2, y + 2, + x - 2, y + 2}; + VGPath path; + VGPaint fill; + + path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0, + VG_PATH_CAPABILITY_ALL); + vgAppendPathData(path, 5, cmds, coords); + + fill = vgCreatePaint(); + vgSetParameterfv(fill, VG_PAINT_COLOR, 4, black_color); + vgSetPaint(fill, VG_FILL_PATH); + + vgDrawPath(path, VG_FILL_PATH); + + vgDestroyPath(path); + vgDestroyPaint(fill); +} + +static void draw_marks(VGPath path) +{ + VGfloat point[2], tangent[2]; + int i = 0; + + for (i = 0; i < 1300; i += 50) { + vgPointAlongPath(path, 0, 6, i, + point + 0, point + 1, + tangent + 0, tangent + 1); + draw_point(point[0], point[1]); + } +} + +static void +init(void) +{ + static const VGubyte cmds[6] = {VG_MOVE_TO_ABS, VG_LINE_TO_ABS, VG_LINE_TO_ABS, VG_LINE_TO_ABS, + VG_LINE_TO_ABS, VG_CLOSE_PATH}; + static const VGfloat coords[] = { 0, 200, + 300, 200, + 50, 0, + 150, 300, + 250, 0}; + path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0, + VG_PATH_CAPABILITY_ALL); + vgAppendPathData(path, 6, cmds, coords); + + fill = vgCreatePaint(); + vgSetParameterfv(fill, VG_PAINT_COLOR, 4, green_color); + vgSetPaint(fill, VG_FILL_PATH); + + vgSetfv(VG_CLEAR_COLOR, 4, white_color); +} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ + vgLoadIdentity(); +} + +static void +draw(void) +{ + VGfloat point[2], tangent[2]; + int i = 0; + + vgClear(0, 0, window_width(), window_height()); + + vgSetPaint(fill, VG_FILL_PATH); + vgDrawPath(path, VG_FILL_PATH); + + draw_marks(path); + + + vgFlush(); +} + + +int main(int argc, char **argv) +{ + return run(argc, argv, init, reshape, + draw, 0); +} diff --git a/progs/egl/openvg/trivial/stroke.c b/progs/egl/openvg/trivial/stroke.c new file mode 100644 index 00000000000..58ae5b7bc87 --- /dev/null +++ b/progs/egl/openvg/trivial/stroke.c @@ -0,0 +1,116 @@ +#include "eglcommon.h" + +#include <VG/openvg.h> +#include <X11/keysym.h> +#include <stdio.h> + +const VGfloat white_color[4] = {1.0, 1.0, 1.0, 1.0}; +const VGfloat color[4] = {0.4, 0.1, 1.0, 1.0}; + +VGPath path; +VGPaint fill; + +VGint cap_style = VG_CAP_BUTT; +VGint join_style = VG_JOIN_MITER; + +static void +init(void) +{ +#if 0 + static const VGubyte cmds[] = {VG_MOVE_TO_ABS, + VG_CUBIC_TO_ABS, + }; + static const VGfloat coords[] = {30, 30, 264, 0, 0, 264, 234, 234 + }; +#else + static const VGubyte cmds[] = {VG_MOVE_TO_ABS, + VG_LINE_TO_ABS, + VG_LINE_TO_ABS + }; + static const VGfloat coords[] = {30, 30, 202, 30, 150, 224 + }; +#endif + VGfloat dash_pattern[2] = { 20.f, 20.f }; + path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, 0, 0, 0, + VG_PATH_CAPABILITY_APPEND_TO); + vgAppendPathData(path, 3, cmds, coords); + + fill = vgCreatePaint(); + vgSetParameterfv(fill, VG_PAINT_COLOR, 4, color); + vgSetPaint(fill, VG_FILL_PATH); + + vgSetfv(VG_CLEAR_COLOR, 4, white_color); + vgSetf(VG_STROKE_LINE_WIDTH, 20); + vgSeti(VG_STROKE_CAP_STYLE, cap_style); + vgSeti(VG_STROKE_JOIN_STYLE, join_style); + vgSetfv(VG_STROKE_DASH_PATTERN, 2, dash_pattern); + vgSetf(VG_STROKE_DASH_PHASE, 0.0f); +} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ + vgLoadIdentity(); +} + +static void +draw(void) +{ + vgClear(0, 0, window_width(), window_height()); + vgDrawPath(path, VG_STROKE_PATH); + + vgFlush(); +} + +static int key_press(unsigned key) +{ + switch(key) { + case XK_c: + case XK_C: + ++cap_style; + if (cap_style > VG_CAP_SQUARE) + cap_style = VG_CAP_BUTT; + switch(cap_style) { + case VG_CAP_BUTT: + fprintf(stderr, "Cap style 'butt'\n"); + break; + case VG_CAP_ROUND: + fprintf(stderr, "Cap style 'round'\n"); + break; + case VG_CAP_SQUARE: + fprintf(stderr, "Cap style 'square'\n"); + break; + } + vgSeti(VG_STROKE_CAP_STYLE, cap_style); + break; + case XK_j: + case XK_J: + ++join_style; + if (join_style > VG_JOIN_BEVEL) + join_style = VG_JOIN_MITER; + switch(join_style) { + case VG_JOIN_MITER: + fprintf(stderr, "Join style 'miter'\n"); + break; + case VG_JOIN_ROUND: + fprintf(stderr, "Join style 'round'\n"); + break; + case VG_JOIN_BEVEL: + fprintf(stderr, "Join style 'bevel'\n"); + break; + } + vgSeti(VG_STROKE_JOIN_STYLE, join_style); + break; + default: + break; + } + + return VG_TRUE; +} + +int main(int argc, char **argv) +{ + return run(argc, argv, init, reshape, + draw, key_press); +} diff --git a/progs/egl/openvg/trivial/stroke2.c b/progs/egl/openvg/trivial/stroke2.c new file mode 100644 index 00000000000..ce950c1886c --- /dev/null +++ b/progs/egl/openvg/trivial/stroke2.c @@ -0,0 +1,207 @@ +#include "eglcommon.h" + +#include <VG/openvg.h> +#include <X11/keysym.h> +#include <stdio.h> + +VGPaint stroke; +VGPath target; +VGPath lines; + +VGfloat xform[9]; +VGfloat color1[4]; +VGfloat color2[4]; +VGfloat bgCol[4]; + +static void +init(void) +{ + VGubyte lineCmds[6]; + VGfloat lineCoords[8]; + VGfloat arcCoords[5]; + VGubyte sccCmd[1]; + VGubyte scCmd[1]; + VGubyte lccCmd[1]; + VGubyte lcCmd[1]; + VGubyte moveCmd[1]; + VGfloat moveCoords[2]; + VGint i; + + bgCol[0] = 1.0f; + bgCol[1] = 1.0f; + bgCol[2] = 1.0f; + bgCol[3] = 1.0f; + + vgSetfv(VG_CLEAR_COLOR, 4, bgCol); + vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_NONANTIALIASED); + + stroke = vgCreatePaint(); + /* Red */ + color1[0] = 1.0f; + color1[1] = 0.0f; + color1[2] = 0.0f; + color1[3] = 1.0f; + + /* Orange */ + color2[0] = 1.0000f; + color2[1] = 1.0f; + color2[2] = 0.0f; + color2[3] = 1.0f; + vgSetPaint(stroke, VG_STROKE_PATH); + + vgSeti(VG_STROKE_CAP_STYLE, VG_CAP_SQUARE); + + { + VGfloat temp[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; + for (i = 0; i < 9; i++) + { + xform[i] = temp[i]; + } + } + vgGetMatrix(xform); + + target = vgCreatePath(VG_PATH_FORMAT_STANDARD, + VG_PATH_DATATYPE_F, 1, 0, 0, 0, VG_PATH_CAPABILITY_TRANSFORM_TO); + +#if 0 + /* Line path */ + { + VGubyte temp[6] = {VG_MOVE_TO_ABS, VG_VLINE_TO_REL, + VG_MOVE_TO_ABS, VG_VLINE_TO_REL, + VG_HLINE_TO_REL, VG_VLINE_TO_REL}; + for (i = 0; i < 6; i++) + { + lineCmds[i] = temp[i]; + } + } + { + VGfloat temp[8] = {0.5f, 0.8f, -0.6f, 0.28f, 0.6f, -0.4f, 0.44f, 0.4f}; + for (i = 0; i < 8; i++) + { + lineCoords[i] = temp[i] * window_width(); + } + } +#else + { + VGfloat temp[5] = {0.35f, 0.15f, 29, 0.3f, 0.4f}; + for (i = 0; i < 5; i++) + { + arcCoords[i] = temp[i] * window_width(); + } + arcCoords[2] = 29; + } + + { + VGubyte temp[1] = {VG_SCCWARC_TO_ABS}; + for (i = 0; i < 1; i++) + { + sccCmd[i] = temp[i]; + } + } + { + VGubyte temp[1] = {VG_SCWARC_TO_ABS}; + for (i = 0; i < 1; i++) + { + scCmd[i] = temp[i]; + } + } + { + VGubyte temp[1] = {VG_LCCWARC_TO_ABS}; + for (i = 0; i < 1; i++) + { + lccCmd[i] = temp[i]; + } + } + { + VGubyte temp[1] = {VG_LCWARC_TO_ABS}; + for (i = 0; i < 1; i++) + { + lcCmd[i] = temp[i]; + } + } + + { + VGubyte temp[1] = {VG_MOVE_TO_ABS}; + for (i = 0; i < 1; i++) + { + moveCmd[i] = temp[i]; + } + } + { + VGfloat temp[2] = {0.7f, 0.6f}; + for (i = 0; i < 2; i++) + { + moveCoords[i] = temp[i] * window_width(); + } + } +#endif + + lines = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, 1, + 0, 0, 0, + VG_PATH_CAPABILITY_APPEND_TO| + VG_PATH_CAPABILITY_TRANSFORM_FROM); +#if 0 + vgAppendPathData(lines, 6, lineCmds, lineCoords); +#else + vgAppendPathData(lines, 1, moveCmd, moveCoords); + vgAppendPathData(lines, 1, sccCmd, arcCoords); + vgAppendPathData(lines, 1, moveCmd, moveCoords); + vgAppendPathData(lines, 1, scCmd, arcCoords); + vgAppendPathData(lines, 1, moveCmd, moveCoords); + vgAppendPathData(lines, 1, lccCmd, arcCoords); + vgAppendPathData(lines, 1, moveCmd, moveCoords); + vgAppendPathData(lines, 1, lcCmd, arcCoords); +#endif + + vgLoadIdentity(); + vgTranslate(0.25f * window_width(), 0.25f * window_height()); + vgRotate(30); + vgTranslate(-0.25f * window_width(), -0.25f * window_height()); + vgTransformPath(target, lines);} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ +} + +static void +draw(void) +{ + vgClear(0, 0, window_width(), window_height()); + vgLoadMatrix(xform); + vgLoadIdentity(); + vgTranslate(0.25f * window_width(), 0.25f * window_height()); + vgRotate(30); + vgTranslate(-0.25f * window_width(), -0.25f * window_height()); + vgSetf(VG_STROKE_LINE_WIDTH, 7); + vgSetParameterfv(stroke, VG_PAINT_COLOR, 4, color1); + vgDrawPath(lines, VG_STROKE_PATH); + + vgLoadMatrix(xform); + vgSetParameterfv(stroke, VG_PAINT_COLOR, 4, color2); + vgSetf(VG_STROKE_LINE_WIDTH, 3); + vgDrawPath(target, VG_STROKE_PATH); +} + +static int key_press(unsigned key) +{ + switch(key) { + case XK_c: + case XK_C: + break; + case XK_j: + case XK_J: + break; + default: + break; + } + + return VG_TRUE; +} + +int main(int argc, char **argv) +{ + return run(argc, argv, init, reshape, + draw, key_press); +} diff --git a/progs/egl/openvg/trivial/vguarc.c b/progs/egl/openvg/trivial/vguarc.c new file mode 100644 index 00000000000..8d971d5c09c --- /dev/null +++ b/progs/egl/openvg/trivial/vguarc.c @@ -0,0 +1,74 @@ +#include "eglcommon.h" + +#include <VG/openvg.h> +#include <VG/vgu.h> + +const VGfloat white_color[4] = {1.0, 1.0, 1.0, 1.0}; +const VGfloat color[4] = {0.4, 0.1, 1.0, 1.0}; + +VGPath path; +VGPaint paint; + + +static void +init(void) +{ + VGfloat clearColor[] = {0.0f, 0.0f, 0.0f, 1.0f};/* black color */ + VGfloat greenColor[] = {0.0f, 1.0f, 0.0f, 1.0f};/* green color */ + VGint arcType = VGU_ARC_OPEN; + VGfloat x, y, w, h, startAngle, angleExtent; + + x = 150; + y = 150; + w = 150; + h = 150; +#if 0 + startAngle = -540.0f; + angleExtent = 270.0f; +#else + startAngle = 270.0f; + angleExtent = 90.0f; +#endif + + paint = vgCreatePaint(); + + vgSetPaint(paint, VG_STROKE_PATH); + vgSetParameterfv(paint, VG_PAINT_COLOR, 4, greenColor); + vgSetParameteri( paint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR); + vgSetf(VG_STROKE_LINE_WIDTH, 6.0f); + vgSeti(VG_RENDERING_QUALITY, VG_RENDERING_QUALITY_NONANTIALIASED); + vgSetfv(VG_CLEAR_COLOR, 4, clearColor); + + path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, + 1.0f, 0.0f, 0, 0, VG_PATH_CAPABILITY_ALL); + + vguArc(path, x, y, w, h, startAngle, angleExtent, arcType); + + vgSeti(VG_STROKE_CAP_STYLE, VG_CAP_BUTT); + vgSeti(VG_STROKE_JOIN_STYLE, VG_JOIN_BEVEL); + vgSetf(VG_STROKE_MITER_LIMIT, 4.0f); +} + +/* new window size or exposure */ +static void +reshape(int w, int h) +{ + vgLoadIdentity(); +} + +static void +draw(void) +{ + vgClear(0, 0, window_width(), window_height()); + vgDrawPath(path, VG_STROKE_PATH); + + vgFlush(); +} + + +int main(int argc, char **argv) +{ + // set_window_size(64, 63); + return run(argc, argv, init, reshape, + draw, 0); +} |