From d3a98cf6cbc3bd0b9efc570f58e8812c03931c18 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 16 Oct 2018 10:08:48 +0200 Subject: Original 5.40 --- hacks/glx/noof.c | 519 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 519 insertions(+) create mode 100644 hacks/glx/noof.c (limited to 'hacks/glx/noof.c') diff --git a/hacks/glx/noof.c b/hacks/glx/noof.c new file mode 100644 index 0000000..4e42840 --- /dev/null +++ b/hacks/glx/noof.c @@ -0,0 +1,519 @@ +/* noof, Copyright (c) 2004-2018 Bill Torzewski + * + * 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. + * + * Originally a demo included with GLUT; + * (Apparently this was called "diatoms" on Irix.) + * ported to raw GL and xscreensaver by jwz, 12-Feb-2004. + */ + +#define DEFAULTS "*delay: 10000 \n" \ + "*showFPS: False \n" \ + "*fpsSolid: True \n" \ + "*doubleBuffer: False \n" \ + "*suppressRotationAnimation: True\n" \ + +# define free_noof 0 +# define release_noof 0 +# define noof_handle_event 0 +#include "xlockmore.h" +#include "pow2.h" + +#ifdef USE_GL /* whole file */ + +#define N_SHAPES 7 + +ENTRYPOINT ModeSpecOpt noof_opts = {0, NULL, 0, NULL, NULL}; + +typedef struct { + GLXContext *glx_context; + + float pos[N_SHAPES * 3]; + float dir[N_SHAPES * 3]; + float acc[N_SHAPES * 3]; + float col[N_SHAPES * 3]; + float hsv[N_SHAPES * 3]; + float hpr[N_SHAPES * 3]; + float ang[N_SHAPES]; + float spn[N_SHAPES]; + float sca[N_SHAPES]; + float geep[N_SHAPES]; + float peep[N_SHAPES]; + float speedsq[N_SHAPES]; + int blad[N_SHAPES]; + + float ht, wd; + + int tko; + + GLuint screenshot_texture, tex_w, tex_h; + +} noof_configuration; + +static noof_configuration *bps = NULL; + + +static void +initshapes(noof_configuration *bp, int i) +{ + int k; + float f; + + /* random init of pos, dir, color */ + for (k = i * 3; k <= i * 3 + 2; k++) { + f = random() / (double) RAND_MAX; + bp->pos[k] = f; + f = random() / (double) RAND_MAX; + f = (f - 0.5) * 0.05; + bp->dir[k] = f; + f = random() / (double) RAND_MAX; + f = (f - 0.5) * 0.0002; + bp->acc[k] = f; + f = random() / (double) RAND_MAX; + bp->col[k] = f; + } + + bp->speedsq[i] = bp->dir[i * 3] * bp->dir[i * 3] + bp->dir[i * 3 + 1] * bp->dir[i * 3 + 1]; + f = random() / (double) RAND_MAX; + bp->blad[i] = 2 + (int) (f * 17.0); + f = random() / (double) RAND_MAX; + bp->ang[i] = f; + f = random() / (double) RAND_MAX; + bp->spn[i] = (f - 0.5) * 40.0 / (10 + bp->blad[i]); + f = random() / (double) RAND_MAX; + bp->sca[i] = (f * 0.1 + 0.08); + bp->dir[i * 3] *= bp->sca[i]; + bp->dir[i * 3 + 1] *= bp->sca[i]; + + f = random() / (double) RAND_MAX; + bp->hsv[i * 3] = f * 360.0; + + f = random() / (double) RAND_MAX; + bp->hsv[i * 3 + 1] = f * 0.6 + 0.4; + + f = random() / (double) RAND_MAX; + bp->hsv[i * 3 + 2] = f * 0.7 + 0.3; + + f = random() / (double) RAND_MAX; + bp->hpr[i * 3] = f * 0.005 * 360.0; + f = random() / (double) RAND_MAX; + bp->hpr[i * 3 + 1] = f * 0.03; + f = random() / (double) RAND_MAX; + bp->hpr[i * 3 + 2] = f * 0.02; + + bp->geep[i] = 0; + f = random() / (double) RAND_MAX; + bp->peep[i] = 0.01 + f * 0.2; +} + +static const float bladeratio[] = +{ + /* nblades = 2..7 */ + 0.0, 0.0, 3.00000, 1.73205, 1.00000, 0.72654, 0.57735, 0.48157, + /* 8..13 */ + 0.41421, 0.36397, 0.19076, 0.29363, 0.26795, 0.24648, + /* 14..19 */ + 0.22824, 0.21256, 0.19891, 0.18693, 0.17633, 0.16687, +}; + +static int +drawleaf(noof_configuration *bp, int l) +{ + int polys = 0; + int b, blades; + float x, y; + float wobble; + + blades = bp->blad[l]; + + y = 0.10 * sin(bp->geep[l] * M_PI / 180.0) + 0.099 * sin(bp->geep[l] * 5.12 * M_PI / 180.0); + if (y < 0) + y = -y; + x = 0.15 * cos(bp->geep[l] * M_PI / 180.0) + 0.149 * cos(bp->geep[l] * 5.12 * M_PI / 180.0); + if (x < 0.0) + x = 0.0 - x; + if (y < 0.001 && x > 0.000002 && ((bp->tko & 0x1) == 0)) { + initshapes(bp, l); /* let it become reborn as something + else */ + bp->tko++; + return polys; + } { + float w1 = sin(bp->geep[l] * 15.3 * M_PI / 180.0); + wobble = 3.0 + 2.00 * sin(bp->geep[l] * 0.4 * M_PI / 180.0) + 3.94261 * w1; + } + + /** + if(blades == 2) if (y > 3.000*x) y = x*3.000; + if(blades == 3) if (y > 1.732*x) y = x*1.732; + if(blades == 4) if (y > x) y = x; + if(blades == 5) if (y > 0.726*x) y = x*0.726; + if(blades == 6) if (y > 0.577*x) y = x*0.577; + if(blades == 7) if (y > 0.481*x) y = x*0.481; + if(blades == 8) if (y > 0.414*x) y = x*0.414; + */ + if (y > x * bladeratio[blades]) + y = x * bladeratio[blades]; + + for (b = 0; b < blades; b++) { + glPushMatrix(); + glTranslatef(bp->pos[l * 3], bp->pos[l * 3 + 1], bp->pos[l * 3 + 2]); + glRotatef(bp->ang[l] + b * (360.0 / blades), 0.0, 0.0, 1.0); + glScalef(wobble * bp->sca[l], wobble * bp->sca[l], wobble * bp->sca[l]); + /** + if(tko & 0x40000) glColor3f(col[l*3], col[l*3+1], col[l*3+2]); + else + */ + glColor4ub(0, 0, 0, 0x60); + + /* constrain geep cooridinates here XXX */ + glEnable(GL_BLEND); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2f(x * bp->sca[l], 0.0); + glVertex2f(x, y); + glVertex2f(x, -y); /* C */ + glVertex2f(0.3, 0.0); /* D */ + polys += 2; + glEnd(); + + /** + if(tko++ & 0x40000) glColor3f(0,0,0); + else + */ + glColor3f(bp->col[l * 3], bp->col[l * 3 + 1], bp->col[l * 3 + 2]); + glBegin(GL_LINE_LOOP); + glVertex2f(x * bp->sca[l], 0.0); + glVertex2f(x, y); + glVertex2f(0.3, 0.0); /* D */ + glVertex2f(x, -y); /* C */ + polys += 3; + glEnd(); + glDisable(GL_BLEND); + + glPopMatrix(); + } + return polys; +} + +static void +motionUpdate(noof_configuration *bp, int t) +{ + if (bp->pos[t * 3] < -bp->sca[t] * bp->wd && bp->dir[t * 3] < 0.0) { + bp->dir[t * 3] = -bp->dir[t * 3]; + /** + acc[t*3+1] += 0.8*acc[t*3]; + acc[t*3] = -0.8*acc[t*3]; + */ + } else if (bp->pos[t * 3] > (1 + bp->sca[t]) * bp->wd && bp->dir[t * 3] > 0.0) { + bp->dir[t * 3] = -bp->dir[t * 3]; + /** + acc[t*3+1] += 0.8*acc[t*3]; + acc[t*3] = -0.8*acc[t*3]; + */ + } else if (bp->pos[t * 3 + 1] < -bp->sca[t] * bp->ht && bp->dir[t * 3 + 1] < 0.0) { + bp->dir[t * 3 + 1] = -bp->dir[t * 3 + 1]; + /** + acc[t*3] += 0.8*acc[t*3+1]; + acc[t*3+1] = -0.8*acc[t*3+1]; + */ + } else if (bp->pos[t * 3 + 1] > (1 + bp->sca[t]) * bp->ht && bp->dir[t * 3 + 1] > 0.0) { + bp->dir[t * 3 + 1] = -bp->dir[t * 3 + 1]; + /** + acc[t*3] += 0.8*acc[t*3+1]; + acc[t*3+1] = -0.8*acc[t*3+1]; + */ + } + + bp->pos[t * 3] += bp->dir[t * 3]; + bp->pos[t * 3 + 1] += bp->dir[t * 3 + 1]; + /** + dir[t*3] += acc[t*3]; + dir[t*3+1] += acc[t*3+1]; + */ + bp->ang[t] += bp->spn[t]; + bp->geep[t] += bp->peep[t]; + if (bp->geep[t] > 360 * 5.0) + bp->geep[t] -= 360 * 5.0; + if (bp->ang[t] < 0.0) { + bp->ang[t] += 360.0; + } + if (bp->ang[t] > 360.0) { + bp->ang[t] -= 360.0; + } +} + +static void +colorUpdate(noof_configuration *bp, int i) +{ + if (bp->hsv[i * 3 + 1] <= 0.5 && bp->hpr[i * 3 + 1] < 0.0) + bp->hpr[i * 3 + 1] = -bp->hpr[i * 3 + 1]; /* adjust s */ + if (bp->hsv[i * 3 + 1] >= 1.0 && bp->hpr[i * 3 + 1] > 0.0) + bp->hpr[i * 3 + 1] = -bp->hpr[i * 3 + 1]; /* adjust s */ + if (bp->hsv[i * 3 + 2] <= 0.4 && bp->hpr[i * 3 + 2] < 0.0) + bp->hpr[i * 3 + 2] = -bp->hpr[i * 3 + 2]; /* adjust s */ + if (bp->hsv[i * 3 + 2] >= 1.0 && bp->hpr[i * 3 + 2] > 0.0) + bp->hpr[i * 3 + 2] = -bp->hpr[i * 3 + 2]; /* adjust s */ + + bp->hsv[i * 3] += bp->hpr[i * 3]; + bp->hsv[i * 3 + 1] += bp->hpr[i * 3 + 1]; + bp->hsv[i * 3 + 2] += bp->hpr[i * 3 + 2]; + + /* --- hsv -> rgb --- */ +#define H(hhh) hhh[i*3 ] +#define S(hhh) hhh[i*3+1] +#define V(hhh) hhh[i*3+2] + +#define R(hhh) hhh[i*3 ] +#define G(hhh) hhh[i*3+1] +#define B(hhh) hhh[i*3+2] + + if (V(bp->hsv) < 0.0) + V(bp->hsv) = 0.0; + if (V(bp->hsv) > 1.0) + V(bp->hsv) = 1.0; + if (S(bp->hsv) <= 0.0) { + R(bp->col) = V(bp->hsv); + G(bp->col) = V(bp->hsv); + B(bp->col) = V(bp->hsv); + } else { + float f, h, p, q, t, v; + int hi; + + while (H(bp->hsv) < 0.0) + H(bp->hsv) += 360.0; + while (H(bp->hsv) >= 360.0) + H(bp->hsv) -= 360.0; + + if (S(bp->hsv) < 0.0) + S(bp->hsv) = 0.0; + if (S(bp->hsv) > 1.0) + S(bp->hsv) = 1.0; + + h = H(bp->hsv) / 60.0; + hi = (int) (h); + f = h - hi; + v = V(bp->hsv); + p = V(bp->hsv) * (1 - S(bp->hsv)); + q = V(bp->hsv) * (1 - S(bp->hsv) * f); + t = V(bp->hsv) * (1 - S(bp->hsv) * (1 - f)); + + if (hi <= 0) { + R(bp->col) = v; + G(bp->col) = t; + B(bp->col) = p; + } else if (hi == 1) { + R(bp->col) = q; + G(bp->col) = v; + B(bp->col) = p; + } else if (hi == 2) { + R(bp->col) = p; + G(bp->col) = v; + B(bp->col) = t; + } else if (hi == 3) { + R(bp->col) = p; + G(bp->col) = q; + B(bp->col) = v; + } else if (hi == 4) { + R(bp->col) = t; + G(bp->col) = p; + B(bp->col) = v; + } else { + R(bp->col) = v; + G(bp->col) = p; + B(bp->col) = q; + } + } +} + +static void +gravity(noof_configuration *bp, float fx) +{ + int a, b; + + for (a = 0; a < N_SHAPES; a++) { + for (b = 0; b < a; b++) { + float t, d2; + + t = bp->pos[b * 3] - bp->pos[a * 3]; + d2 = t * t; + t = bp->pos[b * 3 + 1] - bp->pos[a * 3 + 1]; + d2 += t * t; + if (d2 < 0.000001) + d2 = 0.00001; + if (d2 < 0.1) { + + float v0, v1, z; + v0 = bp->pos[b * 3] - bp->pos[a * 3]; + v1 = bp->pos[b * 3 + 1] - bp->pos[a * 3 + 1]; + + z = 0.00000001 * fx / (d2); + + bp->dir[a * 3] += v0 * z * bp->sca[b]; + bp->dir[b * 3] += -v0 * z * bp->sca[a]; + bp->dir[a * 3 + 1] += v1 * z * bp->sca[b]; + bp->dir[b * 3 + 1] += -v1 * z * bp->sca[a]; + + } + } + /** apply brakes + if(dir[a*3]*dir[a*3] + dir[a*3+1]*dir[a*3+1] + > 0.0001) { + dir[a*3] *= 0.9; + dir[a*3+1] *= 0.9; + } + */ + } +} + +ENTRYPOINT void +draw_noof (ModeInfo *mi) +{ + int i; + noof_configuration *bp = &bps[MI_SCREEN(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); + + /* In the olden days, one could just render directly into the front buffer, + or fail to clear the back buffer and assume that one's bits were still + there. Not so on modern devices, particularly mobile. So to achieve + the effect of frame N+1 accumulating atop frame N, we must save and + restore a screenshot of frame N. + */ + if (bp->screenshot_texture) + { + GLfloat tw = MI_WIDTH(mi) / (GLfloat) bp->tex_w; + GLfloat th = MI_HEIGHT(mi) / (GLfloat) bp->tex_h; + glDisable (GL_BLEND); + glEnable (GL_TEXTURE_2D); + glBindTexture (GL_TEXTURE_2D, bp->screenshot_texture); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glBegin (GL_QUADS); + glTexCoord2f (0, 0); glVertex3f (0, 0, 0); + glTexCoord2f (tw, 0); glVertex3f (bp->wd, 0, 0); + glTexCoord2f (tw, th); glVertex3f (bp->wd, bp->ht, 0); + glTexCoord2f (0, th); glVertex3f (0, bp->ht, 0); + glEnd(); + glDisable (GL_TEXTURE_2D); + glClear (GL_DEPTH_BUFFER_BIT); + } + + mi->polygon_count = 0; + + /** + if((random() & 0xff) == 0x34){ + glClear(GL_COLOR_BUFFER_BIT); + } + + if((tko & 0x1f) == 0x1f){ + glEnable(GL_BLEND); + glColor4f(0.0, 0.0, 0.0, 0.09); + glRectf(0.0, 0.0, wd, ht); + glDisable(GL_BLEND); +#ifdef __sgi + sginap(0); +#endif + } + */ + + gravity(bp, -2.0); + for (i = 0; i < N_SHAPES; i++) { + motionUpdate(bp, i); + colorUpdate(bp, i); + mi->polygon_count += drawleaf(bp, i); + } + + if (bp->screenshot_texture) /* Store a screenshot into the texture. */ + { + glDisable (GL_BLEND); + glEnable (GL_TEXTURE_2D); + glBindTexture (GL_TEXTURE_2D, bp->screenshot_texture); + glCopyTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, 0, 0, + MI_WIDTH(mi), MI_HEIGHT(mi)); + check_gl_error("screenshot texture"); + glDisable (GL_TEXTURE_2D); + } + + if (mi->fps_p) do_fps (mi); + glFinish(); + + glXSwapBuffers(MI_DISPLAY(mi), MI_WINDOW(mi)); +} + + +ENTRYPOINT void +reshape_noof(ModeInfo *mi, int w, int h) +{ + noof_configuration *bp = &bps[MI_SCREEN(mi)]; + char *s; + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + if (w <= h) { + bp->wd = 1.0; + bp->ht = (GLfloat) h / (GLfloat) w; + glOrtho(0.0, 1.0, + 0.0, 1.0 * (GLfloat) h / (GLfloat) w, + -16.0, 4.0); + } else { + bp->wd = (GLfloat) w / (GLfloat) h; + bp->ht = 1.0; + glOrtho(0.0, 1.0 * (GLfloat) w / (GLfloat) h, + 0.0, 1.0, + -16.0, 4.0); + } + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + if (!bp->screenshot_texture) + glGenTextures (1, &bp->screenshot_texture); + + glEnable (GL_TEXTURE_2D); + glBindTexture (GL_TEXTURE_2D, bp->screenshot_texture); + + bp->tex_w = to_pow2 (MI_WIDTH(mi)); + bp->tex_h = to_pow2 (MI_HEIGHT(mi)); + s = calloc (4, bp->tex_w * bp->tex_h); /* init with black */ + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, bp->tex_w, bp->tex_h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, s); + check_gl_error ("texture generation"); + free (s); + glDisable (GL_TEXTURE_2D); + glClear (GL_COLOR_BUFFER_BIT); +} + +ENTRYPOINT void +init_noof (ModeInfo *mi) +{ + int i; + noof_configuration *bp; + + MI_INIT (mi, bps); + + bp = &bps[MI_SCREEN(mi)]; + + bp->glx_context = init_GL(mi); + + glEnable(GL_LINE_SMOOTH); + glShadeModel(GL_FLAT); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + for (i = 0; i < N_SHAPES; i++) + initshapes(bp, i); + + reshape_noof (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); +} + + +XSCREENSAVER_MODULE ("Noof", noof) + +#endif /* USE_GL */ -- cgit v1.2.3-55-g7522