diff options
Diffstat (limited to 'hacks/glx/gleidescope.c')
| -rw-r--r-- | hacks/glx/gleidescope.c | 1619 |
1 files changed, 0 insertions, 1619 deletions
diff --git a/hacks/glx/gleidescope.c b/hacks/glx/gleidescope.c deleted file mode 100644 index b33770a..0000000 --- a/hacks/glx/gleidescope.c +++ /dev/null @@ -1,1619 +0,0 @@ -/* -*- Mode: C; tab-width: 4 -*- */ -/* vim: set ai ts=4 sw=4: */ - -#if 0 -/*static const char sccsid[] = "@(#)gleidescope.c 1.0 03/06/27 xlockmore";*/ -#endif - -/* enable -grab switch for animations */ -#undef GRAB - -#undef DISPLAY_TEXTURE - -/*- - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation. - * - * This file is provided AS IS with no warranties of any kind. The author - * shall have no liability with respect to the infringement of copyrights, - * trade secrets or any patents by this file or any part thereof. In no - * event will the author be liable for any lost revenue or profits or - * other special, indirect and consequential damages. - * - * Revision History: - * - * 20030627 1.0 acd First Release. - * Texture loading code from 'glplanet' - * by Jamie Zawinski <jwz@jwz.org> - * 20030810 1.1 acd Added size flag. - * Now grabs screen / video / picture - * (uses code from 'glslideshow' by - * Mike Oliphant, Ben Buxton, Jamie Zawinski). - * Added -duration. - * Added mouse code. - * Added fade code (also from glslideshow). - * 20031013 1.2 acd Migrated to compile without warnings under - * xscreensaver 4.13. - * 20031023 1.3 acd Better code to limit twisting speeds. - * Tweaked initial rotation values. - * Move, Rotate, Zoom now chosen at random if - * no preference is given. - * Made grid slightly bigger so you can't see - * the edge when zooming and moving. - * 20061226 1.4 acd Now uses GL Display Lists. - * 20070318 1.5 acd Generates textures. - * Fixed texture size problem (and introduced another). - * 20070412 1.6 acd Textures now have independant sizes. - * 20070413 1.7 acd Added Lissajous movement pattern. - * 20070414 1.8 acd Added corners movement pattern. - * 20080319 1.9 acd Changes to arguments for saner gleidescope.xml. - * - * TODO - * generate textures myself - render random shapes to 256x256 texture. (done) - * lower res for checks and random - use 256 and 4x4 or 8x8 pixels. (disabled for now) - * gnome-saver doesn't let you specify source directory so add that to this. - * image loading routine is too slow - rotation grinds to a halt - stop using it. (better in version 5) - * image loading also looks bad for non-square images - edges are black. (fixed) - * possible to see edge of the world on widescreen terminals - use larger grid and hidden hex removal? - * fading textures may have different max_tx - use two sets. (done) - * choice of movement patterns. (3 implemented, chooseable at compile time) - * look into rangle and tangle. - */ - -/* -**---------------------------------------------------------------------------- -** Defines -**---------------------------------------------------------------------------- -*/ - -#ifdef STANDALONE -# define DEFAULTS \ - "*delay: 20000 \n" \ - "*showFPS: False \n" \ - "*size: 0 \n" \ - "*useSHM: True \n" \ - "*suppressRotationAnimation: True\n" \ - -# define release_gleidescope 0 -# include "xlockmore.h" /* from the xscreensaver distribution */ -#else /* !STANDALONE */ -# include "xlock.h" /* from the xlockmore distribution */ -#endif /* !STANDALONE */ - -#ifdef USE_GL - -#include "colors.h" -#include "ximage-loader.h" -#include "grab-ximage.h" - -#ifdef GRAB -void grab_frame(Display *display, Window window); -#endif - -/* acd TODO should all these be in gleidestruct? */ -/* they can't be, because of the idiotic way the xlockmore "argtype vars" - interface works. -jwz */ -#ifdef GRAB -static Bool grab; /* grab images */ -#endif -static Bool move; /* moving camera */ -static Bool nomove; /* no moving camera */ -static Bool rotate; /* rotate in place */ -static Bool norotate; /* no rotate in place */ -static Bool zoom; /* zooming camera */ -static Bool nozoom; /* no zooming camera */ -static char *image_str; /* name of texture to load */ -static int duration; /* length of time to display grabbed image */ - -#define MAX_CAM_SPEED 1.0 -#define MAX_ANGLE_VEL 1.0 -#define INITIAL_ANGLE_VEL 0.2 -#define INITIAL_ANGLE_ACC 0.001 -#define TWISTING_PROBABILITY 1000 /* 1 in ... of change of acceleration */ - -#define RADIANS (M_PI / 180) -#define ANGLE_120 (M_PI * 2 / 3) -#define ANGLE_240 (M_PI * 4 / 3) - -#define DEF_GRAB "False" -#define DEF_MOVE "False" -#define DEF_NOMOVE "False" -#define DEF_ROTATE "False" -#define DEF_NOROTATE "False" -#define DEF_ZOOM "False" -#define DEF_NOZOOM "False" -#define DEF_IMAGE "DEFAULT" -#define DEF_DURATION "30" - - -static XrmOptionDescRec opts[] = -{ -#ifdef GRAB - {"-grab", ".gleidescope.grab", XrmoptionNoArg, "true"}, -#endif - {"-move", ".gleidescope.move", XrmoptionNoArg, "true"}, - {"-no-move", ".gleidescope.nomove", XrmoptionNoArg, "true"}, - {"-rotate", ".gleidescope.rotate", XrmoptionNoArg, "true"}, - {"-no-rotate", ".gleidescope.norotate", XrmoptionNoArg, "true"}, - {"-zoom", ".gleidescope.zoom", XrmoptionNoArg, "true"}, - {"-no-zoom", ".gleidescope.nozoom", XrmoptionNoArg, "true"}, - {"-image", ".gleidescope.image", XrmoptionSepArg, "DEFAULT"}, - {"-duration", ".gleidescope.duration", XrmoptionSepArg, "30"}, -}; - - -static argtype vars[] = { -#ifdef GRAB - {&grab, "grab", "Grab", DEF_GRAB, t_Bool}, -#endif - {&move, "move", "Move", DEF_MOVE, t_Bool}, - {&nomove, "nomove", "noMove", DEF_NOMOVE, t_Bool}, - {&rotate, "rotate", "Rotate", DEF_ROTATE, t_Bool}, - {&norotate, "norotate", "noRotate", DEF_NOROTATE, t_Bool}, - {&zoom, "zoom", "Zoom", DEF_ZOOM, t_Bool}, - {&nozoom, "nozoom", "noZoom", DEF_NOZOOM, t_Bool}, - {&image_str, "image", "Image", DEF_IMAGE, t_String}, - {&duration, "duration", "Duration", DEF_DURATION, t_Int}, -}; - -static OptionStruct desc[] = { -#ifdef GRAB - {"-grab", "grab images to create animation"}, -#endif - {"-move", "camera will move"}, - {"-no-move", "camera won't move"}, - {"-rotate", "camera will rotate"}, - {"-no-rotate", "camera won't rotate"}, - {"-zoom", "camera will zoom"}, - {"-no-zoom", "camera won't zoom"}, - {"-image", "xpm / xbm image file to use for texture"}, - {"-duration", "length of time texture will be used"}, -}; - -ENTRYPOINT ModeSpecOpt gleidescope_opts = { - sizeof opts / sizeof opts[0], opts, - sizeof vars / sizeof vars[0], vars, - desc -}; - -#ifdef USE_MODULES -ModStruct gleidescope_description = { - "gleidescope", "init_gleidescope", "draw_gleidescope", NULL, - "draw_gleidescope", "init_gleidescope", "free_gleidescope", - &gleidescope_opts, 1000, 1, 2, 1, 4, 1.0, "", - "GL Kaleidescope", 0, NULL}; -#endif - -/* -**----------------------------------------------------------------------------- -** Typedefs -**----------------------------------------------------------------------------- -*/ - -typedef struct hex_s { - GLfloat x, y, z; /* position */ -} hex_t; - -typedef struct { - GLfloat x; - GLfloat y; - GLfloat z; -} vectorf; - -typedef struct { - GLfloat x; - GLfloat y; -} vector2f; - -typedef struct { - GLuint id; /* opengl texture id */ - GLfloat width, height; /* texture width and height */ - GLfloat min_tx, min_ty; /* minimum texture sizes */ - GLfloat max_tx, max_ty; /* maximum texture sizes */ - time_t start_time; - Bool button_down_p; - Bool mipmap_p; - Bool waiting_for_image_p; - /* r_phase is for triangle rotation speed */ - GLfloat x_period, y_period, r_period; - GLfloat x_phase, y_phase, r_phase; -} texture; - -#define MAX_FADE 500 /* number of fade cycles */ - -typedef struct { - float cam_x_speed, cam_z_speed, cam_y_speed; - int cam_x_phase, cam_z_phase, cam_y_phase; - float tic; - GLXContext *glx_context; - Window window; - texture textures[2]; /* texture handles */ - GLuint visible; /* index for current texture */ - GLint fade; - time_t start_time; - Bool button_down_p; - - int size; - int list; - - float tangle; /* texture angle (degrees) */ - float tangle_vel; /* texture velocity */ - float tangle_acc; /* texture acceleration */ - - float rangle; /* rotate angle */ - float rangle_vel; /* rotate velocity */ - float rangle_acc; /* rotate acceleration */ - - /* mouse */ - int xstart; - int ystart; - double xmouse; - double ymouse; - - Bool mipmap_p; - Bool waiting_for_image_p; - -} gleidestruct; - -#define frandrange(x, y) (x + frand(y - x)) - -#define XOFFSET (0.8660254f) /* sin 60' */ -#define YOFFSET (1.5000000f) /* cos 60' + 1 */ - -#if 0 - -#define SIZE 3 - -/* generates a grid with edges of given size */ -/* acd TODO - replace hex[] with this and allow size and distance as parameters */ - -int -generate_grid(int size) - - int i, x, y; - - gp->size--; - - i = gp->size; - for (y = -size ; y <= size ; y++) { - for (x = -i ; x <= i ; x += 2) { - printf("{XOFFSET * %d, YOFFSET * %d, 0},\n", x, y); - } - printf("\n"); - if (y < 0) { - i++; - } else { - i--; - } - } - return 0; -} -#endif - -/* acd - this is terrible - 120+ hexes */ -static const hex_t hex[] = { - /* edges of size 7 */ - /* number of hexagons required to cover screen depends on camera distance */ - /* at a distance of 10 this is just about enough. */ - {XOFFSET * -6, YOFFSET * -6, 0}, - {XOFFSET * -4, YOFFSET * -6, 0}, - {XOFFSET * -2, YOFFSET * -6, 0}, - {XOFFSET * 0, YOFFSET * -6, 0}, - {XOFFSET * 2, YOFFSET * -6, 0}, - {XOFFSET * 4, YOFFSET * -6, 0}, - {XOFFSET * 6, YOFFSET * -6, 0}, - - {XOFFSET * -7, YOFFSET * -5, 0}, - {XOFFSET * -5, YOFFSET * -5, 0}, - {XOFFSET * -3, YOFFSET * -5, 0}, - {XOFFSET * -1, YOFFSET * -5, 0}, - {XOFFSET * 1, YOFFSET * -5, 0}, - {XOFFSET * 3, YOFFSET * -5, 0}, - {XOFFSET * 5, YOFFSET * -5, 0}, - {XOFFSET * 7, YOFFSET * -5, 0}, - - {XOFFSET * -8, YOFFSET * -4, 0}, - {XOFFSET * -6, YOFFSET * -4, 0}, - {XOFFSET * -4, YOFFSET * -4, 0}, - {XOFFSET * -2, YOFFSET * -4, 0}, - {XOFFSET * 0, YOFFSET * -4, 0}, - {XOFFSET * 2, YOFFSET * -4, 0}, - {XOFFSET * 4, YOFFSET * -4, 0}, - {XOFFSET * 6, YOFFSET * -4, 0}, - {XOFFSET * 8, YOFFSET * -4, 0}, - - {XOFFSET * -9, YOFFSET * -3, 0}, - {XOFFSET * -7, YOFFSET * -3, 0}, - {XOFFSET * -5, YOFFSET * -3, 0}, - {XOFFSET * -3, YOFFSET * -3, 0}, - {XOFFSET * -1, YOFFSET * -3, 0}, - {XOFFSET * 1, YOFFSET * -3, 0}, - {XOFFSET * 3, YOFFSET * -3, 0}, - {XOFFSET * 5, YOFFSET * -3, 0}, - {XOFFSET * 7, YOFFSET * -3, 0}, - {XOFFSET * 9, YOFFSET * -3, 0}, - - {XOFFSET * -10, YOFFSET * -2, 0}, - {XOFFSET * -8, YOFFSET * -2, 0}, - {XOFFSET * -6, YOFFSET * -2, 0}, - {XOFFSET * -4, YOFFSET * -2, 0}, - {XOFFSET * -2, YOFFSET * -2, 0}, - {XOFFSET * 0, YOFFSET * -2, 0}, - {XOFFSET * 2, YOFFSET * -2, 0}, - {XOFFSET * 4, YOFFSET * -2, 0}, - {XOFFSET * 6, YOFFSET * -2, 0}, - {XOFFSET * 8, YOFFSET * -2, 0}, - {XOFFSET * 10, YOFFSET * -2, 0}, - - {XOFFSET * -11, YOFFSET * -1, 0}, - {XOFFSET * -9, YOFFSET * -1, 0}, - {XOFFSET * -7, YOFFSET * -1, 0}, - {XOFFSET * -5, YOFFSET * -1, 0}, - {XOFFSET * -3, YOFFSET * -1, 0}, - {XOFFSET * -1, YOFFSET * -1, 0}, - {XOFFSET * 1, YOFFSET * -1, 0}, - {XOFFSET * 3, YOFFSET * -1, 0}, - {XOFFSET * 5, YOFFSET * -1, 0}, - {XOFFSET * 7, YOFFSET * -1, 0}, - {XOFFSET * 9, YOFFSET * -1, 0}, - {XOFFSET * 11, YOFFSET * -1, 0}, - - {XOFFSET * -12, YOFFSET * 0, 0}, - {XOFFSET * -10, YOFFSET * 0, 0}, - {XOFFSET * -8, YOFFSET * 0, 0}, - {XOFFSET * -6, YOFFSET * 0, 0}, - {XOFFSET * -4, YOFFSET * 0, 0}, - {XOFFSET * -2, YOFFSET * 0, 0}, - {XOFFSET * 0, YOFFSET * 0, 0}, - {XOFFSET * 2, YOFFSET * 0, 0}, - {XOFFSET * 4, YOFFSET * 0, 0}, - {XOFFSET * 6, YOFFSET * 0, 0}, - {XOFFSET * 8, YOFFSET * 0, 0}, - {XOFFSET * 10, YOFFSET * 0, 0}, - {XOFFSET * 12, YOFFSET * 0, 0}, - - {XOFFSET * -11, YOFFSET * 1, 0}, - {XOFFSET * -9, YOFFSET * 1, 0}, - {XOFFSET * -7, YOFFSET * 1, 0}, - {XOFFSET * -5, YOFFSET * 1, 0}, - {XOFFSET * -3, YOFFSET * 1, 0}, - {XOFFSET * -1, YOFFSET * 1, 0}, - {XOFFSET * 1, YOFFSET * 1, 0}, - {XOFFSET * 3, YOFFSET * 1, 0}, - {XOFFSET * 5, YOFFSET * 1, 0}, - {XOFFSET * 7, YOFFSET * 1, 0}, - {XOFFSET * 9, YOFFSET * 1, 0}, - {XOFFSET * 11, YOFFSET * 1, 0}, - - {XOFFSET * -10, YOFFSET * 2, 0}, - {XOFFSET * -8, YOFFSET * 2, 0}, - {XOFFSET * -6, YOFFSET * 2, 0}, - {XOFFSET * -4, YOFFSET * 2, 0}, - {XOFFSET * -2, YOFFSET * 2, 0}, - {XOFFSET * 0, YOFFSET * 2, 0}, - {XOFFSET * 2, YOFFSET * 2, 0}, - {XOFFSET * 4, YOFFSET * 2, 0}, - {XOFFSET * 6, YOFFSET * 2, 0}, - {XOFFSET * 8, YOFFSET * 2, 0}, - {XOFFSET * 10, YOFFSET * 2, 0}, - - {XOFFSET * -9, YOFFSET * 3, 0}, - {XOFFSET * -7, YOFFSET * 3, 0}, - {XOFFSET * -5, YOFFSET * 3, 0}, - {XOFFSET * -3, YOFFSET * 3, 0}, - {XOFFSET * -1, YOFFSET * 3, 0}, - {XOFFSET * 1, YOFFSET * 3, 0}, - {XOFFSET * 3, YOFFSET * 3, 0}, - {XOFFSET * 5, YOFFSET * 3, 0}, - {XOFFSET * 7, YOFFSET * 3, 0}, - {XOFFSET * 9, YOFFSET * 3, 0}, - - {XOFFSET * -8, YOFFSET * 4, 0}, - {XOFFSET * -6, YOFFSET * 4, 0}, - {XOFFSET * -4, YOFFSET * 4, 0}, - {XOFFSET * -2, YOFFSET * 4, 0}, - {XOFFSET * 0, YOFFSET * 4, 0}, - {XOFFSET * 2, YOFFSET * 4, 0}, - {XOFFSET * 4, YOFFSET * 4, 0}, - {XOFFSET * 6, YOFFSET * 4, 0}, - {XOFFSET * 8, YOFFSET * 4, 0}, - - {XOFFSET * -7, YOFFSET * 5, 0}, - {XOFFSET * -5, YOFFSET * 5, 0}, - {XOFFSET * -3, YOFFSET * 5, 0}, - {XOFFSET * -1, YOFFSET * 5, 0}, - {XOFFSET * 1, YOFFSET * 5, 0}, - {XOFFSET * 3, YOFFSET * 5, 0}, - {XOFFSET * 5, YOFFSET * 5, 0}, - {XOFFSET * 7, YOFFSET * 5, 0}, - - {XOFFSET * -6, YOFFSET * 6, 0}, - {XOFFSET * -4, YOFFSET * 6, 0}, - {XOFFSET * -2, YOFFSET * 6, 0}, - {XOFFSET * 0, YOFFSET * 6, 0}, - {XOFFSET * 2, YOFFSET * 6, 0}, - {XOFFSET * 4, YOFFSET * 6, 0}, - {XOFFSET * 6, YOFFSET * 6, 0}, -}; - -/* -**---------------------------------------------------------------------------- -** Local Variables -**---------------------------------------------------------------------------- -*/ - -static gleidestruct *gleidescope = NULL; - -#if 0 -/* - *load defaults in config structure - */ -static void setdefaultconfig(void) -{ -#ifdef GRAB - grab = False; -#endif - move = False; - rotate = False; - zoom = False; - image = NULL; -} -#endif - -ENTRYPOINT Bool -gleidescope_handle_event(ModeInfo *mi, XEvent *event) -{ - gleidestruct *gp = &gleidescope[MI_SCREEN(mi)]; - - /* - printf("event:%d\n", event->xany.type); - printf("button:%d\n", event->xbutton.button); - */ - if (event->xany.type == ButtonPress) - { - if (event->xbutton.button == Button1 || - event->xbutton.button == Button3) - { - /* store initial values of mouse */ - gp->xstart = event->xbutton.x; - gp->ystart = event->xbutton.y; - - /* button is down */ - gp->button_down_p = True; - return True; - } -#if 0 /* TODO */ - else if (event->xbutton.button == Button4) - { - /* zoom in */ - return True; - } - else if (event->xbutton.button == Button5) - { - /* zoom out */ - return True; - } -#endif - } else if (event->xany.type == ButtonRelease) - { - if (event->xbutton.button == Button1 || - event->xbutton.button == Button3) - { - /* button is up */ - gp->button_down_p = False; - return True; - } - } else if (event->xany.type == MotionNotify) - { - if (gp->button_down_p) - { - /* update mouse position */ - gp->xmouse += (double)(event->xmotion.x - gp->xstart) / MI_WIDTH(mi); - gp->ymouse += (double)(event->xmotion.y - gp->ystart) / MI_HEIGHT(mi); - gp->xstart = event->xmotion.x; - gp->ystart = event->xmotion.y; - - return True; - } - } - else if (screenhack_event_helper (MI_DISPLAY(mi), MI_WINDOW(mi), event)) - { - gp->start_time = -1; - gp->fade = 0; - return True; - } - - return False; -} - - -static void -image_loaded_cb (const char *filename, XRectangle *geometry, - int image_width, int image_height, - int texture_width, int texture_height, - void *closure) -{ - texture *tp = (texture *) closure; - -#if 0 - gp->max_tx = (GLfloat) image_width / texture_width; - gp->max_ty = (GLfloat) image_height / texture_height; -#endif - - /* new - taken from flipscreen */ - tp->width = texture_width; - tp->height = texture_height; - tp->min_tx = (GLfloat) geometry->x / tp->width; - tp->min_ty = (GLfloat) geometry->y / tp->height; - tp->max_tx = (GLfloat) (geometry->x + geometry->width) / tp->width; - tp->max_ty = (GLfloat) (geometry->y + geometry->height) / tp->height; - -#ifdef DEBUG - printf("Image w,h: (%d, %d)\n", image_width, image_height); - printf("Texture w,h: (%d, %d)\n", texture_width, texture_height); - printf("Geom x,y: (%d, %d)\n", geometry->x, geometry->y); - printf("Geom w,h: (%d, %d)\n", geometry->width, geometry->height); - printf("Max Tx,Ty: (%f, %f)\n", tp->max_tx, tp->max_ty); -#endif - - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - (tp->mipmap_p ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR)); - - tp->waiting_for_image_p = False; - tp->start_time = time ((time_t *) 0); -} - -static void -getSnapshot(ModeInfo *mi, texture *texture) -{ - gleidestruct *gp = &gleidescope[MI_SCREEN(mi)]; - -#ifdef DEBUG - printf("getSnapshot"); -#endif - - if (MI_IS_WIREFRAME(mi)) - return; - - gp->mipmap_p = True; - load_texture_async (mi->xgwa.screen, mi->window, - *gp->glx_context, 0, 0, gp->mipmap_p, - texture->id, image_loaded_cb, texture); - texture->start_time = time((time_t *)0); -} - -#define TEXTURE_SIZE 256 - -static void -plot(unsigned char *buffer, int x, int y, int r, int g, int b, int a) { - int c; - if (x < 0 || x >= TEXTURE_SIZE || y < 0 || y >= TEXTURE_SIZE) { - return; - } - c = ((x * TEXTURE_SIZE) + y) * 4; - /*printf("(%d,%d)[%d]\n", x, y, c);*/ - buffer[c + 0] = r; - buffer[c + 1] = g; - buffer[c + 2] = b; - buffer[c + 3] = a; -} - -#if 0 -static void -plot2(unsigned char *buffer, int x, int y, int r, int g, int b, int a) { - int c; - if (x < 0 || x >= TEXTURE_SIZE || y < 0 || y >= TEXTURE_SIZE) { - return; - } - c = ((x * TEXTURE_SIZE) + y) * 4; - /*printf("(%d,%d)[%d]\n", x, y, c);*/ - buffer[c + 0] = r; - buffer[c + 1] = g; - buffer[c + 2] = b; - buffer[c + 3] = a; - - if (y + 1 < TEXTURE_SIZE) { - buffer[c + 4] = r; - buffer[c + 5] = g; - buffer[c + 6] = b; - buffer[c + 7] = a; - } - - if (x + 1 < TEXTURE_SIZE) { - c += (TEXTURE_SIZE * 4); - buffer[c + 0] = r; - buffer[c + 1] = g; - buffer[c + 2] = b; - buffer[c + 3] = a; - if (y + 1 < TEXTURE_SIZE) { - buffer[c + 4] = r; - buffer[c + 5] = g; - buffer[c + 6] = b; - buffer[c + 7] = a; - } - } -} -#endif - -/* draw geometric shapes to texture */ -/* modifies passed in buffer */ -static void -draw_shapes (unsigned char *buffer) { - int a = 0xff; - int x, y, w, h; - int i, j; - int s; - float left, right; - - for (i = 0 ; i < TEXTURE_SIZE * TEXTURE_SIZE * 4 ; i += 4) { - buffer[i + 0] = 0x00; - buffer[i + 1] = 0x00; - buffer[i + 2] = 0x00; - buffer[i + 3] = 0xff; - } - - for (s = 0 ; s < 25 ; s++) { - int shape = random() % 3; - - /* 8 bits */ - int r = (random() & 0xff); - int g = (random() & 0xff); - int b = (random() & 0xff); - - switch (shape) { - case 0: - /* rectangle */ - x = (random() % TEXTURE_SIZE) - (TEXTURE_SIZE / 4); /* top left */ - y = (random() % TEXTURE_SIZE) - (TEXTURE_SIZE / 4); - w = 10 + random() % (TEXTURE_SIZE / 4); /* size */ - h = 10 + random() % (TEXTURE_SIZE / 4); -#ifdef DEBUG - printf("Rectangle: (%d, %d)(%d, %d)\n", x, y, w, h); -#endif - if (x < 0) { - x = 0; - } - if (y < 0) { - y = 0; - } - for (i = x ; i < x + w && i < TEXTURE_SIZE; i++) { - for (j = y ; j < y + h && j < TEXTURE_SIZE; j++) { - plot(buffer, i, j, r, g, b, a); - } - } - break; - - case 1: - /* circle */ - x = random() % TEXTURE_SIZE; /* centre */ - y = random() % TEXTURE_SIZE; - h = 10 + random() % (TEXTURE_SIZE / 8); /* radius */ -#ifdef DEBUG - printf("Circle: %d, %d, %d\n", x, y, h); -#endif - for (i = 0 ; i < h ; i++) { - int xdist = i * i; - for (j = 0 ; j < h ; j++) { - int ydist = j * j; - /* - printf("xdist: %d\n", xdist); - printf("ydist: %d\n", ydist); - printf("radius: %d\n", h * h); - */ - if ((xdist + ydist) < (h * h)) { - plot(buffer, x + i, y + j, r, b, g, a); - /* check we haven't already done these */ - if (j != 0) { - plot(buffer, x + i, y - j, r, b, g, a); - } - if (i != 0) { - plot(buffer, x - i, y + j, r, b, g, a); - if (j != 0) { - plot(buffer, x - i, y - j, r, b, g, a); - } - } - } - } - } - break; - - case 2: - /* triangle */ - x = random() % TEXTURE_SIZE; /* top */ - y = random() % TEXTURE_SIZE; - h = 10 + random() % (TEXTURE_SIZE / 4); /* height */ -#ifdef DEBUG - printf("Triangle: %d, %d, %d\n", x, y, h); -#endif - left = x; - right = x; - for (i = 0 ; i < h ; i++) { - for (j = left ; j < right ; j++) { - plot(buffer, j, y + i, r, g, b, a); - } - left -= .5; - right += .5; - } - break; - } - } -} - -static void -setup_random_texture (ModeInfo *mi, texture *texture) -{ - int width = 0, height = 0; - char buf[1024]; - unsigned char *my_data = NULL; -#if 0 - int i, j, c; - int style; - int r0, g0, b0, a0, r1, g1, b1, a1; -#endif - -#ifdef DEBUG - printf("RandomTexture\n"); -#endif - - /* use this texture */ - glBindTexture(GL_TEXTURE_2D, texture->id); - - clear_gl_error(); - - /* - * code for various generated patterns - noise, stripes, checks etc. - * random geometric shapes looked the best. - */ - -#if 0 - style = random() & 0x3; - r0 = random() & 0xff; - g0 = random() & 0xff; - b0 = random() & 0xff; - a0 = 0xff; - r1 = random() & 0xff; - g1 = random() & 0xff; - b1 = random() & 0xff; - a1 = 0xff; - - switch (style) { - case 0: /* random */ - printf("Random0\n"); - height = width = TEXTURE_SIZE; - my_data = (void *)malloc(width * height * 4); - for (i = 0 ; i < width ; i += 2) { - for (j = 0 ; j < height ; j += 2) { - r0 = random() & 0xff; - g0 = random() & 0xff; - b0 = random() & 0xff; - a0 = 0xff; - plot2(my_data, i, j, r0, g0, b0, a0); - } - } - break; - - case 1: /* shapes */ -#endif -#ifdef DEBUG - printf("Shapes\n"); -#endif - height = width = TEXTURE_SIZE; - my_data = (void *)malloc(width * height * 4); - draw_shapes(my_data); -#if 0 - break; - - case 2: /* check */ - printf("Check\n"); - height = width = TEXTURE_SIZE; - my_data = (void *)malloc(width * height * 4); - for (i = 0 ; i < height ; i += 2) { - for (j = 0 ; j < width ; j += 2) { - if (((i + j) & 0x3) == 0) { - plot2(my_data, i, j, r0, g0, b0, a0); - } else { - plot2(my_data, i, j, r1, g1, b1, a1); - } - } - } - break; - - case 3: /* random stripes */ - printf("Stripes 2\n"); - height = width = TEXTURE_SIZE; - my_data = (void *)malloc(width * height * 4); - for (i = 0 ; i < height ; i += 2) { - r0 = random() & 0xff; - g0 = random() & 0xff; - b0 = random() & 0xff; - a0 = 0xff; - for (j = 0 ; j < width ; j += 2) { - plot2(my_data, i, j, r0, g0, b0, a0); - } - } - break; - } -#endif - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, - width, height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, my_data); - sprintf (buf, "random texture: (%dx%d)", - width, height); - check_gl_error(buf); - - /* setup parameters for texturing */ - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - glPixelStorei(GL_UNPACK_ROW_LENGTH, width); - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - if (random() & 0x1) { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } else { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - - if (my_data != NULL) { - free(my_data); - my_data = NULL; - } - - /* use full texture */ - /* acd - was 1.0 */ - texture->min_tx = 0.0; - texture->max_tx = 2.0; - texture->min_ty = 0.0; - texture->max_ty = 2.0; - texture->start_time = time((time_t *)0); -} - -static Bool -setup_file_texture (ModeInfo *mi, char *filename, texture *texture) -{ - Display *dpy = mi->dpy; - Visual *visual = mi->xgwa.visual; - char buf[1024]; - - XImage *image = file_to_ximage (dpy, visual, filename); - if (!image) return False; - -#ifdef DEBUG - printf("FileTexture\n"); -#endif - - /* use this texture */ - glBindTexture(GL_TEXTURE_2D, texture->id); - - clear_gl_error(); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, - image->width, image->height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, image->data); - sprintf (buf, "texture: %.100s (%dx%d)", - filename, image->width, image->height); - check_gl_error(buf); - - /* setup parameters for texturing */ - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - glPixelStorei(GL_UNPACK_ROW_LENGTH, image->width); - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - - /* use full texture */ - texture->min_tx = 0.0; - texture->max_tx = 1.0; - texture->min_ty = 0.0; - texture->max_ty = 1.0; - texture->start_time = time((time_t *)0); - return True; -} - -static void -setup_texture(ModeInfo * mi, texture *texture) -{ - gleidestruct *gp = &gleidescope[MI_SCREEN(mi)]; - - if (!image_str || !*image_str || !strcmp(image_str, "DEFAULT")) { - BUILTIN: - /* no image specified - use system settings */ -#ifdef DEBUG - printf("SetupTexture: get_snapshot\n"); -#endif - getSnapshot(mi, texture); - } else { - if (strcmp(image_str, "GENERATE") == 0) { -#ifdef DEBUG - printf("SetupTexture: random_texture\n"); -#endif - setup_random_texture(mi, texture); - } else { - /* use supplied image file */ -#ifdef DEBUG - printf("SetupTexture: file_texture\n"); -#endif - if (! setup_file_texture(mi, image_str, texture)) - goto BUILTIN; - } - } - /* copy start time from texture */ - gp->start_time = texture->start_time; - - check_gl_error("texture initialization"); - - /* acd - * resultant loaded image is upside down BUT - * it's a kaledescope and half of the hexagon is backwards anyway... - */ - - /* TODO: values for lissajous movement */ - texture->x_period = frandrange(-2.0, 2.0); - texture->y_period = frandrange(-2.0, 2.0); - texture->r_period = frandrange(-2.0, 2.0); - texture->x_phase = frand(M_PI * 2); - texture->y_phase = frand(M_PI * 2); - texture->r_phase = frand(M_PI * 2); -#ifdef DEBUG - printf("XPeriod %f XPhase %f\n", texture->x_period, texture->x_phase); - printf("YPeriod %f YPhase %f\n", texture->y_period, texture->y_phase); - printf("RPeriod %f RPhase %f\n", texture->r_period, texture->r_phase); -#endif -} - -#define VERTEX0 glVertex3f( 0.0000f, 0.000f, 0.0f); -#define VERTEX1 glVertex3f( 0.0000f, 1.000f, 0.0f); -#define VERTEX2 glVertex3f( XOFFSET, 0.500f, 0.0f); -#define VERTEX3 glVertex3f( XOFFSET, -0.500f, 0.0f); -#define VERTEX4 glVertex3f( 0.0000f, -1.000f, 0.0f); -#define VERTEX5 glVertex3f(-XOFFSET, -0.500f, 0.0f); -#define VERTEX6 glVertex3f(-XOFFSET, 0.500f, 0.0f); - -/* -** Three different functions for calculating texture coordinates -** which modify how the texture triangle moves over the source image. -** Choose one. -*/ - -#if 0 -/* the classic equilateral triangle rotating around centre */ -static void -calculate_texture_coords(ModeInfo *mi, texture *texture, vector2f t[3]) { - - gleidestruct *gp = &gleidescope[MI_SCREEN(mi)]; - GLfloat centre_x = 0.5; - GLfloat centre_y = 0.5; - GLfloat radius_x = (texture->max_tx - texture->min_tx) / 2; - GLfloat radius_y = (texture->max_ty - texture->min_ty) / 2; - GLfloat tangle2; - t[0].x = centre_x; - t[0].y = centre_y; - - /* t[1] */ - t[1].x = centre_x + .95 * radius_x * cos((gp->ymouse * 2 * M_PI) + (gp->tangle * RADIANS)); - t[1].y = centre_y + .95 * radius_y * sin((gp->ymouse * 2 * M_PI) + (gp->tangle * RADIANS)); - - /* t[2] is always 60' further around than t2 */ - tangle2 = (gp->ymouse * 2 * M_PI) + (gp->tangle * RADIANS) + (M_PI * 2 / 6); - t[2].x = centre_x + .95 * radius_x * cos(tangle2); - t[2].y = centre_y + .95 * radius_y * sin(tangle2); -#if 0 - printf("texcoords:[%f,%f]->[%f,%f](%f,%f)\n", t[0].x, t[0].y, t[1].x, t[1].y, texture->max_tx, texture->max_ty); -#endif -} -#endif - -#if 1 -/* new lissajous movement pattern */ -static void -calculate_texture_coords(ModeInfo *mi, texture *texture, vector2f t[3]) { - - /* equilateral triangle rotating around centre */ - gleidestruct *gp = &gleidescope[MI_SCREEN(mi)]; - GLfloat width = texture->max_tx - texture->min_tx; - GLfloat height = texture->max_ty - texture->min_ty; - /* centre */ - GLfloat centre_x = texture->min_tx + (width * .5); - GLfloat centre_y = texture->min_ty + (height * .5); - /* m radius and t radius should be = .5 */ - /* triangle radius is 30% available space */ - GLfloat t_radius_x = width * .3; - GLfloat t_radius_y = height * .3; - /* movement radius is 30% available space */ - GLfloat m_radius_x = width * .2; - GLfloat m_radius_y = height * .2; - GLfloat angle2; - - /* centre of triangle */ - GLfloat angle = (gp->ymouse * 2 * M_PI) + (gp->tangle * RADIANS); /* to radians */ - GLfloat t_centre_x = centre_x + m_radius_x * cos(texture->x_period * angle + texture->x_phase); - GLfloat t_centre_y = centre_y + m_radius_y * sin(texture->y_period * angle + texture->y_phase); - -#if 0 - printf("WH: %f, %f - tWH: %f, %f\n", width, height, texture->width, texture->height); - printf("size: (%f, %f)\n", width, height); - printf("centre: (%f, %f)\n", centre_x, centre_y); -#endif - - angle2 = texture->r_period * angle + texture->r_phase; - t[0].x = t_centre_x + t_radius_x * cos(angle2); - t[0].y = t_centre_y + t_radius_y * sin(angle2); - t[1].x = t_centre_x + t_radius_x * cos(angle2 + ANGLE_120); - t[1].y = t_centre_y + t_radius_y * sin(angle2 + ANGLE_120); - t[2].x = t_centre_x + t_radius_x * cos(angle2 + ANGLE_240); - t[2].y = t_centre_y + t_radius_y * sin(angle2 + ANGLE_240); - -#if 0 - printf("texcoords:[%f,%f]->[%f,%f](%f,%f)\n", t[0].x, t[0].y, t[1].x, t[1].y, texture->max_tx, texture->max_ty); -#endif -} -#endif - -#if 0 -/* corners into corners - meant to maximise coverage */ -static void -calculate_texture_coords(ModeInfo *mi, texture *texture, vector2f t[3]) { - - /* equilateral triangle rotating around centre */ - gleidestruct *gp = &gleidescope[MI_SCREEN(mi)]; - GLfloat width = texture->max_tx - texture->min_tx; - GLfloat height = texture->max_ty - texture->min_ty; - /* centre */ - GLfloat centre_x = texture->min_tx + (width * .5); - GLfloat centre_y = texture->min_ty + (height * .5); - /* m radius and t radius should be = .5 */ - /* triangle radius calculated using maths 8) */ -#define TRADIUS (M_SQRT2 - 1.0) -#define MRADIUS (1.0 - (M_SQRT2 / 2.0)) - GLfloat t_radius_x = width * TRADIUS * .95; - GLfloat t_radius_y = height * TRADIUS * .95; - /* movement radius also calculated using maths */ - GLfloat m_radius_x = width * MRADIUS * .95; - GLfloat m_radius_y = height * MRADIUS * .95; - GLfloat angle, angle2; - GLfloat t_centre_x, t_centre_y; - - /* centre of triangle */ - angle = gp->tangle * RADIANS; /* to radians */ - t_centre_x = centre_x + m_radius_x * cos(angle); - t_centre_y = centre_y + m_radius_y * sin(angle); -#if 0 - printf("angle: %f, %f\n", angle, gp->tangle); - printf("tcentre: %f,%f\n", t_centre_x, t_centre_y); - printf("tradius: %f,%f\n", t_radius_x, t_radius_y); - - printf("size: (%f, %f)\n", width, height); - printf("centre: (%f, %f)\n", centre_x, centre_y); - printf("centre: (%f, %f)\n", centre_x, centre_y); - printf("TRADIUS: %f\n", TRADIUS); - printf("MRADIUS: %f\n", MRADIUS); -#endif - - /* angle2 is tied to tangle */ - angle2 = (180.0 - ((30.0 / 90.0) * gp->tangle)) * RADIANS; -#if 0 - printf("Angle1: %f\tAngle2: %f\n", angle / RADIANS, angle2 / RADIANS); -#endif - t[0].x = t_centre_x + t_radius_x * cos(angle2); - t[0].y = t_centre_y + t_radius_y * sin(angle2); - t[1].x = t_centre_x + t_radius_x * cos(angle2 + ANGLE_120); - t[1].y = t_centre_y + t_radius_y * sin(angle2 + ANGLE_120); - t[2].x = t_centre_x + t_radius_x * cos(angle2 + ANGLE_240); - t[2].y = t_centre_y + t_radius_y * sin(angle2 + ANGLE_240); - -#if 0 - printf("texcoords:[%f,%f][%f,%f][%f,%f]\n", t[0].x, t[0].y, t[1].x, t[1].y, t[2].x, t[2].y); -#endif -} -#endif - -static int -draw_hexagons(ModeInfo *mi, int translucency, texture *texture) -{ - int polys = 0; - int i; - vector2f t[3]; - gleidestruct *gp = &gleidescope[MI_SCREEN(mi)]; - - calculate_texture_coords(mi, texture, t); - - glColor4f(1.0, 1.0, 1.0, (float)translucency / MAX_FADE); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDepthMask(GL_FALSE); - glBindTexture(GL_TEXTURE_2D, texture->id); - - if (gp->list == -1) { - gp->list = glGenLists(1); - } - - /* compile new list */ - glNewList(gp->list, GL_COMPILE); - glBegin(GL_TRIANGLES); - - /* - ** six triangles to each hexagon - */ - - glTexCoord2f(t[0].x, t[0].y); - VERTEX0; - glTexCoord2f(t[1].x, t[1].y); - VERTEX1; - glTexCoord2f(t[2].x, t[2].y); - VERTEX6; - - glTexCoord2f(t[0].x, t[0].y); - VERTEX0; - glTexCoord2f(t[2].x, t[2].y); - VERTEX6; - glTexCoord2f(t[1].x, t[1].y); - VERTEX5; - - glTexCoord2f(t[0].x, t[0].y); - VERTEX0; - glTexCoord2f(t[1].x, t[1].y); - VERTEX5; - glTexCoord2f(t[2].x, t[2].y); - VERTEX4; - - glTexCoord2f(t[0].x, t[0].y); - VERTEX0; - glTexCoord2f(t[2].x, t[2].y); - VERTEX4; - glTexCoord2f(t[1].x, t[1].y); - VERTEX3; - - glTexCoord2f(t[0].x, t[0].y); - VERTEX0; - glTexCoord2f(t[1].x, t[1].y); - VERTEX3; - glTexCoord2f(t[2].x, t[2].y); - VERTEX2; - - glTexCoord2f(t[0].x, t[0].y); - VERTEX0; - glTexCoord2f(t[2].x, t[2].y); - VERTEX2; - glTexCoord2f(t[1].x, t[1].y); - VERTEX1; - - glEnd(); - glEndList(); - - /* call the list n times */ - for (i = 0 ; i < sizeof(hex) / sizeof(hex[0]) ; i++) { - - glPushMatrix(); - - glTranslatef(hex[i].x, hex[i].y, 0.0); - glCallList(gp->list); - polys += 6; - - glPopMatrix(); - } - -#ifdef DISPLAY_TEXTURE - glPushMatrix(); - /* acd debug - display (bigger, centred) texture */ - glScalef(2.0, 2.0, 2.0); - glTranslatef(-0.5, -0.5, 0.0); - glBegin(GL_QUADS); - glTexCoord2f(0.0, 0.0); - glVertex3f(0.0, 0.0, -0.1); - glTexCoord2f(1.0, 0.0); - glVertex3f(1.0, 0.0, -0.1); - glTexCoord2f(1.0, 1.0); - glVertex3f(1.0, 1.0, -0.1); - glTexCoord2f(0.0, 1.0); - glVertex3f(0.0, 1.0, -0.1); - polys++; - glEnd(); - /* acd debug - display texture triangle */ - glColor4f(1.0, 0.5, 1.0, 1.0); - glBegin(GL_LINE_LOOP); - glVertex3f(t[0].x, t[0].y, -0.11); - glVertex3f(t[1].x, t[1].y, -0.11); - glVertex3f(t[2].x, t[2].y, -0.11); - polys++; - glEnd(); - glPopMatrix(); -#endif - - glDisable(GL_TEXTURE_2D); - glDepthMask(GL_TRUE); - glDisable(GL_BLEND); - return polys; -} - -/* - * main rendering loop - */ -static void -draw(ModeInfo * mi) -{ - GLfloat x_angle, y_angle, z_angle; - gleidestruct *gp = &gleidescope[MI_SCREEN(mi)]; - vectorf v1; - - mi->polygon_count = 0; - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glLoadIdentity(); - - gp->tic += 0.005f; - - x_angle = gp->cam_x_phase + gp->tic * gp->cam_x_speed; - y_angle = gp->cam_y_phase + gp->tic * gp->cam_y_speed; - z_angle = gp->cam_z_phase + gp->tic * gp->cam_z_speed; - - if (move) { - v1.x = 1 * sin(x_angle); - v1.y = 1 * sin(y_angle); - } else { - v1.x = 0; - v1.y = 0; - } - - /* size is changed in pinit() to be distance from plane */ - gp->size = MI_SIZE(mi); - if (gp->size > 10) { - gp->size = 10; - } - if (gp->size <= 0) { - gp->size = 0; - } - if (gp->size > 0) { - /* user defined size */ - v1.z = gp->size; - } else if (zoom) { - /* max distance given by adding the constant and the multiplier */ - v1.z = 5.0 + 3.0 * sin(z_angle); - } else { - /* default */ - v1.z = 7.0; - } - - /* update rotation angle (but not if mouse button down) */ - if (rotate && !gp->button_down_p) - { - float new_rangle_vel = 0.0; - - /* update camera rotation angle and velocity */ - gp->rangle += gp->rangle_vel; - new_rangle_vel = gp->rangle_vel + gp->rangle_acc; - if (new_rangle_vel > -MAX_ANGLE_VEL && new_rangle_vel < MAX_ANGLE_VEL) - { - /* new velocity is within limits */ - gp->rangle_vel = new_rangle_vel; - } - - /* randomly change twisting speed - 3ff = 1024 */ - if ((random() % TWISTING_PROBABILITY) < 1.0) { - gp->rangle_acc = INITIAL_ANGLE_ACC * frand(1.0); - if (gp->rangle_vel > 0.0) { - gp->rangle_acc = -gp->rangle_acc; - } - } - } -#if 0 - printf("Rangle: %f : %f : %f\n", gp->rangle, gp->rangle_vel, gp->rangle_acc); - printf("Tangle: %f : %f : %f\n", gp->tangle, gp->tangle_vel, gp->tangle_acc); -#endif - -#ifdef WOBBLE - /* this makes the image wobble - requires -move and a larger grid */ - gluLookAt(0, 0, v1.z, v1.x, v1.y, 0.0, 0.0, 1.0, 0.0); -#else - /* no wobble - camera always perpendicular to grid */ - - /* rotating camera rather than entire space - smoother */ - gluLookAt( - v1.x, v1.y, v1.z, - v1.x, v1.y, 0.0, - sin((gp->xmouse * M_PI * 2) + gp->rangle * RADIANS), - cos((gp->xmouse * M_PI * 2) + gp->rangle * RADIANS), - 0.0); -#endif - - { - GLfloat s = (MI_WIDTH(mi) < MI_HEIGHT(mi) - ? (MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi)) - : 1); - glScalef (s, s, s); - } - - if (gp->fade == 0) - { - /* not fading */ - mi->polygon_count += - draw_hexagons(mi, MAX_FADE, &gp->textures[gp->visible]); - } - else - { - /* fading - show both textures with alpha - NB first is always max alpha */ - mi->polygon_count += - draw_hexagons(mi, MAX_FADE, &gp->textures[1 - gp->visible]); - mi->polygon_count += - draw_hexagons(mi, MAX_FADE - gp->fade, &gp->textures[gp->visible]); - - /* fade some more */ - gp->fade++; - - /* have we faded enough? */ - if (gp->fade > MAX_FADE) - { - /* stop fading */ - gp->fade = 0; - gp->visible = 1 - gp->visible; - } - } - - /* increment texture angle based on time, velocity etc */ - /* but only if button is not down */ - if (!gp->button_down_p) - { - float new_tangle_vel = 0.0; - - gp->tangle += gp->tangle_vel; - - /* work out new texture angle velocity */ - new_tangle_vel = gp->tangle_vel + gp->tangle_acc; - if (new_tangle_vel > -MAX_ANGLE_VEL && new_tangle_vel < MAX_ANGLE_VEL) - { - /* new velocity is inside limits */ - gp->tangle_vel = new_tangle_vel; - } - - /* randomly change twisting speed - 3ff = 1024 */ - if ((random() % TWISTING_PROBABILITY) < 1.0) { - gp->tangle_acc = INITIAL_ANGLE_ACC * frand(1.0); - if (gp->tangle_vel > 0.0) { - gp->tangle_acc = -gp->tangle_acc; - } - } - } - - glFlush(); -} - -/* - * new window size or exposure - */ -ENTRYPOINT void reshape_gleidescope(ModeInfo *mi, int width, int height) -{ - gleidestruct *gp = &gleidescope[MI_SCREEN(mi)]; - GLfloat h = (GLfloat) height / (GLfloat) width; - - int y = 0; - - if (width > height * 5) { /* tiny window: show middle */ - height = width * 9/16; - y = -height/2; - h = height / (GLfloat) width; - } - - glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *gp->glx_context); - - glViewport(0, y, (GLint) width, (GLint) height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(50.0, 1/h, 0.1, 2000.0); - glMatrixMode (GL_MODELVIEW); - glLineWidth(1); - glPointSize(1); -} - -static void -pinit(ModeInfo * mi) -{ - gleidestruct *gp = &gleidescope[MI_SCREEN(mi)]; - - /* set start time - star_time = 0 implies non-dynamic texture */ - gp->start_time = (time_t)0; - - /* set the texture size to default */ - /* - gp->max_tx = 1.0; - gp->max_ty = 1.0; - */ - - /* no fading */ - gp->fade = 0; - - glShadeModel(GL_SMOOTH); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glDisable(GL_LIGHTING); - - /* space for textures */ - glGenTextures(1, &gp->textures[0].id); - glGenTextures(1, &gp->textures[1].id); - gp->visible = 0; - - setup_texture(mi, &gp->textures[gp->visible]); - - /* - ** want to choose a value for arg randomly if neither -arg nor -no-arg - ** is specified. xscreensaver libraries don't seem to let you do this - - ** if something isn't true then it is false (pesky two-state boolean values). - ** so, i've defined both -arg and -no-arg to arguments and added the - ** following logic. - ** (btw if both -arg and -no-arg are defined then arg is set to False) - */ - if (zoom == False && nozoom == False) - { - /* no zoom preference - randomise */ - zoom = (((random() & 0x1) == 0x1) ? True : False); - } - else if (nozoom == True) - { - /* definately no zoom */ - zoom = False; - } - - if (move == False && nomove == False) - { - /* no move preference - randomise */ - move = (((random() & 0x1) == 0x1) ? True : False); - } - else if (nomove == True) - { - /* definately no move */ - move = False; - } - - if (rotate == False && norotate == False) - { - /* no rotate preference - randomise */ - rotate = (((random() & 0x1) == 0x1) ? True : False); - } - else if (norotate == True) - { - /* definately no rotate */ - rotate = False; - } - - /* define cam variables */ - gp->cam_x_speed = MAX_CAM_SPEED * frandrange(-.5, 0.5); - gp->cam_x_phase = random() % 360; - gp->cam_y_speed = MAX_CAM_SPEED * frandrange(-.5, 0.5); - gp->cam_y_phase = random() % 360; - gp->cam_z_speed = MAX_CAM_SPEED * frandrange(-.5, 0.5); - gp->cam_z_phase = random() % 360; - - /* initial angular speeds */ - gp->rangle_vel = INITIAL_ANGLE_VEL * frandrange(-.5, 0.5); - gp->tangle_vel = INITIAL_ANGLE_VEL * frandrange(-.5, 0.5); - gp->rangle_acc = INITIAL_ANGLE_ACC * frandrange(-.5, 0.5); - gp->tangle_acc = INITIAL_ANGLE_ACC * frandrange(-.5, 0.5); - - /* jwz */ -#if 0 - { - GLfloat speed = 15; - gp->rangle_vel *= speed; - gp->tangle_vel *= speed; - gp->rangle_acc *= speed; - gp->tangle_acc *= speed; - } -#endif - - /* distance is 11 - size */ - if (gp->size != -1) { - if (zoom) { - fprintf(stderr, "-size given. ignoring -zoom.\n"); - zoom = False; - } - if (gp->size < 1) { - gp->size = 1; - } else if (gp->size >= 10) { - gp->size = 10; - } - gp->size = 11 - gp->size; - } - -#ifdef DEBUG -printf("phases [%d, %d, %d]\n", gp->cam_x_phase, gp->cam_y_phase, gp->cam_z_phase); -#endif -} - -ENTRYPOINT void -init_gleidescope(ModeInfo * mi) -{ - gleidestruct *gp; - int screen = MI_SCREEN(mi); - - MI_INIT(mi, gleidescope); - gp = &gleidescope[screen]; - gp->window = MI_WINDOW(mi); - gp->size = -1; - gp->list = -1; - - if ((gp->glx_context = init_GL(mi)) != NULL) { - - reshape_gleidescope(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); - clear_gl_error(); /* WTF? sometimes "invalid op" from glViewport! */ - - glDrawBuffer(GL_BACK); - - /* do initialisation */ - pinit(mi); - - } else { - MI_CLEARWINDOW(mi); - } -} - -ENTRYPOINT void -draw_gleidescope(ModeInfo * mi) -{ - gleidestruct *gp = &gleidescope[MI_SCREEN(mi)]; - Display *display = MI_DISPLAY(mi); - Window window = MI_WINDOW(mi); - - - if (!gp->glx_context) - return; - - /* Just keep running before the texture has come in. */ - /* if (gp->waiting_for_image_p) return; */ - - glDrawBuffer(GL_BACK); - - glXMakeCurrent(display, window, *gp->glx_context); - draw(mi); - - if (mi->fps_p) { - do_fps (mi); - } - - glFinish(); - glXSwapBuffers(display, window); - -#ifdef GRAB - if (grab) { - grab_frame(display, window); - } -#endif - - /* need to change texture? */ - if ((gp->start_time != 0) && (duration != -1) && gp->fade == 0) { - if (gp->start_time + duration <= time((time_t *)0)) { -#ifdef DEBUG - printf("Start Time: %lu - Current Time: %lu\n", (unsigned long)gp->start_time, (unsigned long)time((time_t *)0)); - printf("Changing Texture\n"); -#endif - /* get new snapshot (into back buffer) and start fade count */ - setup_texture(mi, &gp->textures[1 - gp->visible]); - /* restart fading */ - gp->fade = 1; - } - } -} - -ENTRYPOINT void -free_gleidescope(ModeInfo * mi) -{ - gleidestruct *gp = &gleidescope[MI_SCREEN(mi)]; - if (!gp->glx_context) return; - glXMakeCurrent (MI_DISPLAY(mi), MI_WINDOW(mi), *gp->glx_context); - if (glIsList(gp->list)) glDeleteLists(gp->list, 1); - if (gp->textures[0].id) glDeleteTextures (1, &gp->textures[0].id); - if (gp->textures[1].id) glDeleteTextures (1, &gp->textures[1].id); -} - -XSCREENSAVER_MODULE ("Gleidescope", gleidescope) - -#endif |
