1 /* noof, Copyright (c) 2004 Mark Kilgard <mjk@nvidia.com>
3 * Permission to use, copy, modify, distribute, and sell this software and its
4 * documentation for any purpose is hereby granted without fee, provided that
5 * the above copyright notice appear in all copies and that both that
6 * copyright notice and this permission notice appear in supporting
7 * documentation. No representations are made about the suitability of this
8 * software for any purpose. It is provided "as is" without express or
11 * Originally a demo included with GLUT;
12 * ported to raw GL and xscreensaver by jwz, 12-Feb-2004.
15 #include <X11/Intrinsic.h>
17 extern XtAppContext app;
19 #define PROGCLASS "Noof"
20 #define HACK_INIT init_noof
21 #define HACK_DRAW draw_noof
22 #define HACK_RESHAPE reshape_noof
23 #define noof_opts xlockmore_opts
25 #define DEFAULTS "*delay: 10000 \n" \
26 "*showFPS: False \n" \
27 "*fpsSolid: True \n" \
29 #include "xlockmore.h"
31 #ifdef USE_GL /* whole file */
34 GLXContext *glx_context;
37 static noof_configuration *bps = NULL;
38 ModeSpecOpt noof_opts = {0, NULL, 0, NULL, NULL};
41 /* --- shape parameters def'n --- */
43 static float pos[N_SHAPES * 3];
44 static float dir[N_SHAPES * 3];
45 static float acc[N_SHAPES * 3];
46 static float col[N_SHAPES * 3];
47 static float hsv[N_SHAPES * 3];
48 static float hpr[N_SHAPES * 3];
49 static float ang[N_SHAPES];
50 static float spn[N_SHAPES];
51 static float sca[N_SHAPES];
52 static float geep[N_SHAPES];
53 static float peep[N_SHAPES];
54 static float speedsq[N_SHAPES];
55 static int blad[N_SHAPES];
65 /* random init of pos, dir, color */
66 for (k = i * 3; k <= i * 3 + 2; k++) {
67 f = random() / 2147483647.0;
69 f = random() / 2147483647.0;
72 f = random() / 2147483647.0;
73 f = (f - 0.5) * 0.0002;
75 f = random() / 2147483647.0;
79 speedsq[i] = dir[i * 3] * dir[i * 3] + dir[i * 3 + 1] * dir[i * 3 + 1];
80 f = random() / 2147483647.0;
81 blad[i] = 2 + (int) (f * 17.0);
82 f = random() / 2147483647.0;
84 f = random() / 2147483647.0;
85 spn[i] = (f - 0.5) * 40.0 / (10 + blad[i]);
86 f = random() / 2147483647.0;
87 sca[i] = (f * 0.1 + 0.08);
89 dir[i * 3 + 1] *= sca[i];
91 f = random() / 2147483647.0;
92 hsv[i * 3] = f * 360.0;
94 f = random() / 2147483647.0;
95 hsv[i * 3 + 1] = f * 0.6 + 0.4;
97 f = random() / 2147483647.0;
98 hsv[i * 3 + 2] = f * 0.7 + 0.3;
100 f = random() / 2147483647.0;
101 hpr[i * 3] = f * 0.005 * 360.0;
102 f = random() / 2147483647.0;
103 hpr[i * 3 + 1] = f * 0.03;
104 f = random() / 2147483647.0;
105 hpr[i * 3 + 2] = f * 0.02;
108 f = random() / 2147483647.0;
109 peep[i] = 0.01 + f * 0.2;
114 static float bladeratio[] =
117 0.0, 0.0, 3.00000, 1.73205, 1.00000, 0.72654, 0.57735, 0.48157,
119 0.41421, 0.36397, 0.19076, 0.29363, 0.26795, 0.24648,
121 0.22824, 0.21256, 0.19891, 0.18693, 0.17633, 0.16687,
134 y = 0.10 * sin(geep[l] * M_PI / 180.0) + 0.099 * sin(geep[l] * 5.12 * M_PI / 180.0);
137 x = 0.15 * cos(geep[l] * M_PI / 180.0) + 0.149 * cos(geep[l] * 5.12 * M_PI / 180.0);
140 if (y < 0.001 && x > 0.000002 && ((tko & 0x1) == 0)) {
141 initshapes(l); /* let it become reborn as something
146 float w1 = sin(geep[l] * 15.3 * M_PI / 180.0);
147 wobble = 3.0 + 2.00 * sin(geep[l] * 0.4 * M_PI / 180.0) + 3.94261 * w1;
151 if(blades == 2) if (y > 3.000*x) y = x*3.000;
152 if(blades == 3) if (y > 1.732*x) y = x*1.732;
153 if(blades == 4) if (y > x) y = x;
154 if(blades == 5) if (y > 0.726*x) y = x*0.726;
155 if(blades == 6) if (y > 0.577*x) y = x*0.577;
156 if(blades == 7) if (y > 0.481*x) y = x*0.481;
157 if(blades == 8) if (y > 0.414*x) y = x*0.414;
159 if (y > x * bladeratio[blades])
160 y = x * bladeratio[blades];
162 for (b = 0; b < blades; b++) {
164 glTranslatef(pos[l * 3], pos[l * 3 + 1], pos[l * 3 + 2]);
165 glRotatef(ang[l] + b * (360.0 / blades), 0.0, 0.0, 1.0);
166 glScalef(wobble * sca[l], wobble * sca[l], wobble * sca[l]);
168 if(tko & 0x40000) glColor3f(col[l*3], col[l*3+1], col[l*3+2]);
171 glColor4ub(0, 0, 0, 0x60);
173 /* constrain geep cooridinates here XXX */
176 glBegin(GL_TRIANGLE_STRIP);
177 glVertex2f(x * sca[l], 0.0);
179 glVertex2f(x, -y); /* C */
180 glVertex2f(0.3, 0.0); /* D */
184 if(tko++ & 0x40000) glColor3f(0,0,0);
187 glColor3f(col[l * 3], col[l * 3 + 1], col[l * 3 + 2]);
188 glBegin(GL_LINE_LOOP);
189 glVertex2f(x * sca[l], 0.0);
191 glVertex2f(0.3, 0.0); /* D */
192 glVertex2f(x, -y); /* C */
203 if (pos[t * 3] < -sca[t] * wd && dir[t * 3] < 0.0) {
204 dir[t * 3] = -dir[t * 3];
206 acc[t*3+1] += 0.8*acc[t*3];
207 acc[t*3] = -0.8*acc[t*3];
209 } else if (pos[t * 3] > (1 + sca[t]) * wd && dir[t * 3] > 0.0) {
210 dir[t * 3] = -dir[t * 3];
212 acc[t*3+1] += 0.8*acc[t*3];
213 acc[t*3] = -0.8*acc[t*3];
215 } else if (pos[t * 3 + 1] < -sca[t] * ht && dir[t * 3 + 1] < 0.0) {
216 dir[t * 3 + 1] = -dir[t * 3 + 1];
218 acc[t*3] += 0.8*acc[t*3+1];
219 acc[t*3+1] = -0.8*acc[t*3+1];
221 } else if (pos[t * 3 + 1] > (1 + sca[t]) * ht && dir[t * 3 + 1] > 0.0) {
222 dir[t * 3 + 1] = -dir[t * 3 + 1];
224 acc[t*3] += 0.8*acc[t*3+1];
225 acc[t*3+1] = -0.8*acc[t*3+1];
229 pos[t * 3] += dir[t * 3];
230 pos[t * 3 + 1] += dir[t * 3 + 1];
232 dir[t*3] += acc[t*3];
233 dir[t*3+1] += acc[t*3+1];
237 if (geep[t] > 360 * 5.0)
238 geep[t] -= 360 * 5.0;
242 if (ang[t] > 360.0) {
250 if (hsv[i * 3 + 1] <= 0.5 && hpr[i * 3 + 1] < 0.0)
251 hpr[i * 3 + 1] = -hpr[i * 3 + 1]; /* adjust s */
252 if (hsv[i * 3 + 1] >= 1.0 && hpr[i * 3 + 1] > 0.0)
253 hpr[i * 3 + 1] = -hpr[i * 3 + 1]; /* adjust s */
254 if (hsv[i * 3 + 2] <= 0.4 && hpr[i * 3 + 2] < 0.0)
255 hpr[i * 3 + 2] = -hpr[i * 3 + 2]; /* adjust s */
256 if (hsv[i * 3 + 2] >= 1.0 && hpr[i * 3 + 2] > 0.0)
257 hpr[i * 3 + 2] = -hpr[i * 3 + 2]; /* adjust s */
259 hsv[i * 3] += hpr[i * 3];
260 hsv[i * 3 + 1] += hpr[i * 3 + 1];
261 hsv[i * 3 + 2] += hpr[i * 3 + 2];
263 /* --- hsv -> rgb --- */
264 #define H(hhh) hhh[i*3 ]
265 #define S(hhh) hhh[i*3+1]
266 #define V(hhh) hhh[i*3+2]
268 #define R(hhh) hhh[i*3 ]
269 #define G(hhh) hhh[i*3+1]
270 #define B(hhh) hhh[i*3+2]
281 float f, h, p, q, t, v;
286 while (H(hsv) >= 360.0)
298 p = V(hsv) * (1 - S(hsv));
299 q = V(hsv) * (1 - S(hsv) * f);
300 t = V(hsv) * (1 - S(hsv) * (1 - f));
306 } else if (hi == 1) {
310 } else if (hi == 2) {
314 } else if (hi == 3) {
318 } else if (hi == 4) {
335 for (a = 0; a < N_SHAPES; a++) {
336 for (b = 0; b < a; b++) {
339 t = pos[b * 3] - pos[a * 3];
341 t = pos[b * 3 + 1] - pos[a * 3 + 1];
348 v0 = pos[b * 3] - pos[a * 3];
349 v1 = pos[b * 3 + 1] - pos[a * 3 + 1];
351 z = 0.00000001 * fx / (d2);
353 dir[a * 3] += v0 * z * sca[b];
354 dir[b * 3] += -v0 * z * sca[a];
355 dir[a * 3 + 1] += v1 * z * sca[b];
356 dir[b * 3 + 1] += -v1 * z * sca[a];
361 if(dir[a*3]*dir[a*3] + dir[a*3+1]*dir[a*3+1]
371 draw_noof (ModeInfo *mi)
376 if((random() & 0xff) == 0x34){
377 glClear(GL_COLOR_BUFFER_BIT);
380 if((tko & 0x1f) == 0x1f){
382 glColor4f(0.0, 0.0, 0.0, 0.09);
383 glRectf(0.0, 0.0, wd, ht);
392 for (i = 0; i < N_SHAPES; i++) {
398 if (mi->fps_p) do_fps (mi);
401 glXSwapBuffers(MI_DISPLAY(mi), MI_WINDOW(mi));
406 reshape_noof(ModeInfo *mi, int w, int h)
408 glViewport(0, 0, w, h);
409 glMatrixMode(GL_PROJECTION);
413 ht = (GLfloat) h / (GLfloat) w;
415 0.0, 1.0 * (GLfloat) h / (GLfloat) w,
418 wd = (GLfloat) w / (GLfloat) h;
420 glOrtho(0.0, 1.0 * (GLfloat) w / (GLfloat) h,
424 glMatrixMode(GL_MODELVIEW);
427 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
431 init_noof (ModeInfo *mi)
434 noof_configuration *bp;
437 bps = (noof_configuration *)
438 calloc (MI_NUM_SCREENS(mi), sizeof (noof_configuration));
440 fprintf(stderr, "%s: out of memory\n", progname);
443 bp = &bps[MI_SCREEN(mi)];
446 bp = &bps[MI_SCREEN(mi)];
448 bp->glx_context = init_GL(mi);
450 glClearColor(0.0, 0.0, 0.0, 1.0);
451 glEnable(GL_LINE_SMOOTH);
452 glShadeModel(GL_FLAT);
453 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
454 for (i = 0; i < N_SHAPES; i++)
456 reshape_noof (mi, MI_WIDTH(mi), MI_HEIGHT(mi));