http://packetstormsecurity.org/UNIX/admin/xscreensaver-3.28.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 "config.h"
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <math.h>
18 #include <GL/gl.h>
19
20 #include "yarandom.h"
21 #include "stonerview-osc.h"
22 #include "stonerview-move.h"
23
24 /* The list of polygons. This is filled in by move_increment(), and rendered
25    by perform_render(). */
26 elem_t elist[NUM_ELS];
27
28 /* The polygons are controlled by four parameters. Each is represented by
29    an osc_t object, which is just something that returns a stream of numbers.
30    (Originally the name stood for "oscillator", but it does ever so much more
31    now... see osc.c.)
32    Imagine a cylinder with a vertical axis (along the Z axis), stretching from
33    Z=1 to Z=-1, and a radius of 1.
34 */
35 static osc_t *theta = NULL; /* Angle around the axis. This is expressed in
36    hundredths of a degree, so it's actually 0 to 36000. */
37 static osc_t *rad = NULL; /* Distance from the axis. This goes up to 1000,
38    but we actually allow negative distances -- that just goes to the opposite
39    side of the circle -- so the range is really -1000 to 1000. */
40 static osc_t *alti = NULL; /* Height (Z position). This goes from -1000 to 
41    1000. */
42 static osc_t *color = NULL; /* Consider this to be an angle of a circle going 
43    around the color wheel. It's in tenths of a degree (consistency is all I 
44    ask) so it ranges from 0 to 3600. */
45 /* static GLint prevtime = 0; / * for timing */
46
47 int init_move()
48 {
49   /*theta = new_osc_linear(
50     new_osc_wrap(0, 36000, 25),
51     new_osc_constant(2000));*/
52     
53   theta = new_osc_linear(
54     new_osc_velowrap(0, 36000, new_osc_multiplex(
55       new_osc_randphaser(300, 600),
56       new_osc_constant(25),
57       new_osc_constant(75),
58       new_osc_constant(50),
59       new_osc_constant(100))
60     ),
61         
62     new_osc_multiplex(
63       new_osc_buffer(new_osc_randphaser(300, 600)),
64       new_osc_buffer(new_osc_wrap(0, 36000, 10)),
65       new_osc_buffer(new_osc_wrap(0, 36000, -8)),
66       new_osc_wrap(0, 36000, 4),
67       new_osc_buffer(new_osc_bounce(-2000, 2000, 20))
68       )
69     );
70         
71   rad = new_osc_buffer(new_osc_multiplex(
72     new_osc_randphaser(250, 500),
73     new_osc_bounce(-1000, 1000, 10),
74     new_osc_bounce(  200, 1000, -15),
75     new_osc_bounce(  400, 1000, 10),
76     new_osc_bounce(-1000, 1000, -20)));
77   /*rad = new_osc_constant(1000);*/
78     
79   alti = new_osc_linear(
80     new_osc_constant(-1000),
81     new_osc_constant(2000 / NUM_ELS));
82
83   /*alti = new_osc_multiplex(
84     new_osc_buffer(new_osc_randphaser(60, 270)),
85     new_osc_buffer(new_osc_bounce(-1000, 1000, 48)),
86     new_osc_linear(
87       new_osc_constant(-1000),
88       new_osc_constant(2000 / NUM_ELS)),
89     new_osc_buffer(new_osc_bounce(-1000, 1000, 27)),
90       new_osc_linear(
91       new_osc_constant(-1000),
92       new_osc_constant(2000 / NUM_ELS))
93     );*/
94     
95   /*color = new_osc_buffer(new_osc_randphaser(5, 35));*/
96     
97   /*color = new_osc_buffer(new_osc_multiplex(
98     new_osc_randphaser(25, 70),
99     new_osc_wrap(0, 3600, 20),
100     new_osc_wrap(0, 3600, 30),
101     new_osc_wrap(0, 3600, -20),
102     new_osc_wrap(0, 3600, 10)));*/
103   color = new_osc_multiplex(
104     new_osc_buffer(new_osc_randphaser(150, 300)),
105     new_osc_buffer(new_osc_wrap(0, 3600, 13)),
106     new_osc_buffer(new_osc_wrap(0, 3600, 32)),
107     new_osc_buffer(new_osc_wrap(0, 3600, 17)),
108     new_osc_buffer(new_osc_wrap(0, 3600, 7)));
109
110   move_increment();
111
112   return 1;
113 }
114
115 void final_move()
116 {
117 }
118
119 /* Set up the list of polygon data for rendering. */
120 void move_increment()
121 {
122   int ix, val;
123 /*  GLfloat fval; */
124 /*  GLfloat recipels = (1.0 / (GLfloat)NUM_ELS); */
125   GLfloat pt[2];
126   GLfloat ptrad, pttheta;
127     
128   for (ix=0; ix<NUM_ELS; ix++) {
129     elem_t *el = &elist[ix];
130         
131     /* Grab r and theta... */
132     val = osc_get(theta, ix);
133     pttheta = val * (0.01 * M_PI / 180.0); 
134     ptrad = (GLfloat)osc_get(rad, ix) * 0.001;
135     /* And convert them to x,y coordinates. */
136     pt[0] = ptrad * cos(pttheta);
137     pt[1] = ptrad * sin(pttheta);
138         
139     /* Set x,y,z. */
140     el->pos[0] = pt[0];
141     el->pos[1] = pt[1];
142     el->pos[2] = (GLfloat)osc_get(alti, ix) * 0.001;
143         
144     /* Set which way the square is rotated. This is fixed for now, although
145        it would be trivial to make the squares spin as they revolve. */
146     el->vervec[0] = 0.11;
147     el->vervec[1] = 0.0;
148         
149     /* Grab the color, and convert it to RGB values. Technically, we're
150        converting an HSV value to RGB, where S and V are always 1. */
151     val = osc_get(color, ix);
152     if (val < 1200) {
153       el->col[0] = ((GLfloat)val / 1200.0);
154       el->col[1] = 0;
155       el->col[2] = (GLfloat)(1200 - val) / 1200.0;
156     } 
157     else if (val < 2400) {
158       el->col[0] = (GLfloat)(2400 - val) / 1200.0;
159       el->col[1] = ((GLfloat)(val - 1200) / 1200.0);
160       el->col[2] = 0;
161     }
162     else {
163       el->col[0] = 0;
164       el->col[1] = (GLfloat)(3600 - val) / 1200.0;
165       el->col[2] = ((GLfloat)(val - 2400) / 1200.0);
166     }
167     el->col[3] = 1.0;
168   }
169     
170   osc_increment();
171 }
172