http://ftp.ksu.edu.tw/FTP/FreeBSD/distfiles/xscreensaver-4.20.tar.gz
[xscreensaver] / hacks / glx / extrusion-taper.c
1 /* 
2  * taper.c
3  * 
4  * FUNCTION:
5  * Draws a tapered screw shape.
6  *
7  * HISTORY:
8  * -- created by Linas Vepstas October 1991
9  * -- heavily modified to draw more texas shapes, Feb 1993, Linas
10  * -- converted to use GLUT -- December 1995, Linas
11  *
12  */
13
14 /* required include files */
15 #ifdef HAVE_CONFIG_H
16 #include <config.h>
17 #endif
18
19 #include <math.h>
20 #include <stdlib.h>
21 #include <GL/gl.h>
22 /*#include <GL/glut.h>*/
23 #ifdef HAVE_GLE3
24 #include <GL/gle.h>
25 #else
26 #include <GL/tube.h>
27 #endif
28
29 #ifndef NULL
30 #define NULL ((void *) 0x0)
31 #endif /* NULL */
32
33 /* Some <math.h> files do not define M_PI... */
34 #ifndef M_PI
35 #define M_PI 3.14159265358979323846
36 #endif
37
38 /* =========================================================== */
39
40 #define SCALE 3.33333
41 #define CONTOUR(x,y) {                                  \
42    double ax, ay, alen;                                 \
43    contour[i][0] = SCALE * (x);                         \
44    contour[i][1] = SCALE * (y);                         \
45    if (i!=0) {                                          \
46       ax = contour[i][0] - contour[i-1][0];             \
47       ay = contour[i][1] - contour[i-1][1];             \
48       alen = 1.0 / sqrt (ax*ax + ay*ay);                \
49       ax *= alen;   ay *= alen;                         \
50       norms [i-1][0] = ay;                              \
51       norms [i-1][1] = -ax;                             \
52    }                                                    \
53    i++;                                                 \
54 }
55
56 #define NUM_PTS (25)
57
58 static double contour [NUM_PTS][2];
59 static double norms [NUM_PTS][2];
60
61 static void init_contour (void)
62 {
63    int i;
64
65    /* outline of extrusion */
66    i=0;
67    CONTOUR (1.0, 1.0);
68    CONTOUR (1.0, 2.9);
69    CONTOUR (0.9, 3.0);
70    CONTOUR (-0.9, 3.0);
71    CONTOUR (-1.0, 2.9);
72
73    CONTOUR (-1.0, 1.0);
74    CONTOUR (-2.9, 1.0);
75    CONTOUR (-3.0, 0.9);
76    CONTOUR (-3.0, -0.9);
77    CONTOUR (-2.9, -1.0);
78
79    CONTOUR (-1.0, -1.0);
80    CONTOUR (-1.0, -2.9);
81    CONTOUR (-0.9, -3.0);
82    CONTOUR (0.9, -3.0);
83    CONTOUR (1.0, -2.9);
84
85    CONTOUR (1.0, -1.0);
86    CONTOUR (2.9, -1.0);
87    CONTOUR (3.0, -0.9);
88    CONTOUR (3.0, 0.9);
89    CONTOUR (2.9, 1.0);
90
91    CONTOUR (1.0, 1.0);   /* repeat so that last normal is computed */
92 }
93    
94 /* =========================================================== */
95
96 #define PSIZE 40
97 static double path[PSIZE][3];
98 static double twist[PSIZE];
99 static double taper[PSIZE];
100
101 static void init_taper (void) {
102    int j;
103    double z, deltaz;
104    double ang, dang;
105
106    z = -10.0;
107    deltaz = 0.5;
108
109    ang = 0.0;
110    dang = 20.0;
111    for (j=0; j<40; j++) {
112       path[j][0] = 0x0;
113       path[j][1] = 0x0;
114       path[j][2] = z;
115
116       twist[j] = ang;
117       ang += dang;
118
119       taper[j] = 0.1 * sqrt (9.51*9.51 - z*z);
120
121       z += deltaz;
122    }
123
124    taper[0] = taper[1];
125    taper[39] = taper[38];
126
127 }
128
129 /* =========================================================== */
130
131 /* controls shape of object */
132 extern float lastx;
133 extern float lasty;
134
135 void InitStuff_taper (void)
136 {
137    int style;
138
139    /* configure the pipeline */
140    style = TUBE_JN_CAP;
141    style |= TUBE_CONTOUR_CLOSED;
142    style |= TUBE_NORM_FACET;
143    style |= TUBE_JN_ANGLE;
144    gleSetJoinStyle (style);
145
146    init_contour();
147    init_taper();
148 }
149
150 /* =========================================================== */
151
152 static void gleTaper (int ncp, 
153                gleDouble contour[][2], 
154                gleDouble cont_normal[][2], 
155                gleDouble up[3],
156                int npoints,
157                gleDouble point_array[][3],
158                float color_array[][3],
159                gleDouble taper[],
160                gleDouble twist[])
161 {
162    int j;
163    gleAffine *xforms;
164    double co, si, angle;
165
166    /* malloc the extrusion array and the twist array */
167    xforms = (gleAffine *) malloc (npoints * sizeof(gleAffine));
168
169    for (j=0; j<npoints; j++) {
170       angle = (M_PI/180.0) * twist[j];
171       si = sin (angle);
172       co = cos (angle);
173       xforms[j][0][0] = taper[j] * co;
174       xforms[j][0][1] = - taper[j] * si;
175       xforms[j][0][2] = 0.0;
176       xforms[j][1][0] = taper[j] * si;
177       xforms[j][1][1] = taper[j] * co;
178       xforms[j][1][2] = 0.0;
179    }
180
181    gleSuperExtrusion (ncp,               /* number of contour points */
182                 contour,    /* 2D contour */
183                 cont_normal, /* 2D contour normals */
184                 up,           /* up vector for contour */
185                 npoints,           /* numpoints in poly-line */
186                 point_array,        /* polyline */
187                 color_array,        /* color of polyline */
188                 xforms);
189
190    free (xforms);
191 }
192
193 /* =========================================================== */
194
195 void DrawStuff_taper (void) {
196    int j;
197    double ang, dang;
198    double z, deltaz;
199    double ponent;
200    z=-1.0;
201    deltaz = 1.999/38;
202    ang = 0.0;
203    dang = lasty/40.0;
204    ponent = fabs (lastx/540.0);
205    for (j=1; j<39; j++) {
206       twist[j] = ang;
207       ang += dang;
208
209       taper[j] = pow ((1.0 - pow (fabs(z), 1.0/ponent)), ponent);
210       z += deltaz;
211    }
212
213    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
214    glColor3f (0.5, 0.6, 0.6);
215
216    /* set up some matrices so that the object spins with the mouse */
217    glPushMatrix ();
218    /* glTranslatef (0.0, 0.0, -80.0); */
219    /* glRotatef (130.0, 0.0, 1.0, 0.0); */
220    /* glRotatef (65.0, 1.0, 0.0, 0.0); */
221
222    /* draw the brand and the handle */
223    gleTaper (20, contour, norms,  NULL, 40, path, NULL, taper, twist);
224
225    glPopMatrix ();
226 }
227
228 /* ===================== END OF FILE ================== */