diff options
| author | Simon Rettberg | 2024-09-06 14:42:37 +0200 |
|---|---|---|
| committer | Simon Rettberg | 2024-09-06 14:42:37 +0200 |
| commit | badef32037f52f79abc1f1440b786cd71afdf270 (patch) | |
| tree | 412b792d4cab4a7a110db82fcf74fe8a1ac55ec1 /hacks/glx/raverhoop.c | |
| parent | Delete pre-6.00 files (diff) | |
| download | xscreensaver-master.tar.gz xscreensaver-master.tar.xz xscreensaver-master.zip | |
Diffstat (limited to 'hacks/glx/raverhoop.c')
| -rw-r--r-- | hacks/glx/raverhoop.c | 788 |
1 files changed, 0 insertions, 788 deletions
diff --git a/hacks/glx/raverhoop.c b/hacks/glx/raverhoop.c deleted file mode 100644 index 4a5a26a..0000000 --- a/hacks/glx/raverhoop.c +++ /dev/null @@ -1,788 +0,0 @@ -/* raverhoop, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org> - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation. No representations are made about the suitability of this - * software for any purpose. It is provided "as is" without express or - * implied warranty. - * - * Simulates an LED hula hoop in a dark room. Oontz oontz oontz. - */ - -#define DEFAULTS "*delay: 20000 \n" \ - "*ncolors: 12 \n" \ - "*showFPS: False \n" \ - "*wireframe: False \n" \ - -# define release_hoop 0 - -#include "xlockmore.h" -#include "colors.h" -#include "rotator.h" -#include "gltrackball.h" -#include <ctype.h> - -#ifdef USE_GL /* whole file */ - - -#define DEF_SPIN "False" -#define DEF_WANDER "False" -#define DEF_LIGHTS "200" -#define DEF_SPEED "1.0" -#define DEF_LIGHT_SPEED "1.0" -#define DEF_SUSTAIN "1.0" - -typedef struct { - GLfloat x,y,z; -} XYZ; - -typedef struct afterimage afterimage; -struct afterimage { - GLfloat color[4]; - XYZ position; - afterimage *next; -}; - -typedef struct { - GLfloat color[4]; - int duty_cycle[10]; /* off, on, off, on... values add to 100 */ - GLfloat ratio; - Bool on; -} light; - - -typedef struct oscillator oscillator; -struct oscillator { - GLfloat ratio, from, to, speed, *var; - int remaining; - oscillator *next; -}; - - -typedef struct { - GLXContext *glx_context; - rotator *rot; - trackball_state *trackball; - Bool button_down_p; - - int nlights; - light *lights; - GLfloat radius; - GLfloat axial_radius; - XYZ midpoint; - GLfloat tilt; - GLfloat spin; - GLfloat th; - GLfloat speed; - afterimage *trail; - oscillator *oscillators; - -} hoop_configuration; - -static hoop_configuration *bps = NULL; - -static Bool do_spin; -static Bool do_wander; -static int nlights; -static GLfloat speed, light_speed, sustain; - -static XrmOptionDescRec opts[] = { - { "-spin", ".spin", XrmoptionNoArg, "True" }, - { "+spin", ".spin", XrmoptionNoArg, "False" }, - { "-wander", ".wander", XrmoptionNoArg, "True" }, - { "+wander", ".wander", XrmoptionNoArg, "False" }, - { "-lights", ".lights", XrmoptionSepArg, 0 }, - { "-speed", ".speed", XrmoptionSepArg, 0 }, - { "-light-speed", ".lightSpeed", XrmoptionSepArg, 0 }, - { "-sustain", ".sustain", XrmoptionSepArg, 0 }, -}; - -static argtype vars[] = { - {&do_spin, "spin", "Spin", DEF_SPIN, t_Bool}, - {&do_wander, "wander", "Wander", DEF_WANDER, t_Bool}, - {&nlights, "lights", "Lights", DEF_LIGHTS, t_Int}, - {&speed, "speed", "Speed", DEF_SPEED, t_Float}, - {&light_speed, "lightSpeed", "Speed", DEF_LIGHT_SPEED, t_Float}, - {&sustain, "sustain", "Sustain", DEF_SUSTAIN, t_Float}, -}; - -ENTRYPOINT ModeSpecOpt hoop_opts = {countof(opts), opts, countof(vars), vars, NULL}; - - -static void -decay_afterimages (ModeInfo *mi) -{ - hoop_configuration *bp = &bps[MI_SCREEN(mi)]; - afterimage *prev = 0; - afterimage *a = bp->trail; - GLfloat tick = 0.05 / sustain; - - while (a) - { - afterimage *next = a->next; - a->color[3] -= tick; - if (a->color[3] < 0) - { - if (prev) - prev->next = next; - else - bp->trail = next; - free (a); - } - else - prev = a; - a = next; - } -} - -static void -add_afterimage (ModeInfo *mi, GLfloat x, GLfloat y, GLfloat z, - GLfloat color[4]) -{ - hoop_configuration *bp = &bps[MI_SCREEN(mi)]; - afterimage *a = (afterimage *) calloc (1, sizeof (*a)); - afterimage *b; - a->position.x = x; - a->position.y = y; - a->position.z = z; - memcpy (a->color, color, sizeof(a->color)); - - /* Put it at the end so that the older, dimmer ones are laid down on - the frame buffer before the newer, brighter ones. */ - if (!bp->trail) - bp->trail = a; - else - { - for (b = bp->trail; b->next; b = b->next) - ; - b->next = a; - } -} - - -static void -tick_light (light *L) -{ - int i; - int n = 0; - - L->ratio += 0.05 * light_speed; - while (L->ratio > 1) - L->ratio -= 1; - - for (i = 0; i < countof(L->duty_cycle); i++) - { - n += L->duty_cycle[i]; - if (n > 100) abort(); - if (n / 100.0 > L->ratio) - { - L->on = (i & 1); - break; - } - } -} - - - -static void -tick_hoop (ModeInfo *mi) -{ - hoop_configuration *bp = &bps[MI_SCREEN(mi)]; - GLfloat m0[16]; - int i; - - glGetFloatv (GL_MODELVIEW_MATRIX, m0); - - for (i = 0; i < bp->nlights; i++) - { - light *L = &bp->lights[i]; - GLfloat m1[16]; - GLfloat th = M_PI * 2 * i / bp->nlights; - GLfloat x = cos (th); - GLfloat y = sin (th); - GLfloat z; - - tick_light (L); - if (! L->on) - continue; - - glPushMatrix(); - - glTranslatef (bp->midpoint.x, bp->midpoint.y, bp->midpoint.z); - glRotatef (bp->th * 180 / M_PI, 0, 0, 1); - glRotatef (bp->tilt, 0, 1, 0); - glRotatef (bp->spin, 1, 0, 0); - glTranslatef (x * bp->radius, y * bp->radius, 0); - glGetFloatv (GL_MODELVIEW_MATRIX, m1); - glPopMatrix(); - - /* After all of our translations and rotations, figure out where - it actually ended up. - */ - x = m1[12] - m0[12]; - y = m1[13] - m0[13]; - z = m1[14] - m0[14]; - add_afterimage (mi, x, y, z, L->color); - } -} - - -static void -draw_lights (ModeInfo *mi) -{ - hoop_configuration *bp = &bps[MI_SCREEN(mi)]; - int wire = MI_IS_WIREFRAME(mi); - afterimage *a; - GLfloat m[4][4]; - - if (wire) - { - int n = 360; - int i; - glPushMatrix(); - - glBegin (GL_LINES); - glVertex3f (0, 0, -bp->radius); - glVertex3f (0, 0, bp->radius); - glEnd(); - - glTranslatef (bp->midpoint.x, bp->midpoint.y, bp->midpoint.z); - glRotatef (bp->th * 180 / M_PI, 0, 0, 1); - glRotatef (bp->tilt, 0, 1, 0); - glRotatef (bp->spin, 1, 0, 0); - - glBegin (GL_LINE_LOOP); - glVertex3f (0, 0, 0); - for (i = 0; i <= n; i++) - { - GLfloat th = i * M_PI * 2 / n; - glVertex3f (bp->radius * -cos(th), - bp->radius * -sin(th), 0); - } - for (i = 0; i <= n; i++) - { - GLfloat th = i * M_PI * 2 / n; - glVertex3f (bp->axial_radius * -cos(th), - bp->axial_radius * -sin(th), 0); - } - glEnd(); - glPopMatrix(); - } - - /* Billboard the lights to always face the camera */ - glGetFloatv (GL_MODELVIEW_MATRIX, &m[0][0]); - m[0][0] = 1; m[1][0] = 0; m[2][0] = 0; - m[0][1] = 0; m[1][1] = 1; m[2][1] = 0; - m[0][2] = 0; m[1][2] = 0; m[2][2] = 1; - glLoadIdentity(); - glMultMatrixf (&m[0][0]); - - for (a = bp->trail; a; a = a->next) - { - glPushMatrix(); - - glTranslatef (a->position.x, a->position.y, a->position.z); - - if (wire) - { - GLfloat c[3]; - c[0] = a->color[0] * a->color[3]; - c[1] = a->color[1] * a->color[3]; - c[2] = a->color[2] * a->color[3]; - glColor3fv (c); - } - else - glColor4fv (a->color); - - glRotatef (45, 0, 0, 1); - glScalef (0.15, 0.15, 0.15); - glBegin (GL_QUADS); - glTexCoord2f (0, 0); glVertex3f (-1, -1, 0); - glTexCoord2f (1, 0); glVertex3f ( 1, -1, 0); - glTexCoord2f (1, 1); glVertex3f ( 1, 1, 0); - glTexCoord2f (0, 1); glVertex3f (-1, 1, 0); - glEnd(); - mi->polygon_count++; - - glPopMatrix(); - } -} - - -static GLfloat -ease_fn (GLfloat r) -{ - return cos ((r/2 + 1) * M_PI) + 1; /* Smooth curve up, end at slope 1. */ -} - - -static GLfloat -ease_ratio (GLfloat r) -{ - GLfloat ease = 0.35; - if (r <= 0) return 0; - else if (r >= 1) return 1; - else if (r <= ease) return ease * ease_fn (r / ease); - else if (r > 1-ease) return 1 - ease * ease_fn ((1 - r) / ease); - else return r; -} - - -static void -tick_oscillators (ModeInfo *mi) -{ - hoop_configuration *bp = &bps[MI_SCREEN(mi)]; - oscillator *prev = 0; - oscillator *a = bp->oscillators; - GLfloat tick = 0.1 / speed; - - while (a) - { - oscillator *next = a->next; - a->ratio += tick * a->speed; - if (a->ratio > 1) - a->ratio = 1; - - *a->var = a->from + (a->to - a->from) * ease_ratio (a->ratio); - - if (a->ratio < 1) /* mid cycle */ - prev = a; - else if (--a->remaining <= 0) /* ended, and expired */ - { - if (prev) - prev->next = next; - else - bp->oscillators = next; - free (a); - } - else /* keep going the other way */ - { - GLfloat swap = a->from; - a->from = a->to; - a->to = swap; - a->ratio = 0; - prev = a; - } - - a = next; - } -} - - -static void -calm_oscillators (ModeInfo *mi) -{ - hoop_configuration *bp = &bps[MI_SCREEN(mi)]; - oscillator *a; - for (a = bp->oscillators; a && a->next; a = a->next) - a->remaining = 1; -} - - -static void -add_oscillator (ModeInfo *mi, GLfloat *var, GLfloat speed, GLfloat to, - int repeat) -{ - hoop_configuration *bp = &bps[MI_SCREEN(mi)]; - oscillator *a; - - /* If an oscillator is already running on this variable, don't - add another. */ - for (a = bp->oscillators; a && a->next; a = a->next) - if (a->var == var) - return; - - a = (oscillator *) calloc (1, sizeof (*a)); - if (repeat <= 0) abort(); - a->ratio = 0; - a->from = *var; - a->to = to; - a->speed = speed; - a->var = var; - a->remaining = repeat; - a->next = bp->oscillators; - bp->oscillators = a; -# if 0 - fprintf (stderr, "%s: %3d %6.2f -> %6.2f %s\n", - progname, repeat, *var, to, - (var == &bp->midpoint.z ? "z" : - var == &bp->tilt ? "tilt" : - var == &bp->axial_radius ? "r" : - var == &bp->speed ? "speed" : "?")); -# endif -} - - -static void -add_random_oscillator (ModeInfo *mi) -{ - hoop_configuration *bp = &bps[MI_SCREEN(mi)]; - int n = random() % 12; - switch (n) { - case 0: case 1: case 2: - add_oscillator (mi, &bp->midpoint.z, 1, - bp->radius * (0.8 + frand(0.2)) - * (random() & 1 ? 1 : -1), - (3 + (random() % 10))); - break; - case 3: case 4: case 5: - add_oscillator (mi, &bp->tilt, 1, - -(GLfloat) (random() % 15), - 3 + (random() % 20)); - break; - case 6: case 7: case 8: - add_oscillator (mi, &bp->axial_radius, 1, - 0.1 + bp->radius * frand(1.4), - 1 + (random() % 4)); - break; - case 9: case 10: - add_oscillator (mi, &bp->speed, 3, - (0.7 + frand(0.9)) * (random() & 1 ? 1 : -1), - ((random() % 5) - ? 1 - : 2 + (random() % 5))); - break; - case 11: - add_oscillator (mi, &bp->spin, 0.1, - 180 * (1 + (random() % 2)), - 2 * (1 + (random() % 5))); - break; - default: - abort(); - break; - } -} - - -static void -randomize_colors (ModeInfo *mi) -{ - hoop_configuration *bp = &bps[MI_SCREEN(mi)]; - int ncolors = MI_NCOLORS(mi); - GLfloat *colors; - int ncycles; - int i; - - if (ncolors < 1) - ncolors = 1; - if (ncolors > bp->nlights) - ncolors = bp->nlights; - - if (! (random() % 10)) - ncolors = 1; - - colors = calloc (ncolors, 4 * sizeof(*colors)); - for (i = 0; i < ncolors; i++) - { - GLfloat *c = &colors[i * 4]; -# define QUANTIZE() (((random() % 16) << 4) | 0xF) / 255.0 - c[0] = QUANTIZE(); - c[1] = QUANTIZE(); - c[2] = QUANTIZE(); - c[3] = 1; - } - - switch (random() % 5) { - case 0: ncycles = 1; break; - case 2: ncycles = ncolors * (1 + (random() % 5)); break; - default: ncycles = ncolors; break; - } - - for (i = 0; i < bp->nlights; i++) - { - light *L = &bp->lights[i]; - int n = i * ncolors / bp->nlights; - int m = i * ncycles / bp->nlights; - if (n >= ncolors) abort(); - if (m >= ncycles) abort(); - memcpy (L->color, &colors[n], sizeof (L->color)); - - if (ncycles <= 1) - { - L->duty_cycle[0] = 0; - L->duty_cycle[1] = 100; - } - else if (m & 1) - { - L->duty_cycle[0] = 50; - L->duty_cycle[1] = 50; - } - else - { - L->duty_cycle[0] = 0; - L->duty_cycle[1] = 50; - L->duty_cycle[2] = 50; - } - } - free (colors); -} - - -static void -move_hoop (ModeInfo *mi) -{ - hoop_configuration *bp = &bps[MI_SCREEN(mi)]; - - bp->th += 0.2 * speed * bp->speed; - while (bp->th > M_PI*2) - bp->th -= M_PI*2; - while (bp->th < 0) - bp->th += M_PI*2; - - bp->midpoint.x = bp->axial_radius * cos (bp->th); - bp->midpoint.y = bp->axial_radius * sin (bp->th); - - tick_oscillators (mi); - - if (! (random() % 80)) - add_random_oscillator (mi); - - if (! (random() % 120)) - randomize_colors (mi); -} - - -static void -build_texture (ModeInfo *mi) -{ - int x, y; - int size = 128; - int s2 = size / 2; - int bpl = size * 2; - unsigned char *data = malloc (bpl * size); - - for (y = 0; y < size; y++) - { - for (x = 0; x < size; x++) - { - double dist = (sqrt (((s2 - x) * (s2 - x)) + - ((s2 - y) * (s2 - y))) - / s2); - unsigned char *c = &data [y * bpl + x * 2]; - c[0] = 0xFF; - c[1] = 0xFF * sin (dist > 1 ? 0 : (1 - dist)); - } - } - - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glPixelStorei (GL_UNPACK_ALIGNMENT, 1); - check_gl_error ("texture param"); - - glTexImage2D (GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, size, size, 0, - GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data); - check_gl_error ("light texture"); - free (data); -} - - - -/* Window management, etc - */ -ENTRYPOINT void -reshape_hoop (ModeInfo *mi, int width, int height) -{ - 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; - } - - glViewport (0, y, (GLint) width, (GLint) height); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective (30.0, 1/h, 1.0, 100.0); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - gluLookAt( 0.0, 0.0, 30.0, - 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0); - - { - GLfloat s = (MI_WIDTH(mi) < MI_HEIGHT(mi) - ? (MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi)) - : 1); - glScalef (s, s, s); - } - - glClear(GL_COLOR_BUFFER_BIT); -} - - -ENTRYPOINT Bool -hoop_handle_event (ModeInfo *mi, XEvent *event) -{ - hoop_configuration *bp = &bps[MI_SCREEN(mi)]; - - if (gltrackball_event_handler (event, bp->trackball, - MI_WIDTH (mi), MI_HEIGHT (mi), - &bp->button_down_p)) - return True; - else if (event->xany.type == KeyPress) - { - KeySym keysym; - char c = 0; - XLookupString (&event->xkey, &c, 1, &keysym, 0); - if (c == ' ' || c == '\t') - { - randomize_colors (mi); - calm_oscillators (mi); - add_random_oscillator (mi); - return True; - } - } - - return False; -} - - -ENTRYPOINT void -init_hoop (ModeInfo *mi) -{ - hoop_configuration *bp; - int wire = MI_IS_WIREFRAME(mi); - - MI_INIT (mi, bps); - - bp = &bps[MI_SCREEN(mi)]; - - bp->glx_context = init_GL(mi); - - reshape_hoop (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); - - glDisable (GL_LIGHTING); - glDisable (GL_DEPTH_TEST); - glEnable (GL_CULL_FACE); - glEnable (GL_NORMALIZE); - glEnable (GL_BLEND); - glBlendFunc (GL_SRC_ALPHA, GL_ONE); - glPolygonMode (GL_FRONT, GL_FILL); - glShadeModel (GL_FLAT); - - if (! wire) - { - build_texture (mi); - glEnable (GL_TEXTURE_2D); - } - - { - double spin_speed = 0.3; - double wander_speed = 0.005; - double spin_accel = 2.0; - - bp->rot = make_rotator (do_spin ? spin_speed : 0, - do_spin ? spin_speed : 0, - do_spin ? spin_speed : 0, - spin_accel, - do_wander ? wander_speed : 0, - False); - bp->trackball = gltrackball_init (True); - } - - bp->radius = 30; - bp->axial_radius = bp->radius * 0.3; - bp->tilt = - (GLfloat) (5 + (random() % 12)); - bp->speed = (random() % 1 ? 1 : -1); - bp->nlights = nlights; - bp->lights = (light *) calloc (bp->nlights, sizeof (*bp->lights)); - randomize_colors (mi); - move_hoop (mi); - add_random_oscillator (mi); -} - - -ENTRYPOINT void -draw_hoop (ModeInfo *mi) -{ - hoop_configuration *bp = &bps[MI_SCREEN(mi)]; - Display *dpy = MI_DISPLAY(mi); - Window window = MI_WINDOW(mi); - - if (!bp->glx_context) - return; - - glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *bp->glx_context); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glPushMatrix (); - - { - double x, y, z; - get_position (bp->rot, &x, &y, &z, !bp->button_down_p); - glTranslatef((x - 0.5) * 7, - (y - 0.5) * 0.5, - (z - 0.5) * 15); - - gltrackball_rotate (bp->trackball); - glRotatef (current_device_rotation(), 0, 0, 1); - - get_rotation (bp->rot, &x, &y, &z, !bp->button_down_p); - glRotatef (x * 360, 1.0, 0.0, 0.0); - glRotatef (y * 360, 0.0, 1.0, 0.0); - glRotatef (z * 360, 0.0, 0.0, 1.0); - } - - mi->polygon_count = 0; - - glScalef (0.2, 0.2, 0.2); - -# ifdef HAVE_MOBILE - glScalef (0.7, 0.7, 0.7); -# endif - - glRotatef (70, 1, 0, 0); - - if (! bp->button_down_p) - move_hoop (mi); - - decay_afterimages (mi); - tick_hoop (mi); - draw_lights (mi); - - glPopMatrix (); - - if (mi->fps_p) do_fps (mi); - glFinish(); - - glXSwapBuffers(dpy, window); -} - - -ENTRYPOINT void -free_hoop (ModeInfo *mi) -{ - hoop_configuration *bp = &bps[MI_SCREEN(mi)]; - - if (!bp->glx_context) return; - glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *bp->glx_context); - - if (bp->trackball) gltrackball_free (bp->trackball); - if (bp->rot) free_rotator (bp->rot); - if (bp->lights) free (bp->lights); - while (bp->trail) { - afterimage *n = bp->trail->next; - free (bp->trail); - bp->trail = n; - } - while (bp->oscillators) { - oscillator *n = bp->oscillators->next; - free (bp->oscillators); - bp->oscillators = n; - } - -} - -XSCREENSAVER_MODULE_2 ("RaverHoop", raverhoop, hoop) - -#endif /* USE_GL */ |
