http://packetstormsecurity.org/UNIX/admin/xscreensaver-4.03.tar.gz
[xscreensaver] / hacks / glx / morph3d.c
1 /* -*- Mode: C; tab-width: 4 -*- */
2 /* morph3d --- Shows 3D morphing objects */
3
4 #if !defined( lint ) && !defined( SABER )
5 static const char sccsid[] = "@(#)morph3d.c     5.01 2001/03/01 xlockmore";
6
7 #endif
8
9 #undef DEBUG_CULL_FACE
10
11 /*-
12  * Permission to use, copy, modify, and distribute this software and its
13  * documentation for any purpose and without fee is hereby granted,
14  * provided that the above copyright notice appear in all copies and that
15  * both that copyright notice and this permission notice appear in
16  * supporting documentation.
17  *
18  * This file is provided AS IS with no warranties of any kind.  The author
19  * shall have no liability with respect to the infringement of copyrights,
20  * trade secrets or any patents by this file or any part thereof.  In no
21  * event will the author be liable for any lost revenue or profits or
22  * other special, indirect and consequential damages.
23  *
24  * The original code for this mode was written by Marcelo Fernandes Vianna
25  * (me...) and was inspired on a WindowsNT(R)'s screen saver (Flower Box).
26  * It was written from scratch and it was not based on any other source code.
27  *
28  * Porting it to xlock (the final objective of this code since the moment I
29  * decided to create it) was possible by comparing the original Mesa's gear
30  * demo with it's ported version to xlock, so thanks for Danny Sung (look at
31  * gear.c) for his indirect help.
32  *
33  * Thanks goes also to Brian Paul for making it possible and inexpensive
34  * to use OpenGL at home.
35  *
36  * If you are interested in the original version of this program (not a xlock
37  * mode, please refer to the Mesa package (ftp iris.ssec.wisc.edu on /pub/Mesa)
38  *
39  * Since I'm not a native English speaker, my apologies for any grammatical
40  * mistakes.
41  *
42  * My e-mail address is
43  * mfvianna@centroin.com.br
44  *
45  * Marcelo F. Vianna (Feb-13-1997)
46  *
47  * Revision History:
48  * 05-Apr-2002: Removed all gllist uses (fix some bug with nvidia driver)
49  * 01-Mar-2001: Added FPS stuff E.Lassauge <lassauge@mail.dotcom.fr>
50  * 27-Jul-1997: Speed ups by Marcelo F. Vianna.
51  * 08-May-1997: Speed ups by Marcelo F. Vianna.
52  *
53  */
54
55 #ifdef VMS
56 /*-
57  * due to a Bug/feature in VMS X11/Intrinsic.h has to be placed before xlock.
58  * otherwise caddr_t is not defined correctly
59  */
60
61 #include <X11/Intrinsic.h>
62 #endif
63
64 #ifdef STANDALONE
65 # define MODE_moebius
66 # define PROGCLASS              "Morph3d"
67 # define HACK_INIT              init_morph3d
68 # define HACK_DRAW              draw_morph3d
69 # define HACK_RESHAPE   reshape
70 # define morph3d_opts   xlockmore_opts
71 # define DEFAULTS               "*delay:                40000   \n"             \
72                                                 "*showFPS:      False   \n"             \
73                                                 "*count:                0               \n"
74 # include "xlockmore.h"         /* from the xscreensaver distribution */
75 #else /* !STANDALONE */
76 # include "xlock.h"             /* from the xlockmore distribution */
77 #endif /* !STANDALONE */
78
79 #ifdef MODE_moebius
80
81 ModeSpecOpt morph3d_opts =
82 {0, (XrmOptionDescRec *) NULL, 0, (argtype *) NULL, (OptionStruct *) NULL};
83
84 #ifdef USE_MODULES
85 ModStruct   morph3d_description =
86 {"morph3d", "init_morph3d", "draw_morph3d", "release_morph3d",
87  "draw_morph3d", "change_morph3d", (char *) NULL, &morph3d_opts,
88  1000, 0, 1, 1, 4, 1.0, "",
89  "Shows GL morphing polyhedra", 0, NULL};
90
91 #endif
92
93 #define Scale4Window               0.3
94 #define Scale4Iconic               1.0
95
96 #define VectMul(X1,Y1,Z1,X2,Y2,Z2) (Y1)*(Z2)-(Z1)*(Y2),(Z1)*(X2)-(X1)*(Z2),(X1)*(Y2)-(Y1)*(X2)
97 #define sqr(A)                     ((A)*(A))
98
99 /* Increasing this values produces better image quality, the price is speed. */
100 #define tetradivisions             23
101 #define cubedivisions              20
102 #define octadivisions              21
103 #define dodecadivisions            10
104 #define icodivisions               15
105
106 #define tetraangle                 109.47122063449069174
107 #define cubeangle                  90.000000000000000000
108 #define octaangle                  109.47122063449069174
109 #define dodecaangle                63.434948822922009981
110 #define icoangle                   41.810314895778596167
111
112 #ifndef Pi
113 #define Pi                         M_PI
114 #endif
115 #define SQRT2                      1.4142135623730951455
116 #define SQRT3                      1.7320508075688771932
117 #define SQRT5                      2.2360679774997898051
118 #define SQRT6                      2.4494897427831778813
119 #define SQRT15                     3.8729833462074170214
120 #define cossec36_2                 0.8506508083520399322
121 #define cos72                      0.3090169943749474241
122 #define sin72                      0.9510565162951535721
123 #define cos36                      0.8090169943749474241
124 #define sin36                      0.5877852522924731292
125
126 /*************************************************************************/
127
128 typedef struct {
129         GLint       WindH, WindW;
130         GLfloat     step;
131         GLfloat     seno;
132         int         object;
133         int         edgedivisions;
134         int         VisibleSpikes;
135         void        (*draw_object) (ModeInfo * mi);
136         float       Magnitude;
137         float      *MaterialColor[20];
138         GLXContext *glx_context;
139 } morph3dstruct;
140
141 static float front_shininess[] =
142 {60.0};
143 static float front_specular[] =
144 {0.7, 0.7, 0.7, 1.0};
145 static float ambient[] =
146 {0.0, 0.0, 0.0, 1.0};
147 static float diffuse[] =
148 {1.0, 1.0, 1.0, 1.0};
149 static float position0[] =
150 {1.0, 1.0, 1.0, 0.0};
151 static float position1[] =
152 {-1.0, -1.0, 1.0, 0.0};
153 static float lmodel_ambient[] =
154 {0.5, 0.5, 0.5, 1.0};
155 static float lmodel_twoside[] =
156 {GL_TRUE};
157
158 static float MaterialRed[] =
159 {0.7, 0.0, 0.0, 1.0};
160 static float MaterialGreen[] =
161 {0.1, 0.5, 0.2, 1.0};
162 static float MaterialBlue[] =
163 {0.0, 0.0, 0.7, 1.0};
164 static float MaterialCyan[] =
165 {0.2, 0.5, 0.7, 1.0};
166 static float MaterialYellow[] =
167 {0.7, 0.7, 0.0, 1.0};
168 static float MaterialMagenta[] =
169 {0.6, 0.2, 0.5, 1.0};
170 static float MaterialWhite[] =
171 {0.7, 0.7, 0.7, 1.0};
172 static float MaterialGray[] =
173 {0.5, 0.5, 0.5, 1.0};
174
175 static morph3dstruct *morph3d = (morph3dstruct *) NULL;
176
177 #define TRIANGLE(Edge, Amp, Divisions, Z, VS)                                                                    \
178 {                                                                                                                \
179   GLfloat   Xf,Yf,Xa,Yb=0.0,Xf2=0.0,Yf2=0.0,Yf_2=0.0,Yb2,Yb_2;                                                   \
180   GLfloat   Factor=0.0,Factor1,Factor2;                                                                          \
181   GLfloat   VertX,VertY,VertZ,NeiAX,NeiAY,NeiAZ,NeiBX,NeiBY,NeiBZ;                                               \
182   GLfloat   Ax,Ay;                                                                                               \
183   int       Ri,Ti;                                                                                               \
184   GLfloat   Vr=(Edge)*SQRT3/3;                                                                                   \
185   GLfloat   AmpVr2=(Amp)/sqr(Vr);                                                                                \
186   GLfloat   Zf=(Edge)*(Z);                                                                                       \
187                                                                                                                  \
188   Ax=(Edge)*(+0.5/(Divisions)), Ay=(Edge)*(-SQRT3/(2*Divisions));                                                \
189                                                                                                                  \
190   Yf=Vr+Ay; Yb=Yf+0.001;                                                                                         \
191   for (Ri=1; Ri<=(Divisions); Ri++) {                                                                            \
192     glBegin(GL_TRIANGLE_STRIP);                                                                                  \
193     Xf=(float)Ri*Ax; Xa=Xf+0.001;                                                                                \
194     Yf2=sqr(Yf); Yf_2=sqr(Yf-Ay);                                                                                \
195     Yb2=sqr(Yb); Yb_2=sqr(Yb-Ay);                                                                                \
196     for (Ti=0; Ti<Ri; Ti++) {                                                                                    \
197       Factor=1-(((Xf2=sqr(Xf))+Yf2)*AmpVr2);                                                                     \
198       Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                          \
199       Factor2=1-((Xf2+Yb2)*AmpVr2);                                                                              \
200       VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                           \
201       NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                    \
202       NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                    \
203       glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                             \
204       glVertex3f(VertX, VertY, VertZ);                                                                           \
205                                                                                                                  \
206       Xf-=Ax; Yf-=Ay; Xa-=Ax; Yb-=Ay;                                                                            \
207                                                                                                                  \
208       Factor=1-(((Xf2=sqr(Xf))+Yf_2)*AmpVr2);                                                                    \
209       Factor1=1-((sqr(Xa)+Yf_2)*AmpVr2);                                                                         \
210       Factor2=1-((Xf2+Yb_2)*AmpVr2);                                                                             \
211       VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                           \
212       NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                    \
213       NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                    \
214       glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                             \
215       glVertex3f(VertX, VertY, VertZ);                                                                           \
216                                                                                                                  \
217       Xf-=Ax; Yf+=Ay; Xa-=Ax; Yb+=Ay;                                                                            \
218     }                                                                                                            \
219     Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2);                                                             \
220     Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                            \
221     Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                            \
222     VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                             \
223     NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                      \
224     NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                      \
225     glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                               \
226     glVertex3f(VertX, VertY, VertZ);                                                                             \
227     Yf+=Ay; Yb+=Ay;                                                                                              \
228     glEnd();                                                                                                     \
229   }                                                                                                              \
230   VS=(Factor<0);                                                                                                 \
231 }
232
233 #define SQUARE(Edge, Amp, Divisions, Z, VS)                                                                      \
234 {                                                                                                                \
235   int       Xi,Yi;                                                                                               \
236   GLfloat   Xf,Yf,Y,Xf2,Yf2,Y2,Xa,Xa2,Yb;                                                                        \
237   GLfloat   Factor=0.0,Factor1,Factor2;                                                                          \
238   GLfloat   VertX,VertY,VertZ,NeiAX,NeiAY,NeiAZ,NeiBX,NeiBY,NeiBZ;                                               \
239   GLfloat   Zf=(Edge)*(Z);                                                                                       \
240   GLfloat   AmpVr2=(Amp)/sqr((Edge)*SQRT2/2);                                                                    \
241                                                                                                                  \
242   for (Yi=0; Yi<(Divisions); Yi++) {                                                                             \
243     Yf=-((Edge)/2.0) + ((float)Yi)/(Divisions)*(Edge);                                                           \
244     Yf2=sqr(Yf);                                                                                                 \
245     Y=Yf+1.0/(Divisions)*(Edge);                                                                                 \
246     Y2=sqr(Y);                                                                                                   \
247     glBegin(GL_QUAD_STRIP);                                                                                      \
248     for (Xi=0; Xi<=(Divisions); Xi++) {                                                                          \
249       Xf=-((Edge)/2.0) + ((float)Xi)/(Divisions)*(Edge);                                                         \
250       Xf2=sqr(Xf);                                                                                               \
251                                                                                                                  \
252       Xa=Xf+0.001; Yb=Y+0.001;                                                                                   \
253       Factor=1-((Xf2+Y2)*AmpVr2);                                                                                \
254       Factor1=1-(((Xa2=sqr(Xa))+Y2)*AmpVr2);                                                                     \
255       Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                          \
256       VertX=Factor*Xf;        VertY=Factor*Y;         VertZ=Factor*Zf;                                           \
257       NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Y-VertY;  NeiAZ=Factor1*Zf-VertZ;                                    \
258       NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                    \
259       glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                             \
260       glVertex3f(VertX, VertY, VertZ);                                                                           \
261                                                                                                                  \
262       Yb=Yf+0.001;                                                                                               \
263       Factor=1-((Xf2+Yf2)*AmpVr2);                                                                               \
264       Factor1=1-((Xa2+Yf2)*AmpVr2);                                                                              \
265       Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                          \
266       VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                           \
267       NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                    \
268       NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                    \
269       glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                             \
270       glVertex3f(VertX, VertY, VertZ);                                                                           \
271     }                                                                                                            \
272     glEnd();                                                                                                     \
273   }                                                                                                              \
274   VS=(Factor<0);                                                                                                 \
275 }
276
277 #define PENTAGON(Edge, Amp, Divisions, Z, VS)                                                                    \
278 {                                                                                                                \
279   int       Ri,Ti,Fi;                                                                                            \
280   GLfloat   Xf,Yf,Xa,Yb,Xf2,Yf2;                                                                                 \
281   GLfloat   Factor=0.0,Factor1,Factor2;                                                                          \
282   GLfloat   VertX,VertY,VertZ,NeiAX,NeiAY,NeiAZ,NeiBX,NeiBY,NeiBZ;                                               \
283   GLfloat   Zf=(Edge)*(Z);                                                                                       \
284   GLfloat   AmpVr2=(Amp)/sqr((Edge)*cossec36_2);                                                                 \
285                                                                                                                  \
286   static    GLfloat x[6],y[6];                                                                                   \
287   static    int arrayninit=1;                                                                                    \
288                                                                                                                  \
289   if (arrayninit) {                                                                                              \
290     for(Fi=0;Fi<6;Fi++) {                                                                                        \
291       x[Fi]=-cos( Fi*2*Pi/5 + Pi/10 )/(Divisions)*cossec36_2*(Edge);                                             \
292       y[Fi]=sin( Fi*2*Pi/5 + Pi/10 )/(Divisions)*cossec36_2*(Edge);                                              \
293     }                                                                                                            \
294     arrayninit=0;                                                                                                \
295   }                                                                                                              \
296                                                                                                                  \
297   for (Ri=1; Ri<=(Divisions); Ri++) {                                                                            \
298     for (Fi=0; Fi<5; Fi++) {                                                                                     \
299       glBegin(GL_TRIANGLE_STRIP);                                                                                \
300       for (Ti=0; Ti<Ri; Ti++) {                                                                                  \
301         Xf=(float)(Ri-Ti)*x[Fi] + (float)Ti*x[Fi+1];                                                             \
302         Yf=(float)(Ri-Ti)*y[Fi] + (float)Ti*y[Fi+1];                                                             \
303         Xa=Xf+0.001; Yb=Yf+0.001;                                                                                \
304         Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2);                                                         \
305         Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                        \
306         Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                        \
307         VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                         \
308         NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                  \
309         NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                  \
310         glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                           \
311         glVertex3f(VertX, VertY, VertZ);                                                                         \
312                                                                                                                  \
313         Xf-=x[Fi]; Yf-=y[Fi]; Xa-=x[Fi]; Yb-=y[Fi];                                                              \
314                                                                                                                  \
315         Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2);                                                         \
316         Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                        \
317         Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                        \
318         VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                         \
319         NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                  \
320         NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                  \
321         glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                           \
322         glVertex3f(VertX, VertY, VertZ);                                                                         \
323                                                                                                                  \
324       }                                                                                                          \
325       Xf=(float)Ri*x[Fi+1];                                                                                      \
326       Yf=(float)Ri*y[Fi+1];                                                                                      \
327       Xa=Xf+0.001; Yb=Yf+0.001;                                                                                  \
328       Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2);                                                           \
329       Factor1=1-((sqr(Xa)+Yf2)*AmpVr2);                                                                          \
330       Factor2=1-((Xf2+sqr(Yb))*AmpVr2);                                                                          \
331       VertX=Factor*Xf;        VertY=Factor*Yf;        VertZ=Factor*Zf;                                           \
332       NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ;                                    \
333       NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ;                                    \
334       glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ));                                             \
335       glVertex3f(VertX, VertY, VertZ);                                                                           \
336       glEnd();                                                                                                   \
337     }                                                                                                            \
338   }                                                                                                              \
339   VS=(Factor<0);                                                                                             \
340 }
341
342 static void
343 draw_tetra(ModeInfo * mi)
344 {
345         morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
346
347         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[0]);
348
349         TRIANGLE(2, mp->seno, mp->edgedivisions, 0.5 / SQRT6, mp->VisibleSpikes);
350
351         glPushMatrix();
352         glRotatef(180, 0, 0, 1);
353         glRotatef(-tetraangle, 1, 0, 0);
354         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[1]);
355         TRIANGLE(2, mp->seno, mp->edgedivisions, 0.5 / SQRT6, mp->VisibleSpikes);
356         glPopMatrix();
357         glPushMatrix();
358         glRotatef(180, 0, 1, 0);
359         glRotatef(-180 + tetraangle, 0.5, SQRT3 / 2, 0);
360         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[2]);
361         TRIANGLE(2, mp->seno, mp->edgedivisions, 0.5 / SQRT6, mp->VisibleSpikes);
362         glPopMatrix();
363         glRotatef(180, 0, 1, 0);
364         glRotatef(-180 + tetraangle, 0.5, -SQRT3 / 2, 0);
365         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[3]);
366         TRIANGLE(2, mp->seno, mp->edgedivisions, 0.5 / SQRT6, mp->VisibleSpikes);
367 }
368
369 static void
370 draw_cube(ModeInfo * mi)
371 {
372         morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
373
374         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[0]);
375
376         SQUARE(2, mp->seno, mp->edgedivisions, 0.5, mp->VisibleSpikes)
377
378         glRotatef(cubeangle, 1, 0, 0);
379         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[1]);
380         SQUARE(2, mp->seno, mp->edgedivisions, 0.5, mp->VisibleSpikes)
381         glRotatef(cubeangle, 1, 0, 0);
382         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[2]);
383         SQUARE(2, mp->seno, mp->edgedivisions, 0.5, mp->VisibleSpikes)
384         glRotatef(cubeangle, 1, 0, 0);
385         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[3]);
386         SQUARE(2, mp->seno, mp->edgedivisions, 0.5, mp->VisibleSpikes)
387         glRotatef(cubeangle, 0, 1, 0);
388         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[4]);
389         SQUARE(2, mp->seno, mp->edgedivisions, 0.5, mp->VisibleSpikes)
390         glRotatef(2 * cubeangle, 0, 1, 0);
391         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[5]);
392         SQUARE(2, mp->seno, mp->edgedivisions, 0.5, mp->VisibleSpikes)
393 }
394
395 static void
396 draw_octa(ModeInfo * mi)
397 {
398         morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
399
400         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[0]);
401         TRIANGLE(2, mp->seno, mp->edgedivisions, 1 / SQRT6, mp->VisibleSpikes);
402
403         glPushMatrix();
404         glRotatef(180, 0, 0, 1);
405         glRotatef(-180 + octaangle, 1, 0, 0);
406         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[1]);
407         TRIANGLE(2, mp->seno, mp->edgedivisions, 1 / SQRT6, mp->VisibleSpikes);
408         glPopMatrix();
409         glPushMatrix();
410         glRotatef(180, 0, 1, 0);
411         glRotatef(-octaangle, 0.5, SQRT3 / 2, 0);
412         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[2]);
413         TRIANGLE(2, mp->seno, mp->edgedivisions, 1 / SQRT6, mp->VisibleSpikes);
414         glPopMatrix();
415         glPushMatrix();
416         glRotatef(180, 0, 1, 0);
417         glRotatef(-octaangle, 0.5, -SQRT3 / 2, 0);
418         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[3]);
419         TRIANGLE(2, mp->seno, mp->edgedivisions, 1 / SQRT6, mp->VisibleSpikes);
420         glPopMatrix();
421         glRotatef(180, 1, 0, 0);
422         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[4]);
423         TRIANGLE(2, mp->seno, mp->edgedivisions, 1 / SQRT6, mp->VisibleSpikes);
424         glPushMatrix();
425         glRotatef(180, 0, 0, 1);
426         glRotatef(-180 + octaangle, 1, 0, 0);
427         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[5]);
428         TRIANGLE(2, mp->seno, mp->edgedivisions, 1 / SQRT6, mp->VisibleSpikes);
429         glPopMatrix();
430         glPushMatrix();
431         glRotatef(180, 0, 1, 0);
432         glRotatef(-octaangle, 0.5, SQRT3 / 2, 0);
433         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[6]);
434         TRIANGLE(2, mp->seno, mp->edgedivisions, 1 / SQRT6, mp->VisibleSpikes);
435         glPopMatrix();
436         glRotatef(180, 0, 1, 0);
437         glRotatef(-octaangle, 0.5, -SQRT3 / 2, 0);
438         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[7]);
439         TRIANGLE(2, mp->seno, mp->edgedivisions, 1 / SQRT6, mp->VisibleSpikes);
440 }
441
442 static void
443 draw_dodeca(ModeInfo * mi)
444 {
445         morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
446
447 #define TAU ((SQRT5+1)/2)
448
449         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[0]);
450
451         PENTAGON(1, mp->seno, mp->edgedivisions, sqr(TAU) * sqrt((TAU + 2) / 5) / 2, mp->VisibleSpikes);
452
453         glPushMatrix();
454         glRotatef(180, 0, 0, 1);
455         glPushMatrix();
456         glRotatef(-dodecaangle, 1, 0, 0);
457         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[1]);
458         PENTAGON(1, mp->seno, mp->edgedivisions, sqr(TAU) * sqrt((TAU + 2) / 5) / 2, mp->VisibleSpikes);
459         glPopMatrix();
460         glPushMatrix();
461         glRotatef(-dodecaangle, cos72, sin72, 0);
462         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[2]);
463         PENTAGON(1, mp->seno, mp->edgedivisions, sqr(TAU) * sqrt((TAU + 2) / 5) / 2, mp->VisibleSpikes);
464         glPopMatrix();
465         glPushMatrix();
466         glRotatef(-dodecaangle, cos72, -sin72, 0);
467         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[3]);
468         PENTAGON(1, mp->seno, mp->edgedivisions, sqr(TAU) * sqrt((TAU + 2) / 5) / 2, mp->VisibleSpikes);
469         glPopMatrix();
470         glPushMatrix();
471         glRotatef(dodecaangle, cos36, -sin36, 0);
472         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[4]);
473         PENTAGON(1, mp->seno, mp->edgedivisions, sqr(TAU) * sqrt((TAU + 2) / 5) / 2, mp->VisibleSpikes);
474         glPopMatrix();
475         glRotatef(dodecaangle, cos36, sin36, 0);
476         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[5]);
477         PENTAGON(1, mp->seno, mp->edgedivisions, sqr(TAU) * sqrt((TAU + 2) / 5) / 2, mp->VisibleSpikes);
478         glPopMatrix();
479         glRotatef(180, 1, 0, 0);
480         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[6]);
481         PENTAGON(1, mp->seno, mp->edgedivisions, sqr(TAU) * sqrt((TAU + 2) / 5) / 2, mp->VisibleSpikes);
482         glRotatef(180, 0, 0, 1);
483         glPushMatrix();
484         glRotatef(-dodecaangle, 1, 0, 0);
485         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[7]);
486         PENTAGON(1, mp->seno, mp->edgedivisions, sqr(TAU) * sqrt((TAU + 2) / 5) / 2, mp->VisibleSpikes);
487         glPopMatrix();
488         glPushMatrix();
489         glRotatef(-dodecaangle, cos72, sin72, 0);
490         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[8]);
491         PENTAGON(1, mp->seno, mp->edgedivisions, sqr(TAU) * sqrt((TAU + 2) / 5) / 2, mp->VisibleSpikes);
492         glPopMatrix();
493         glPushMatrix();
494         glRotatef(-dodecaangle, cos72, -sin72, 0);
495         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[9]);
496         PENTAGON(1, mp->seno, mp->edgedivisions, sqr(TAU) * sqrt((TAU + 2) / 5) / 2, mp->VisibleSpikes);
497         glPopMatrix();
498         glPushMatrix();
499         glRotatef(dodecaangle, cos36, -sin36, 0);
500         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[10]);
501         PENTAGON(1, mp->seno, mp->edgedivisions, sqr(TAU) * sqrt((TAU + 2) / 5) / 2, mp->VisibleSpikes);
502         glPopMatrix();
503         glRotatef(dodecaangle, cos36, sin36, 0);
504         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[11]);
505         PENTAGON(1, mp->seno, mp->edgedivisions, sqr(TAU) * sqrt((TAU + 2) / 5) / 2, mp->VisibleSpikes);
506 }
507
508 static void
509 draw_icosa(ModeInfo * mi)
510 {
511         morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
512
513         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[0]);
514
515         TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes);
516
517         glPushMatrix();
518
519         glPushMatrix();
520         glRotatef(180, 0, 0, 1);
521         glRotatef(-icoangle, 1, 0, 0);
522         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[1]);
523         TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes);
524         glPushMatrix();
525         glRotatef(180, 0, 1, 0);
526         glRotatef(-180 + icoangle, 0.5, SQRT3 / 2, 0);
527         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[2]);
528         TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes);
529         glPopMatrix();
530         glRotatef(180, 0, 1, 0);
531         glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0);
532         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[3]);
533         TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes);
534         glPopMatrix();
535         glPushMatrix();
536         glRotatef(180, 0, 1, 0);
537         glRotatef(-180 + icoangle, 0.5, SQRT3 / 2, 0);
538         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[4]);
539         TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes);
540         glPushMatrix();
541         glRotatef(180, 0, 1, 0);
542         glRotatef(-180 + icoangle, 0.5, SQRT3 / 2, 0);
543         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[5]);
544         TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes);
545         glPopMatrix();
546         glRotatef(180, 0, 0, 1);
547         glRotatef(-icoangle, 1, 0, 0);
548         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[6]);
549         TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes);
550         glPopMatrix();
551         glRotatef(180, 0, 1, 0);
552         glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0);
553         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[7]);
554         TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes);
555         glPushMatrix();
556         glRotatef(180, 0, 1, 0);
557         glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0);
558         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[8]);
559         TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes);
560         glPopMatrix();
561         glRotatef(180, 0, 0, 1);
562         glRotatef(-icoangle, 1, 0, 0);
563         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[9]);
564         TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes);
565         glPopMatrix();
566         glRotatef(180, 1, 0, 0);
567         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[10]);
568         TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes);
569         glPushMatrix();
570         glRotatef(180, 0, 0, 1);
571         glRotatef(-icoangle, 1, 0, 0);
572         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[11]);
573         TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes);
574         glPushMatrix();
575         glRotatef(180, 0, 1, 0);
576         glRotatef(-180 + icoangle, 0.5, SQRT3 / 2, 0);
577         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[12]);
578         TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes);
579         glPopMatrix();
580         glRotatef(180, 0, 1, 0);
581         glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0);
582         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[13]);
583         TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes);
584         glPopMatrix();
585         glPushMatrix();
586         glRotatef(180, 0, 1, 0);
587         glRotatef(-180 + icoangle, 0.5, SQRT3 / 2, 0);
588         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[14]);
589         TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes);
590         glPushMatrix();
591         glRotatef(180, 0, 1, 0);
592         glRotatef(-180 + icoangle, 0.5, SQRT3 / 2, 0);
593         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[15]);
594         TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes);
595         glPopMatrix();
596         glRotatef(180, 0, 0, 1);
597         glRotatef(-icoangle, 1, 0, 0);
598         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[16]);
599         TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes);
600         glPopMatrix();
601         glRotatef(180, 0, 1, 0);
602         glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0);
603         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[17]);
604         TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes);
605         glPushMatrix();
606         glRotatef(180, 0, 1, 0);
607         glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0);
608         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[18]);
609         TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes);
610         glPopMatrix();
611         glRotatef(180, 0, 0, 1);
612         glRotatef(-icoangle, 1, 0, 0);
613         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[19]);
614         TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes);
615 }
616
617 void
618 reshape(ModeInfo * mi, int width, int height)
619 {
620         morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
621
622         glViewport(0, 0, mp->WindW = (GLint) width, mp->WindH = (GLint) height);
623         glMatrixMode(GL_PROJECTION);
624         glLoadIdentity();
625         glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 15.0);
626         glMatrixMode(GL_MODELVIEW);
627 }
628
629 static void
630 pinit(ModeInfo * mi)
631 {
632         morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
633
634         glClearDepth(1.0);
635         glClearColor(0.0, 0.0, 0.0, 1.0);
636         glColor3f(1.0, 1.0, 1.0);
637
638         glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
639         glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
640         glLightfv(GL_LIGHT0, GL_POSITION, position0);
641         glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
642         glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
643         glLightfv(GL_LIGHT1, GL_POSITION, position1);
644         glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
645         glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
646         glEnable(GL_LIGHTING);
647         glEnable(GL_LIGHT0);
648         glEnable(GL_LIGHT1);
649         glEnable(GL_DEPTH_TEST);
650         glEnable(GL_NORMALIZE);
651
652         glShadeModel(GL_SMOOTH);
653         glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_shininess);
654         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular);
655
656         switch (mp->object) {
657                 case 2:
658                         mp->draw_object = draw_cube;
659                         mp->MaterialColor[0] = MaterialRed;
660                         mp->MaterialColor[1] = MaterialGreen;
661                         mp->MaterialColor[2] = MaterialCyan;
662                         mp->MaterialColor[3] = MaterialMagenta;
663                         mp->MaterialColor[4] = MaterialYellow;
664                         mp->MaterialColor[5] = MaterialBlue;
665                         mp->edgedivisions = cubedivisions;
666                         mp->Magnitude = 2.0;
667                         break;
668                 case 3:
669                         mp->draw_object = draw_octa;
670                         mp->MaterialColor[0] = MaterialRed;
671                         mp->MaterialColor[1] = MaterialGreen;
672                         mp->MaterialColor[2] = MaterialBlue;
673                         mp->MaterialColor[3] = MaterialWhite;
674                         mp->MaterialColor[4] = MaterialCyan;
675                         mp->MaterialColor[5] = MaterialMagenta;
676                         mp->MaterialColor[6] = MaterialGray;
677                         mp->MaterialColor[7] = MaterialYellow;
678                         mp->edgedivisions = octadivisions;
679                         mp->Magnitude = 2.5;
680                         break;
681                 case 4:
682                         mp->draw_object = draw_dodeca;
683                         mp->MaterialColor[0] = MaterialRed;
684                         mp->MaterialColor[1] = MaterialGreen;
685                         mp->MaterialColor[2] = MaterialCyan;
686                         mp->MaterialColor[3] = MaterialBlue;
687                         mp->MaterialColor[4] = MaterialMagenta;
688                         mp->MaterialColor[5] = MaterialYellow;
689                         mp->MaterialColor[6] = MaterialGreen;
690                         mp->MaterialColor[7] = MaterialCyan;
691                         mp->MaterialColor[8] = MaterialRed;
692                         mp->MaterialColor[9] = MaterialMagenta;
693                         mp->MaterialColor[10] = MaterialBlue;
694                         mp->MaterialColor[11] = MaterialYellow;
695                         mp->edgedivisions = dodecadivisions;
696                         mp->Magnitude = 2.0;
697                         break;
698                 case 5:
699                         mp->draw_object = draw_icosa;
700                         mp->MaterialColor[0] = MaterialRed;
701                         mp->MaterialColor[1] = MaterialGreen;
702                         mp->MaterialColor[2] = MaterialBlue;
703                         mp->MaterialColor[3] = MaterialCyan;
704                         mp->MaterialColor[4] = MaterialYellow;
705                         mp->MaterialColor[5] = MaterialMagenta;
706                         mp->MaterialColor[6] = MaterialRed;
707                         mp->MaterialColor[7] = MaterialGreen;
708                         mp->MaterialColor[8] = MaterialBlue;
709                         mp->MaterialColor[9] = MaterialWhite;
710                         mp->MaterialColor[10] = MaterialCyan;
711                         mp->MaterialColor[11] = MaterialYellow;
712                         mp->MaterialColor[12] = MaterialMagenta;
713                         mp->MaterialColor[13] = MaterialRed;
714                         mp->MaterialColor[14] = MaterialGreen;
715                         mp->MaterialColor[15] = MaterialBlue;
716                         mp->MaterialColor[16] = MaterialCyan;
717                         mp->MaterialColor[17] = MaterialYellow;
718                         mp->MaterialColor[18] = MaterialMagenta;
719                         mp->MaterialColor[19] = MaterialGray;
720                         mp->edgedivisions = icodivisions;
721                         mp->Magnitude = 2.5;
722                         break;
723                 default:
724                         mp->draw_object = draw_tetra;
725                         mp->MaterialColor[0] = MaterialRed;
726                         mp->MaterialColor[1] = MaterialGreen;
727                         mp->MaterialColor[2] = MaterialBlue;
728                         mp->MaterialColor[3] = MaterialWhite;
729                         mp->edgedivisions = tetradivisions;
730                         mp->Magnitude = 2.5;
731                         break;
732         }
733         if (MI_IS_MONO(mi)) {
734                 int         loop;
735
736                 for (loop = 0; loop < 20; loop++)
737                         mp->MaterialColor[loop] = MaterialGray;
738         }
739 }
740
741 void
742 init_morph3d(ModeInfo * mi)
743 {
744         morph3dstruct *mp;
745
746         if (morph3d == NULL) {
747                 if ((morph3d = (morph3dstruct *) calloc(MI_NUM_SCREENS(mi),
748                                             sizeof (morph3dstruct))) == NULL)
749                         return;
750         }
751         mp = &morph3d[MI_SCREEN(mi)];
752         mp->step = NRAND(90);
753         mp->VisibleSpikes = 1;
754
755         if ((mp->glx_context = init_GL(mi)) != NULL) {
756
757                 reshape(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
758                 glDrawBuffer(GL_BACK);
759                 mp->object = MI_COUNT(mi);
760                 if (mp->object <= 0 || mp->object > 5)
761                         mp->object = NRAND(5) + 1;
762                 pinit(mi);
763         } else {
764                 MI_CLEARWINDOW(mi);
765         }
766 }
767
768 void
769 draw_morph3d(ModeInfo * mi)
770 {
771         Display    *display = MI_DISPLAY(mi);
772         Window      window = MI_WINDOW(mi);
773         morph3dstruct *mp;
774
775         if (morph3d == NULL)
776                 return;
777         mp = &morph3d[MI_SCREEN(mi)];
778
779         MI_IS_DRAWN(mi) = True;
780
781         if (!mp->glx_context)
782                 return;
783
784         glXMakeCurrent(display, window, *(mp->glx_context));
785
786         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
787
788         glPushMatrix();
789
790         glTranslatef(0.0, 0.0, -10.0);
791
792         if (!MI_IS_ICONIC(mi)) {
793                 glScalef(Scale4Window * mp->WindH / mp->WindW, Scale4Window, Scale4Window);
794                 glTranslatef(2.5 * mp->WindW / mp->WindH * sin(mp->step * 1.11), 2.5 * cos(mp->step * 1.25 * 1.11), 0);
795         } else {
796                 glScalef(Scale4Iconic * mp->WindH / mp->WindW, Scale4Iconic, Scale4Iconic);
797         }
798
799         glRotatef(mp->step * 100, 1, 0, 0);
800         glRotatef(mp->step * 95, 0, 1, 0);
801         glRotatef(mp->step * 90, 0, 0, 1);
802
803         mp->seno = (sin(mp->step) + 1.0 / 3.0) * (4.0 / 5.0) * mp->Magnitude;
804
805         if (mp->VisibleSpikes) {
806 #ifdef DEBUG_CULL_FACE
807                 int         loop;
808
809                 for (loop = 0; loop < 20; loop++)
810                         mp->MaterialColor[loop] = MaterialGray;
811 #endif
812                 glDisable(GL_CULL_FACE);
813         } else {
814 #ifdef DEBUG_CULL_FACE
815                 int         loop;
816
817                 for (loop = 0; loop < 20; loop++)
818                         mp->MaterialColor[loop] = MaterialWhite;
819 #endif
820                 glEnable(GL_CULL_FACE);
821         }
822
823         mp->draw_object(mi);
824
825         glPopMatrix();
826
827         if (MI_IS_FPS(mi)) do_fps (mi);
828         glXSwapBuffers(display, window);
829
830         mp->step += 0.05;
831 }
832
833 void
834 change_morph3d(ModeInfo * mi)
835 {
836         morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
837
838         if (!mp->glx_context)
839                 return;
840
841         mp->object = (mp->object) % 5 + 1;
842         pinit(mi);
843 }
844
845 void
846 release_morph3d(ModeInfo * mi)
847 {
848         if (morph3d != NULL) {
849                 (void) free((void *) morph3d);
850                 morph3d = (morph3dstruct *) NULL;
851         }
852         FreeAllGL(mi);
853 }
854
855 #endif