From http://www.jwz.org/xscreensaver/xscreensaver-5.18.tar.gz
[xscreensaver] / hacks / glx / stonerview-move.c
1 /* StonerView: An eccentric visual toy.
2    Copyright 1998-2001 by Andrew Plotkin (erkyrath@eblong.com)
3
4    Permission to use, copy, modify, distribute, and sell this software and its
5    documentation for any purpose is hereby granted without fee, provided that
6    the above copyright notice appear in all copies and that both that
7    copyright notice and this permission notice appear in supporting
8    documentation.  No representations are made about the suitability of this
9    software for any purpose.  It is provided "as is" without express or 
10    implied warranty.
11 */
12
13 #include <math.h>
14
15 #ifdef HAVE_CONFIG_H
16 # include "config.h"
17 #endif
18
19 #include <stdio.h>
20 #include <stdlib.h>
21
22 #ifndef HAVE_COCOA
23 # include <GL/gl.h>
24 #endif
25
26 #ifdef HAVE_JWZGLES
27 # include "jwzgles.h"
28 #endif /* HAVE_JWZGLES */
29
30 #include "yarandom.h"
31 #include "stonerview.h"
32
33
34 void
35 stonerview_init_move(stonerview_state *st)
36 {
37   /*st->theta = new_osc_linear(
38     new_osc_wrap(0, 36000, 25),
39     new_osc_constant(2000));*/
40     
41   st->theta = new_osc_linear(st,
42     new_osc_velowrap(st, 0, 36000, new_osc_multiplex(st,
43       new_osc_randphaser(st, 300, 600),
44       new_osc_constant(st, 25),
45       new_osc_constant(st, 75),
46       new_osc_constant(st, 50),
47       new_osc_constant(st, 100))
48     ),
49         
50     new_osc_multiplex(st,
51       new_osc_buffer(st, new_osc_randphaser(st, 300, 600)),
52       new_osc_buffer(st, new_osc_wrap(st, 0, 36000, 10)),
53       new_osc_buffer(st, new_osc_wrap(st, 0, 36000, -8)),
54       new_osc_wrap(st, 0, 36000, 4),
55       new_osc_buffer(st, new_osc_bounce(st, -2000, 2000, 20))
56       )
57     );
58         
59   st->rad = new_osc_buffer(st, new_osc_multiplex(st,
60     new_osc_randphaser(st, 250, 500),
61     new_osc_bounce(st, -1000, 1000, 10),
62     new_osc_bounce(st,   200, 1000, -15),
63     new_osc_bounce(st,   400, 1000, 10),
64     new_osc_bounce(st, -1000, 1000, -20)));
65   /*st->rad = new_osc_constant(st, 1000);*/
66     
67   st->alti = new_osc_linear(st,
68     new_osc_constant(st, -1000),
69     new_osc_constant(st, 2000 / st->num_els));
70
71   /*st->alti = new_osc_multiplex(
72     new_osc_buffer(st, new_osc_randphaser(60, 270)),
73     new_osc_buffer(st, new_osc_bounce(-1000, 1000, 48)),
74     new_osc_linear(
75       new_osc_constant(-1000),
76       new_osc_constant(2000 / st->num_els)),
77     new_osc_buffer(st, new_osc_bounce(-1000, 1000, 27)),
78       new_osc_linear(
79       new_osc_constant(-1000),
80       new_osc_constant(2000 / st->num_els))
81     );*/
82     
83   /*st->color = new_osc_buffer(st, new_osc_randphaser(5, 35));*/
84     
85   /*st->color = new_osc_buffer(st, new_osc_multiplex(
86     new_osc_randphaser(25, 70),
87     new_osc_wrap(0, 3600, 20),
88     new_osc_wrap(0, 3600, 30),
89     new_osc_wrap(0, 3600, -20),
90     new_osc_wrap(0, 3600, 10)));*/
91   st->color = new_osc_multiplex(st,
92     new_osc_buffer(st, new_osc_randphaser(st, 150, 300)),
93     new_osc_buffer(st, new_osc_wrap(st, 0, 3600, 13)),
94     new_osc_buffer(st, new_osc_wrap(st, 0, 3600, 32)),
95     new_osc_buffer(st, new_osc_wrap(st, 0, 3600, 17)),
96     new_osc_buffer(st, new_osc_wrap(st, 0, 3600, 7)));
97
98   stonerview_move_increment(st);
99 }
100
101 /* Set up the list of polygon data for rendering. */
102 void
103 stonerview_move_increment(stonerview_state *st)
104 {
105   int ix, val;
106 /*  GLfloat fval; */
107 /*  GLfloat recipels = (1.0 / (GLfloat)st->num_els); */
108   GLfloat pt[2];
109   GLfloat ptrad, pttheta;
110     
111   for (ix=0; ix<st->num_els; ix++) {
112     stonerview_elem_t *el = &st->elist[ix];
113         
114     /* Grab r and theta... */
115     val = osc_get(st, st->theta, ix);
116     pttheta = val * (0.01 * M_PI / 180.0); 
117     ptrad = (GLfloat)osc_get(st, st->rad, ix) * 0.001;
118     /* And convert them to x,y coordinates. */
119     pt[0] = ptrad * cos(pttheta);
120     pt[1] = ptrad * sin(pttheta);
121         
122     /* Set x,y,z. */
123     el->pos[0] = pt[0];
124     el->pos[1] = pt[1];
125     el->pos[2] = (GLfloat)osc_get(st, st->alti, ix) * 0.001;
126         
127     /* Set which way the square is rotated. This is fixed for now, although
128        it would be trivial to make the squares spin as they revolve. */
129     el->vervec[0] = 0.11;
130     el->vervec[1] = 0.0;
131         
132     /* Grab the color, and convert it to RGB values. Technically, we're
133        converting an HSV value to RGB, where S and V are always 1. */
134     val = osc_get(st, st->color, ix);
135     if (val < 1200) {
136       el->col[0] = ((GLfloat)val / 1200.0);
137       el->col[1] = 0;
138       el->col[2] = (GLfloat)(1200 - val) / 1200.0;
139     } 
140     else if (val < 2400) {
141       el->col[0] = (GLfloat)(2400 - val) / 1200.0;
142       el->col[1] = ((GLfloat)(val - 1200) / 1200.0);
143       el->col[2] = 0;
144     }
145     else {
146       el->col[0] = 0;
147       el->col[1] = (GLfloat)(3600 - val) / 1200.0;
148       el->col[2] = ((GLfloat)(val - 2400) / 1200.0);
149     }
150     el->col[3] = 1.0;
151   }
152     
153   osc_increment(st);
154 }
155