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/hydrostat.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/hydrostat.c')
| -rw-r--r-- | hacks/glx/hydrostat.c | 816 |
1 files changed, 0 insertions, 816 deletions
diff --git a/hacks/glx/hydrostat.c b/hacks/glx/hydrostat.c deleted file mode 100644 index 6ff00e8..0000000 --- a/hacks/glx/hydrostat.c +++ /dev/null @@ -1,816 +0,0 @@ -/* hydrostat, Copyright (C) 2012 by Justin Windle - * Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org> - * - * 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. - * - * Tentacle simulation using inverse kinematics. - * - * http://soulwire.co.uk/experiments/muscular-hydrostats/ - * https://github.com/soulwire/Muscular-Hydrostats/ - * - * Ported to C from Javascript by jwz, May 2016 - */ - -#define DEFAULTS "*delay: 20000 \n" \ - "*count: 3 \n" \ - "*showFPS: False \n" \ - "*wireframe: False \n" \ - "*suppressRotationAnimation: True\n" \ - -# define release_hydrostat 0 - -#include "xlockmore.h" -#include "colors.h" -#include "sphere.h" -#include "normals.h" -#include "gltrackball.h" -#include <ctype.h> - -#ifdef USE_GL /* whole file */ - -/* It looks bad when you rotate it with the trackball, because it reveals - that the tentacles are moving in a 2d plane. But it's useful for - debugging. */ -#undef USE_TRACKBALL - -#define DEF_SPEED "1.0" -#define DEF_PULSE "True" -#define DEF_HEAD_RADIUS "60" -#define DEF_TENTACLES "35" -#define DEF_THICKNESS "18" -#define DEF_LENGTH "55" -#define DEF_GRAVITY "0.5" -#define DEF_CURRENT "0.25" -#define DEF_FRICTION "0.02" -#define DEF_OPACITY "0.8" - - -#define TENTACLE_FACES 5 - -typedef struct { - XYZ pos, opos, v; -} node; - -typedef struct { - int length; - GLfloat radius; - GLfloat spacing; - GLfloat friction; - GLfloat th; - node *nodes; - GLfloat color[4]; -} tentacle; - -typedef struct { - XYZ pos, from, to; - GLfloat ratio, pulse, rate; - GLfloat head_radius; - GLfloat thickness; - int ntentacles; - tentacle *tentacles; - GLfloat color[4]; -} squid; - -typedef struct { - GLXContext *glx_context; - Bool button_down_p; - int dragging; - squid **squids; - GLfloat cos_sin_table[2 * (TENTACLE_FACES + 1)]; - GLuint head; - int head_polys; -# ifdef USE_TRACKBALL - trackball_state *trackball; -# endif -} hydrostat_configuration; - -static hydrostat_configuration *bps = NULL; - -static Bool do_pulse; -static GLfloat speed_arg; -static GLfloat head_radius_arg; -static GLfloat ntentacles_arg; -static GLfloat thickness_arg; -static GLfloat length_arg; -static GLfloat gravity_arg; -static GLfloat current_arg; -static GLfloat friction_arg; -static GLfloat opacity_arg; - -static XrmOptionDescRec opts[] = { - { "-pulse", ".pulse", XrmoptionNoArg, "True" }, - { "+pulse", ".pulse", XrmoptionNoArg, "False" }, - { "-speed", ".speed", XrmoptionSepArg, 0 }, - { "-head-radius", ".headRadius", XrmoptionSepArg, 0 }, - { "-tentacles", ".tentacles", XrmoptionSepArg, 0 }, - { "-thickness", ".thickness", XrmoptionSepArg, 0 }, - { "-length", ".length", XrmoptionSepArg, 0 }, - { "-gravity", ".gravity", XrmoptionSepArg, 0 }, - { "-current", ".current", XrmoptionSepArg, 0 }, - { "-friction", ".friction", XrmoptionSepArg, 0 }, - { "-opacity", ".opacity", XrmoptionSepArg, 0 }, -}; - -static argtype vars[] = { - { &do_pulse, "pulse", "Pulse", DEF_PULSE, t_Bool }, - { &speed_arg, "speed", "Speed", DEF_SPEED, t_Float }, - { &head_radius_arg, "headRadius", "HeadRadius", DEF_HEAD_RADIUS, t_Float }, - { &ntentacles_arg, "tentacles", "Tentacles", DEF_TENTACLES, t_Float }, - { &thickness_arg, "thickness", "Thickness", DEF_THICKNESS, t_Float }, - { &length_arg, "length", "Length", DEF_LENGTH, t_Float }, - { &gravity_arg, "gravity", "Gravity", DEF_GRAVITY, t_Float }, - { ¤t_arg, "current", "Current", DEF_CURRENT, t_Float }, - { &friction_arg, "friction", "Friction", DEF_FRICTION, t_Float }, - { &opacity_arg, "opacity", "Opacity", DEF_OPACITY, t_Float }, -}; - -ENTRYPOINT ModeSpecOpt hydrostat_opts = {countof(opts), opts, - countof(vars), vars, NULL}; - - -static void -move_tentacle (squid *sq, tentacle *t) -{ - int i, j; - node *prev = &t->nodes[0]; - int rot = (int) current_device_rotation(); - - for (i = 1, j = 0; i < t->length; i++, j++) - { - XYZ d, p; - GLfloat da; - node *n = &t->nodes[i]; - - /* Sadly, this is still computing motion in a 2d plane, so the - tentacles look dumb if the scene is rotated. */ - - n->pos.x += n->v.x; - n->pos.y += n->v.y; - n->pos.z += n->v.z; - - d.x = prev->pos.x - n->pos.x; - d.y = prev->pos.y - n->pos.y; - d.z = prev->pos.z - n->pos.z; - da = atan2 (d.z, d.x); - - p.x = n->pos.x + cos (da) * t->spacing * t->length; - p.y = n->pos.y + cos (da) * t->spacing * t->length; - p.z = n->pos.z + sin (da) * t->spacing * t->length; - - n->pos.x = prev->pos.x - (p.x - n->pos.x); - n->pos.y = prev->pos.y - (p.y - n->pos.y); - n->pos.z = prev->pos.z - (p.z - n->pos.z); - - n->v.x = n->pos.x - n->opos.x; - n->v.y = n->pos.y - n->opos.y; - n->v.z = n->pos.z - n->opos.z; - - n->v.x *= t->friction * (1 - friction_arg); - n->v.y *= t->friction * (1 - friction_arg); - n->v.z *= t->friction * (1 - friction_arg); - - switch (rot) { - case 90: case -270: - n->v.x += gravity_arg; - n->v.y -= current_arg; - n->v.z -= current_arg; - break; - case -90: case 270: - n->v.x -= gravity_arg; - n->v.y += current_arg; - n->v.z += current_arg; - break; - case 180: case -180: - n->v.x -= current_arg; - n->v.y -= current_arg; - n->v.z -= gravity_arg; - break; - default: - n->v.x += current_arg; - n->v.y += current_arg; - n->v.z += gravity_arg; - break; - } - - n->opos.x = n->pos.x; - n->opos.y = n->pos.y; - n->opos.z = n->pos.z; - - prev = n; - } -} - - -static GLfloat -ease_fn (GLfloat r) -{ - return cos ((r/2 + 1) * M_PI) + 1; /* Smooth curve up, end at slope 1. */ -} - - -/* Squirty motion: fast acceleration, then fade. */ -static GLfloat -ease_ratio (GLfloat r) -{ - GLfloat ease = 0.05; - GLfloat ease2 = 1-ease; - if (r <= 0) r = 0; - else if (r >= 1) r = 1; - else if (r <= ease) r = ease * ease_fn (r / ease); - else r = 1 - ease2 * ease_fn ((1 - r) / ease2); - return r; -} - - -static void -move_squid (ModeInfo *mi, squid *sq) -{ - hydrostat_configuration *bp = &bps[MI_SCREEN(mi)]; - GLfloat step = M_PI * 2 / sq->ntentacles; - int i; - GLfloat radius = head_radius_arg; - GLfloat r; - - /* Move to a new position */ - - if (! bp->button_down_p) - { - sq->ratio += speed_arg * 0.01; - if (sq->ratio >= 1) - { - sq->ratio = -(frand(2.0) + frand(2.0) + frand(2.0)); - sq->from.x = sq->to.x; - sq->from.y = sq->to.y; - sq->from.z = sq->to.z; - sq->to.x = 250 - frand(500); - sq->to.y = 250 - frand(500); - sq->to.z = 250 - frand(500); - } - - r = sq->ratio > 0 ? ease_ratio (sq->ratio) : 0; - sq->pos.x = sq->from.x + r * (sq->to.x - sq->from.x); - sq->pos.y = sq->from.y + r * (sq->to.y - sq->from.y); - sq->pos.z = sq->from.z + r * (sq->to.z - sq->from.z); - } - - if (do_pulse) - { - GLfloat p = pow (sin (sq->pulse * M_PI), 18); - sq->head_radius = (head_radius_arg * 0.7 + - head_radius_arg * 0.3 * p); - radius = sq->head_radius * 0.25; - sq->pulse += sq->rate * speed_arg * 0.02; - if (sq->pulse > 1) sq->pulse = 0; - } - - for (i = 0; i < sq->ntentacles; i++) - { - tentacle *tt = &sq->tentacles[i]; - GLfloat th = i * step; - GLfloat px = cos (th) * radius; - GLfloat py = sin (th) * radius; - tt->th = th; - tt->nodes[0].pos.x = sq->pos.x + px; - tt->nodes[0].pos.y = sq->pos.y + py; - tt->nodes[0].pos.z = sq->pos.z; - move_tentacle (sq, tt); - } -} - - -/* Find the angle at which the head should be tilted in the XY plane. - */ -static GLfloat -head_angle (ModeInfo *mi, squid *sq) -{ - int i; - XYZ sum = { 0, }; - - for (i = 0; i < sq->ntentacles; i++) - { - tentacle *t = &sq->tentacles[i]; - int j = t->length / 3; /* Pick a node toward the top */ - node *n = &t->nodes[j]; - sum.x += n->pos.x; - sum.y += n->pos.y; - sum.z += n->pos.z; - } - - sum.x /= sq->ntentacles; - sum.y /= sq->ntentacles; - sum.z /= sq->ntentacles; - - sum.x -= sq->pos.x; - sum.y -= sq->pos.y; - sum.z -= sq->pos.z; - - return (-atan2 (sum.x, sum.z) * (180 / M_PI)); -} - - -static void -draw_head (ModeInfo *mi, squid *sq, GLfloat scale) -{ - hydrostat_configuration *bp = &bps[MI_SCREEN(mi)]; - GLfloat c2[4]; - GLfloat angle = head_angle (mi, sq); - - scale *= 1.1; - - glPushMatrix(); - glTranslatef (sq->pos.x, sq->pos.y, sq->pos.z); - glScalef (sq->head_radius, sq->head_radius, sq->head_radius); - glScalef (scale, scale, scale); - glRotatef (90, 1, 0, 0); - - memcpy (c2, sq->color, sizeof(c2)); - if (opacity_arg < 1.0 && scale >= 1.0) - c2[3] *= 0.6; - glColor4fv (c2); - glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, c2); - - glTranslatef (0, 0.3, 0); - glRotatef (angle, 0, 0, 1); - - glCallList (bp->head); - mi->polygon_count += bp->head_polys; - - glPopMatrix(); -} - - -static void -draw_squid (ModeInfo *mi, squid *sq) -{ - hydrostat_configuration *bp = &bps[MI_SCREEN(mi)]; - int wire = MI_IS_WIREFRAME(mi); - int i; - glPushMatrix(); - glRotatef (90, 1, 0, 0); - - if (opacity_arg < 1.0) - draw_head (mi, sq, 0.75); - - if (!wire) { - glFrontFace (GL_CCW); - glBegin (GL_TRIANGLE_STRIP); - } - - for (i = 0; i < sq->ntentacles; i++) - { - tentacle *t = &sq->tentacles[i]; - int j; - - glColor4fv (t->color); - glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, t->color); - - if (wire) - { - glBegin (GL_LINE_STRIP); - for (j = 0; j < t->length; j++) - glVertex3f (t->nodes[j].pos.x, - t->nodes[j].pos.y, - t->nodes[j].pos.z); - glEnd(); - mi->polygon_count += t->length; - } - else - { - GLfloat radius = t->radius * thickness_arg; - GLfloat rstep = radius / t->length; - for (j = 0; j < t->length-1; j++) - { - int k; - node *n1 = &t->nodes[j]; - node *n2 = &t->nodes[j+1]; - GLfloat X = (n1->pos.x - n2->pos.x); - GLfloat Y = (n1->pos.y - n2->pos.y); - GLfloat Z = (n1->pos.z - n2->pos.z); - GLfloat L = sqrt (X*X + Y*Y + Z*Z); - GLfloat r2 = radius - rstep; - GLfloat L2 = sqrt (X*X + Y*Y); - - for (k = 0; k <= TENTACLE_FACES; k++) - { - GLfloat c = bp->cos_sin_table[2 * k]; - GLfloat s = bp->cos_sin_table[2 * k + 1]; - GLfloat x1 = radius * c; - GLfloat y1 = radius * s; - GLfloat z1 = 0; - GLfloat x2 = r2 * c; - GLfloat y2 = r2 * s; - GLfloat z2 = L; - - GLfloat x1t = (L2*X*z1-X*Z*y1+L*Y*x1)/(L*L2); - GLfloat z1t = (L2*Y*z1-Y*Z*y1-L*X*x1)/(L*L2); - GLfloat y1t = (Z*z1+L2*y1)/L; - - GLfloat x2t = (L2*X*z2-X*Z*y2+L*Y*x2)/(L*L2) + n1->pos.x; - GLfloat z2t = (L2*Y*z2-Y*Z*y2-L*X*x2)/(L*L2) + n1->pos.y; - GLfloat y2t = (Z*z2+L2*y2)/L + n1->pos.z; - - glNormal3f (x1t, z1t, y1t); - - x1t += n1->pos.x; - z1t += n1->pos.y; - y1t += n1->pos.z; - - if (k == 0) - glVertex3f (x1t, z1t, y1t); - glVertex3f (x1t, z1t, y1t); - - glVertex3f (x2t, z2t, y2t); - if (k == TENTACLE_FACES) - glVertex3f (x2t, z2t, y2t); - - mi->polygon_count++; - } - radius = r2; - } - } - } - - if (!wire) - glEnd (); - - draw_head (mi, sq, 1.0); - - glPopMatrix(); -} - - -static squid * -make_squid (ModeInfo *mi, int which) -{ - squid *sq = calloc (1, sizeof(*sq)); - int i; - - sq->head_radius = head_radius_arg; - sq->thickness = thickness_arg; - sq->ntentacles = ntentacles_arg; - - sq->color[0] = 0.1 + frand(0.7); - sq->color[1] = 0.5 + frand(0.5); - sq->color[2] = 0.1 + frand(0.7); - sq->color[3] = opacity_arg; - - sq->from.x = sq->to.x = sq->pos.x = 200 - frand(400); - sq->from.y = sq->to.y = sq->pos.y = 200 - frand(400); - sq->from.z = sq->to.z = sq->pos.z = -frand(200); - - sq->ratio = -frand(3); - - if (which > 0) /* Start others off screen, and moving in */ - { - sq->from.x = sq->to.x = sq->pos.x = 800 + frand(500) - * (random()&1 ? 1 : -1); - sq->from.y = sq->to.y = sq->pos.y = 800 + frand(500) - * (random()&1 ? 1 : -1); - sq->ratio = 0; - } - - if (do_pulse) - sq->pulse = frand(1.0); - sq->rate = 0.8 + frand(0.2); - - sq->tentacles = (tentacle *) - calloc (sq->ntentacles, sizeof(*sq->tentacles)); - for (i = 0; i < sq->ntentacles; i++) - { - int j; - tentacle *t = &sq->tentacles[i]; - GLfloat shade = 0.75 + frand(0.25); - - t->length = 2 + length_arg * (0.8 + frand (0.4)); - t->radius = 0.05 + frand (0.95); - t->spacing = 0.02 + frand (0.08); - t->friction = 0.7 + frand (0.18); - t->nodes = (node *) calloc (t->length + 1, sizeof (*t->nodes)); - - t->color[0] = shade * sq->color[0]; - t->color[1] = shade * sq->color[1]; - t->color[2] = shade * sq->color[2]; - t->color[3] = sq->color[3]; - - for (j = 0; j < t->length; j++) - { - node *n = &t->nodes[j]; - n->pos.x = sq->pos.x; - n->pos.y = sq->pos.y; - n->pos.z = sq->pos.z + j; - } - } - - return sq; -} - -/* qsort comparator for sorting squid by depth */ -static int -cmp_squid (const void *aa, const void *bb) -{ - squid * const *a = aa; - squid * const *b = bb; - return ((int) ((*b)->pos.y * 10000) - - (int) ((*a)->pos.y * 10000)); -} - - -static void -free_squid (squid *sq) -{ - int i; - for (i = 0; i < sq->ntentacles; i++) - free (sq->tentacles[i].nodes); - free (sq->tentacles); - free (sq); -} - - -/* Window management, etc - */ -ENTRYPOINT void -reshape_hydrostat (ModeInfo *mi, int width, int height) -{ - GLfloat h = (GLfloat) height / (GLfloat) width; - - glViewport (0, 0, (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 -hydrostat_handle_event (ModeInfo *mi, XEvent *event) -{ - hydrostat_configuration *bp = &bps[MI_SCREEN(mi)]; - int w = MI_WIDTH(mi); - int h = MI_HEIGHT(mi); - int x, y; - -# ifdef USE_TRACKBALL - if (gltrackball_event_handler (event, bp->trackball, - MI_WIDTH (mi), MI_HEIGHT (mi), - &bp->button_down_p)) - return True; -# endif - - switch (event->xany.type) { - case ButtonPress: case ButtonRelease: - x = event->xbutton.x; - y = event->xbutton.y; - break; - case MotionNotify: - x = event->xmotion.x; - y = event->xmotion.y; - break; - default: - x = y = 0; - } - - x -= w/2; - y -= h/2; - x *= 0.7; - y *= 0.7; - - if (event->xany.type == ButtonPress) - { - int i; - GLfloat D0 = 999999; - - /* This is pretty halfassed hit detection, but it works ok... */ - for (i = 0; i < MI_COUNT(mi); i++) - { - squid *s = bp->squids[i]; - GLfloat X = s->pos.x - x; - GLfloat Y = s->pos.z - y; - GLfloat D = sqrt(X*X + Y*Y); - if (D < D0) - { - bp->dragging = i; - D0 = D; - } - } - - if (D0 > 300) /* Too far away, missed hit */ - { - bp->dragging = -1; - return False; - } - - bp->squids[bp->dragging]->ratio = -3; - bp->button_down_p = True; - - return True; - } - else if (event->xany.type == ButtonRelease && bp->dragging >= 0) - { - bp->button_down_p = False; - bp->dragging = -1; - return True; - } - else if (event->xany.type == MotionNotify && bp->dragging >= 0) - { - squid *s = bp->squids[bp->dragging]; - s->from.x = s->to.x = s->pos.x = x; - s->from.z = s->to.z = s->pos.z = y; - s->from.y = s->to.y = s->pos.y; - return True; - } - - return False; -} - - -ENTRYPOINT void -init_hydrostat (ModeInfo *mi) -{ - int wire = MI_IS_WIREFRAME(mi); - hydrostat_configuration *bp; - int i; - - MI_INIT (mi, bps); - - bp = &bps[MI_SCREEN(mi)]; - - bp->glx_context = init_GL(mi); - - reshape_hydrostat (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); - - if (!wire) - { - GLfloat pos[4] = {1.0, 1.0, 1.0, 0.0}; - GLfloat amb[4] = {0.0, 0.0, 0.0, 1.0}; - GLfloat dif[4] = {1.0, 1.0, 1.0, 1.0}; - GLfloat spc[4] = {0.0, 1.0, 1.0, 1.0}; - int k; - - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - - glLightfv(GL_LIGHT0, GL_POSITION, pos); - glLightfv(GL_LIGHT0, GL_AMBIENT, amb); - glLightfv(GL_LIGHT0, GL_DIFFUSE, dif); - glLightfv(GL_LIGHT0, GL_SPECULAR, spc); - - for (k = 0; k <= TENTACLE_FACES; k++) - { - GLfloat th = k * M_PI * 2 / TENTACLE_FACES; - bp->cos_sin_table[2 * k] = cos(th); - bp->cos_sin_table[2 * k + 1] = sin(th); - } - } - - glShadeModel(GL_SMOOTH); - - glEnable(GL_DEPTH_TEST); - glEnable(GL_NORMALIZE); - - if (MI_COUNT(mi) <= 0) - MI_COUNT(mi) = 1; - - if (random() & 1) - current_arg = -current_arg; - - if (MI_COUNT(mi) == 1 || wire) - opacity_arg = 1.0; - if (opacity_arg < 0.1) opacity_arg = 0.1; - if (opacity_arg > 1.0) opacity_arg = 1.0; - - bp->squids = (squid **) calloc (MI_COUNT(mi), sizeof(*bp->squids)); - for (i = 0; i < MI_COUNT(mi); i++) - bp->squids[i] = make_squid (mi, i); - - bp->dragging = -1; - - if (opacity_arg < 1.0) - { - glEnable (GL_BLEND); - glBlendFunc (GL_SRC_ALPHA, GL_ONE); - } - - i = wire ? 4 : 24; - bp->head = glGenLists (1); - glNewList (bp->head, GL_COMPILE); - glScalef (1, 1.1, 1); - bp->head_polys = unit_dome (wire ? 8 : 16, i, wire); - glRotatef (180, 0, 0, 1); - glScalef (1, 0.5, 1); - bp->head_polys += unit_dome (wire ? 8 : 8, i, wire); - glEndList (); - -# ifdef USE_TRACKBALL - bp->trackball = gltrackball_init (True); -# endif -} - - -ENTRYPOINT void -draw_hydrostat (ModeInfo *mi) -{ - hydrostat_configuration *bp = &bps[MI_SCREEN(mi)]; - Display *dpy = MI_DISPLAY(mi); - Window window = MI_WINDOW(mi); - int i; - - 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 (); - - glScalef (0.03, 0.03, 0.03); - -# ifdef USE_TRACKBALL - gltrackball_rotate (bp->trackball); -# endif - - mi->polygon_count = 0; - - if (opacity_arg < 1.0) - qsort (bp->squids, MI_COUNT(mi), sizeof(*bp->squids), cmp_squid); - - for (i = 0; i < MI_COUNT(mi); i++) - { - squid *sq = bp->squids[i]; - move_squid (mi, sq); - draw_squid (mi, sq); - if (opacity_arg < 1.0) - glClear (GL_DEPTH_BUFFER_BIT); - } - - if (! (random() % 700)) /* Reverse the flow every now and then */ - current_arg = -current_arg; - - glPopMatrix (); - - if (mi->fps_p) do_fps (mi); - glFinish(); - - glXSwapBuffers(dpy, window); -} - - -ENTRYPOINT void -free_hydrostat (ModeInfo *mi) -{ - hydrostat_configuration *bp = &bps[MI_SCREEN(mi)]; - int i; - - if (!bp->glx_context) return; - glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *bp->glx_context); - -# ifdef USE_TRACKBALL - if (bp->trackball) gltrackball_free (bp->trackball); -# endif - if (bp->squids) - { - for (i = 0; i < MI_COUNT(mi); i++) - free_squid (bp->squids[i]); - free (bp->squids); - } - - if (glIsList(bp->head)) glDeleteLists(bp->head, 1); -} - -XSCREENSAVER_MODULE ("Hydrostat", hydrostat) - -#endif /* USE_GL */ |
