1 #if !defined( lint ) && !defined( SABER )
2 static const char sccsid[] = "@(#)morph3d.c 4.02 97/04/01 xlockmore";
9 * morph3d.c - Shows 3D morphing objects (XLock Version)
11 * See xlock.c for copying information.
13 * The original code for this mode was written by Marcelo Fernandes Vianna
14 * (me...) and was inspired on a WindowsNT(R)'s screen saver. It was written
15 * from scratch and it was not based on any other source code.
17 * Porting it to xlock (the final objective of this code since the moment I
18 * decided to create it) was possible by comparing the original Mesa's gear
19 * demo with it's ported version to xlock, so thanks for Danny Sung (look at
20 * gear.c) for his indirect help.
22 * Thanks goes also to Brian Paul for making it possible and inexpensive
23 * to use OpenGL at home.
25 * If you are interested in the original version of this program (not a xlock
26 * mode, please refer to the Mesa package (ftp iris.ssec.wisc.edu on /pub/Mesa)
28 * Since I'm not a native english speaker, my apologies for any gramatical
31 * My e-mail addresses are
34 * marcelo@venus.rdc.puc-rio.br
36 * Marcelo F. Vianna (Feb-13-1997)
39 * 27-Jul-97: Speed ups by Marcelo F. Vianna.
40 * 08-May-97: Speed ups by Marcelo F. Vianna.
45 * PURIFY 3.0a on SunOS4 reports an unitialized memory read on each of
46 * the glCallList() functions below when using MesaGL 2.1. This has
47 * been fixed in MesaGL 2.2 and later releases.
51 * due to a Bug/feature in VMS X11/Intrinsic.h has to be placed before xlock.
52 * otherwise caddr_t is not defined correctly
55 #include <X11/Intrinsic.h>
58 # define PROGCLASS "Morph3d"
59 # define HACK_INIT init_morph3d
60 # define HACK_DRAW draw_morph3d
61 # define morph3d_opts xlockmore_opts
62 # define DEFAULTS "*delay: 1000 \n" \
64 # include "xlockmore.h" /* from the xscreensaver distribution */
65 #else /* !STANDALONE */
66 # include "xlock.h" /* from the xlockmore distribution */
67 #endif /* !STANDALONE */
71 ModeSpecOpt morph3d_opts =
72 {0, NULL, 0, NULL, NULL};
74 #define Scale4Window 0.3
75 #define Scale4Iconic 1.0
77 #define VectMul(X1,Y1,Z1,X2,Y2,Z2) (Y1)*(Z2)-(Z1)*(Y2),(Z1)*(X2)-(X1)*(Z2),(X1)*(Y2)-(Y1)*(X2)
78 #define sqr(A) ((A)*(A))
80 /* Increasing this values produces better image quality, the price is speed. */
81 #define tetradivisions 23
82 #define cubedivisions 20
83 #define octadivisions 21
84 #define dodecadivisions 10
85 #define icodivisions 15
87 #define tetraangle 109.47122063449069174
88 #define cubeangle 90.000000000000000000
89 #define octaangle 109.47122063449069174
90 #define dodecaangle 63.434948822922009981
91 #define icoangle 41.810314895778596167
96 #define SQRT2 1.4142135623730951455
97 #define SQRT3 1.7320508075688771932
98 #define SQRT5 2.2360679774997898051
99 #define SQRT6 2.4494897427831778813
100 #define SQRT15 3.8729833462074170214
101 #define cossec36_2 0.8506508083520399322
102 #define cos72 0.3090169943749474241
103 #define sin72 0.9510565162951535721
104 #define cos36 0.8090169943749474241
105 #define sin36 0.5877852522924731292
107 /*************************************************************************/
116 void (*draw_object) (ModeInfo * mi);
118 float *MaterialColor[20];
119 GLXContext glx_context;
122 static float front_shininess[] =
124 static float front_specular[] =
125 {0.7, 0.7, 0.7, 1.0};
126 static float ambient[] =
127 {0.0, 0.0, 0.0, 1.0};
128 static float diffuse[] =
129 {1.0, 1.0, 1.0, 1.0};
130 static float position0[] =
131 {1.0, 1.0, 1.0, 0.0};
132 static float position1[] =
133 {-1.0, -1.0, 1.0, 0.0};
134 static float lmodel_ambient[] =
135 {0.5, 0.5, 0.5, 1.0};
136 static float lmodel_twoside[] =
139 static float MaterialRed[] =
140 {0.7, 0.0, 0.0, 1.0};
141 static float MaterialGreen[] =
142 {0.1, 0.5, 0.2, 1.0};
143 static float MaterialBlue[] =
144 {0.0, 0.0, 0.7, 1.0};
145 static float MaterialCyan[] =
146 {0.2, 0.5, 0.7, 1.0};
147 static float MaterialYellow[] =
148 {0.7, 0.7, 0.0, 1.0};
149 static float MaterialMagenta[] =
150 {0.6, 0.2, 0.5, 1.0};
151 static float MaterialWhite[] =
152 {0.7, 0.7, 0.7, 1.0};
153 static float MaterialGray[] =
154 {0.2, 0.2, 0.2, 1.0};
156 static morph3dstruct *morph3d = NULL;
158 #define TRIANGLE(Edge, Amp, Divisions, Z, VS) \
160 GLfloat Xf,Yf,Xa,Yb,Xf2,Yf2,Yf_2,Yb2,Yb_2; \
161 GLfloat Factor=0.0,Factor1,Factor2; \
162 GLfloat VertX,VertY,VertZ,NeiAX,NeiAY,NeiAZ,NeiBX,NeiBY,NeiBZ; \
165 GLfloat Vr=(Edge)*SQRT3/3; \
166 GLfloat AmpVr2=(Amp)/sqr(Vr); \
167 GLfloat Zf=(Edge)*(Z); \
169 Ax=(Edge)*(+0.5/(Divisions)), Ay=(Edge)*(-SQRT3/(2*Divisions)); \
171 Yf=Vr+Ay; Yb=Yf+0.001; \
172 for (Ri=1; Ri<=(Divisions); Ri++) { \
173 glBegin(GL_TRIANGLE_STRIP); \
174 Xf=(float)Ri*Ax; Xa=Xf+0.001; \
175 Yf2=sqr(Yf); Yf_2=sqr(Yf-Ay); \
176 Yb2=sqr(Yb); Yb_2=sqr(Yb-Ay); \
177 for (Ti=0; Ti<Ri; Ti++) { \
178 Factor=1-(((Xf2=sqr(Xf))+Yf2)*AmpVr2); \
179 Factor1=1-((sqr(Xa)+Yf2)*AmpVr2); \
180 Factor2=1-((Xf2+Yb2)*AmpVr2); \
181 VertX=Factor*Xf; VertY=Factor*Yf; VertZ=Factor*Zf; \
182 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ; \
183 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
184 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
185 glVertex3f(VertX, VertY, VertZ); \
187 Xf-=Ax; Yf-=Ay; Xa-=Ax; Yb-=Ay; \
189 Factor=1-(((Xf2=sqr(Xf))+Yf_2)*AmpVr2); \
190 Factor1=1-((sqr(Xa)+Yf_2)*AmpVr2); \
191 Factor2=1-((Xf2+Yb_2)*AmpVr2); \
192 VertX=Factor*Xf; VertY=Factor*Yf; VertZ=Factor*Zf; \
193 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ; \
194 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
195 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
196 glVertex3f(VertX, VertY, VertZ); \
198 Xf-=Ax; Yf+=Ay; Xa-=Ax; Yb+=Ay; \
200 Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2); \
201 Factor1=1-((sqr(Xa)+Yf2)*AmpVr2); \
202 Factor2=1-((Xf2+sqr(Yb))*AmpVr2); \
203 VertX=Factor*Xf; VertY=Factor*Yf; VertZ=Factor*Zf; \
204 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ; \
205 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
206 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
207 glVertex3f(VertX, VertY, VertZ); \
214 #define SQUARE(Edge, Amp, Divisions, Z, VS) \
217 GLfloat Xf,Yf,Y,Xf2,Yf2,Y2,Xa,Xa2,Yb; \
218 GLfloat Factor=0.0,Factor1,Factor2; \
219 GLfloat VertX,VertY,VertZ,NeiAX,NeiAY,NeiAZ,NeiBX,NeiBY,NeiBZ; \
220 GLfloat Zf=(Edge)*(Z); \
221 GLfloat AmpVr2=(Amp)/sqr((Edge)*SQRT2/2); \
223 for (Yi=0; Yi<(Divisions); Yi++) { \
224 Yf=-((Edge)/2.0) + ((float)Yi)/(Divisions)*(Edge); \
226 Y=Yf+1.0/(Divisions)*(Edge); \
228 glBegin(GL_QUAD_STRIP); \
229 for (Xi=0; Xi<=(Divisions); Xi++) { \
230 Xf=-((Edge)/2.0) + ((float)Xi)/(Divisions)*(Edge); \
233 Xa=Xf+0.001; Yb=Y+0.001; \
234 Factor=1-((Xf2+Y2)*AmpVr2); \
235 Factor1=1-(((Xa2=sqr(Xa))+Y2)*AmpVr2); \
236 Factor2=1-((Xf2+sqr(Yb))*AmpVr2); \
237 VertX=Factor*Xf; VertY=Factor*Y; VertZ=Factor*Zf; \
238 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Y-VertY; NeiAZ=Factor1*Zf-VertZ; \
239 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
240 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
241 glVertex3f(VertX, VertY, VertZ); \
244 Factor=1-((Xf2+Yf2)*AmpVr2); \
245 Factor1=1-((Xa2+Yf2)*AmpVr2); \
246 Factor2=1-((Xf2+sqr(Yb))*AmpVr2); \
247 VertX=Factor*Xf; VertY=Factor*Yf; VertZ=Factor*Zf; \
248 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ; \
249 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
250 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
251 glVertex3f(VertX, VertY, VertZ); \
258 #define PENTAGON(Edge, Amp, Divisions, Z, VS) \
261 GLfloat Xf,Yf,Xa,Yb,Xf2,Yf2; \
262 GLfloat Factor=0.0,Factor1,Factor2; \
263 GLfloat VertX,VertY,VertZ,NeiAX,NeiAY,NeiAZ,NeiBX,NeiBY,NeiBZ; \
264 GLfloat Zf=(Edge)*(Z); \
265 GLfloat AmpVr2=(Amp)/sqr((Edge)*cossec36_2); \
267 static GLfloat x[6],y[6]; \
268 static arrayninit=1; \
271 for(Fi=0;Fi<6;Fi++) { \
272 x[Fi]=-cos( Fi*2*Pi/5 + Pi/10 )/(Divisions)*cossec36_2*(Edge); \
273 y[Fi]=sin( Fi*2*Pi/5 + Pi/10 )/(Divisions)*cossec36_2*(Edge); \
278 for (Ri=1; Ri<=(Divisions); Ri++) { \
279 for (Fi=0; Fi<5; Fi++) { \
280 glBegin(GL_TRIANGLE_STRIP); \
281 for (Ti=0; Ti<Ri; Ti++) { \
282 Xf=(float)(Ri-Ti)*x[Fi] + (float)Ti*x[Fi+1]; \
283 Yf=(float)(Ri-Ti)*y[Fi] + (float)Ti*y[Fi+1]; \
284 Xa=Xf+0.001; Yb=Yf+0.001; \
285 Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2); \
286 Factor1=1-((sqr(Xa)+Yf2)*AmpVr2); \
287 Factor2=1-((Xf2+sqr(Yb))*AmpVr2); \
288 VertX=Factor*Xf; VertY=Factor*Yf; VertZ=Factor*Zf; \
289 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ; \
290 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
291 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
292 glVertex3f(VertX, VertY, VertZ); \
294 Xf-=x[Fi]; Yf-=y[Fi]; Xa-=x[Fi]; Yb-=y[Fi]; \
296 Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2); \
297 Factor1=1-((sqr(Xa)+Yf2)*AmpVr2); \
298 Factor2=1-((Xf2+sqr(Yb))*AmpVr2); \
299 VertX=Factor*Xf; VertY=Factor*Yf; VertZ=Factor*Zf; \
300 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ; \
301 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
302 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
303 glVertex3f(VertX, VertY, VertZ); \
306 Xf=(float)Ri*x[Fi+1]; \
307 Yf=(float)Ri*y[Fi+1]; \
308 Xa=Xf+0.001; Yb=Yf+0.001; \
309 Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2); \
310 Factor1=1-((sqr(Xa)+Yf2)*AmpVr2); \
311 Factor2=1-((Xf2+sqr(Yb))*AmpVr2); \
312 VertX=Factor*Xf; VertY=Factor*Yf; VertZ=Factor*Zf; \
313 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ; \
314 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
315 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
316 glVertex3f(VertX, VertY, VertZ); \
324 draw_tetra(ModeInfo * mi)
328 morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
330 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[0]);
332 list = glGenLists(1);
333 glNewList(list, GL_COMPILE_AND_EXECUTE);
334 TRIANGLE(2, mp->seno, mp->edgedivisions, 0.5 / SQRT6, mp->VisibleSpikes);
338 glRotatef(180, 0, 0, 1);
339 glRotatef(-tetraangle, 1, 0, 0);
340 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[1]);
344 glRotatef(180, 0, 1, 0);
345 glRotatef(-180 + tetraangle, 0.5, SQRT3 / 2, 0);
346 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[2]);
349 glRotatef(180, 0, 1, 0);
350 glRotatef(-180 + tetraangle, 0.5, -SQRT3 / 2, 0);
351 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[3]);
354 glDeleteLists(list, 1);
358 draw_cube(ModeInfo * mi)
362 morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
365 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[0]);
367 list = glGenLists(1);
368 glNewList(list, GL_COMPILE_AND_EXECUTE);
369 SQUARE(2, mp->seno, mp->edgedivisions, 0.5, mp->VisibleSpikes)
372 glRotatef(cubeangle, 1, 0, 0);
373 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[1]);
375 glRotatef(cubeangle, 1, 0, 0);
376 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[2]);
378 glRotatef(cubeangle, 1, 0, 0);
379 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[3]);
381 glRotatef(cubeangle, 0, 1, 0);
382 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[4]);
384 glRotatef(2 * cubeangle, 0, 1, 0);
385 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[5]);
388 glDeleteLists(list, 1);
392 draw_octa(ModeInfo * mi)
396 morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
398 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[0]);
400 list = glGenLists(1);
401 glNewList(list, GL_COMPILE_AND_EXECUTE);
402 TRIANGLE(2, mp->seno, mp->edgedivisions, 1 / SQRT6, mp->VisibleSpikes);
406 glRotatef(180, 0, 0, 1);
407 glRotatef(-180 + octaangle, 1, 0, 0);
408 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[1]);
412 glRotatef(180, 0, 1, 0);
413 glRotatef(-octaangle, 0.5, SQRT3 / 2, 0);
414 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[2]);
418 glRotatef(180, 0, 1, 0);
419 glRotatef(-octaangle, 0.5, -SQRT3 / 2, 0);
420 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[3]);
423 glRotatef(180, 1, 0, 0);
424 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[4]);
427 glRotatef(180, 0, 0, 1);
428 glRotatef(-180 + octaangle, 1, 0, 0);
429 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[5]);
433 glRotatef(180, 0, 1, 0);
434 glRotatef(-octaangle, 0.5, SQRT3 / 2, 0);
435 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[6]);
438 glRotatef(180, 0, 1, 0);
439 glRotatef(-octaangle, 0.5, -SQRT3 / 2, 0);
440 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[7]);
443 glDeleteLists(list, 1);
447 draw_dodeca(ModeInfo * mi)
451 morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
453 #define TAU ((SQRT5+1)/2)
455 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[0]);
457 list = glGenLists(1);
458 glNewList(list, GL_COMPILE_AND_EXECUTE);
459 PENTAGON(1, mp->seno, mp->edgedivisions, sqr(TAU) * sqrt((TAU + 2) / 5) / 2, mp->VisibleSpikes);
463 glRotatef(180, 0, 0, 1);
465 glRotatef(-dodecaangle, 1, 0, 0);
466 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[1]);
470 glRotatef(-dodecaangle, cos72, sin72, 0);
471 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[2]);
475 glRotatef(-dodecaangle, cos72, -sin72, 0);
476 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[3]);
480 glRotatef(dodecaangle, cos36, -sin36, 0);
481 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[4]);
484 glRotatef(dodecaangle, cos36, sin36, 0);
485 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[5]);
488 glRotatef(180, 1, 0, 0);
489 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[6]);
491 glRotatef(180, 0, 0, 1);
493 glRotatef(-dodecaangle, 1, 0, 0);
494 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[7]);
498 glRotatef(-dodecaangle, cos72, sin72, 0);
499 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[8]);
503 glRotatef(-dodecaangle, cos72, -sin72, 0);
504 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[9]);
508 glRotatef(dodecaangle, cos36, -sin36, 0);
509 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[10]);
512 glRotatef(dodecaangle, cos36, sin36, 0);
513 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[11]);
516 glDeleteLists(list, 1);
520 draw_icosa(ModeInfo * mi)
524 morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
526 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[0]);
528 list = glGenLists(1);
529 glNewList(list, GL_COMPILE_AND_EXECUTE);
530 TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes);
536 glRotatef(180, 0, 0, 1);
537 glRotatef(-icoangle, 1, 0, 0);
538 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[1]);
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[2]);
546 glRotatef(180, 0, 1, 0);
547 glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0);
548 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[3]);
552 glRotatef(180, 0, 1, 0);
553 glRotatef(-180 + icoangle, 0.5, SQRT3 / 2, 0);
554 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[4]);
557 glRotatef(180, 0, 1, 0);
558 glRotatef(-180 + icoangle, 0.5, SQRT3 / 2, 0);
559 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[5]);
562 glRotatef(180, 0, 0, 1);
563 glRotatef(-icoangle, 1, 0, 0);
564 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[6]);
567 glRotatef(180, 0, 1, 0);
568 glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0);
569 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[7]);
572 glRotatef(180, 0, 1, 0);
573 glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0);
574 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[8]);
577 glRotatef(180, 0, 0, 1);
578 glRotatef(-icoangle, 1, 0, 0);
579 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[9]);
582 glRotatef(180, 1, 0, 0);
583 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[10]);
586 glRotatef(180, 0, 0, 1);
587 glRotatef(-icoangle, 1, 0, 0);
588 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[11]);
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[12]);
596 glRotatef(180, 0, 1, 0);
597 glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0);
598 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[13]);
602 glRotatef(180, 0, 1, 0);
603 glRotatef(-180 + icoangle, 0.5, SQRT3 / 2, 0);
604 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[14]);
607 glRotatef(180, 0, 1, 0);
608 glRotatef(-180 + icoangle, 0.5, SQRT3 / 2, 0);
609 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[15]);
612 glRotatef(180, 0, 0, 1);
613 glRotatef(-icoangle, 1, 0, 0);
614 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[16]);
617 glRotatef(180, 0, 1, 0);
618 glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0);
619 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[17]);
622 glRotatef(180, 0, 1, 0);
623 glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0);
624 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[18]);
627 glRotatef(180, 0, 0, 1);
628 glRotatef(-icoangle, 1, 0, 0);
629 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[19]);
632 glDeleteLists(list, 1);
636 draw_morph3d(ModeInfo * mi)
638 morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
640 Display *display = MI_DISPLAY(mi);
641 Window window = MI_WINDOW(mi);
643 glDrawBuffer(GL_BACK);
644 glXMakeCurrent(display, window, mp->glx_context);
646 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
650 glTranslatef(0.0, 0.0, -10.0);
652 if (!MI_WIN_IS_ICONIC(mi)) {
653 glScalef(Scale4Window * mp->WindH / mp->WindW, Scale4Window, Scale4Window);
654 glTranslatef(2.5 * mp->WindW / mp->WindH * sin(mp->step * 1.11), 2.5 * cos(mp->step * 1.25 * 1.11), 0);
656 glScalef(Scale4Iconic * mp->WindH / mp->WindW, Scale4Iconic, Scale4Iconic);
659 glRotatef(mp->step * 100, 1, 0, 0);
660 glRotatef(mp->step * 95, 0, 1, 0);
661 glRotatef(mp->step * 90, 0, 0, 1);
663 mp->seno = (sin(mp->step) + 1.0 / 3.0) * (4.0 / 5.0) * mp->Magnitude;
665 if (mp->VisibleSpikes) {
666 #ifdef DEBUG_CULL_FACE
669 for (loop = 0; loop < 20; loop++)
670 mp->MaterialColor[loop] = MaterialGray;
672 glDisable(GL_CULL_FACE);
674 #ifdef DEBUG_CULL_FACE
677 for (loop = 0; loop < 20; loop++)
678 mp->MaterialColor[loop] = MaterialWhite;
680 glEnable(GL_CULL_FACE);
689 glXSwapBuffers(display, window);
695 reshape(ModeInfo * mi, int width, int height)
697 morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
699 glViewport(0, 0, mp->WindW = (GLint) width, mp->WindH = (GLint) height);
700 glMatrixMode(GL_PROJECTION);
702 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 15.0);
703 glMatrixMode(GL_MODELVIEW);
709 morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
712 glClearColor(0.0, 0.0, 0.0, 1.0);
713 glColor3f(1.0, 1.0, 1.0);
715 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
716 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
717 glLightfv(GL_LIGHT0, GL_POSITION, position0);
718 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
719 glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
720 glLightfv(GL_LIGHT1, GL_POSITION, position1);
721 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
722 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
723 glEnable(GL_LIGHTING);
726 glEnable(GL_DEPTH_TEST);
727 glEnable(GL_NORMALIZE);
729 glShadeModel(GL_SMOOTH);
730 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_shininess);
731 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular);
733 switch (mp->object) {
735 mp->draw_object = draw_cube;
736 mp->MaterialColor[0] = MaterialRed;
737 mp->MaterialColor[1] = MaterialGreen;
738 mp->MaterialColor[2] = MaterialCyan;
739 mp->MaterialColor[3] = MaterialMagenta;
740 mp->MaterialColor[4] = MaterialYellow;
741 mp->MaterialColor[5] = MaterialBlue;
742 mp->edgedivisions = cubedivisions;
746 mp->draw_object = draw_octa;
747 mp->MaterialColor[0] = MaterialRed;
748 mp->MaterialColor[1] = MaterialGreen;
749 mp->MaterialColor[2] = MaterialBlue;
750 mp->MaterialColor[3] = MaterialWhite;
751 mp->MaterialColor[4] = MaterialCyan;
752 mp->MaterialColor[5] = MaterialMagenta;
753 mp->MaterialColor[6] = MaterialGray;
754 mp->MaterialColor[7] = MaterialYellow;
755 mp->edgedivisions = octadivisions;
759 mp->draw_object = draw_dodeca;
760 mp->MaterialColor[0] = MaterialRed;
761 mp->MaterialColor[1] = MaterialGreen;
762 mp->MaterialColor[2] = MaterialCyan;
763 mp->MaterialColor[3] = MaterialBlue;
764 mp->MaterialColor[4] = MaterialMagenta;
765 mp->MaterialColor[5] = MaterialYellow;
766 mp->MaterialColor[6] = MaterialGreen;
767 mp->MaterialColor[7] = MaterialCyan;
768 mp->MaterialColor[8] = MaterialRed;
769 mp->MaterialColor[9] = MaterialMagenta;
770 mp->MaterialColor[10] = MaterialBlue;
771 mp->MaterialColor[11] = MaterialYellow;
772 mp->edgedivisions = dodecadivisions;
776 mp->draw_object = draw_icosa;
777 mp->MaterialColor[0] = MaterialRed;
778 mp->MaterialColor[1] = MaterialGreen;
779 mp->MaterialColor[2] = MaterialBlue;
780 mp->MaterialColor[3] = MaterialCyan;
781 mp->MaterialColor[4] = MaterialYellow;
782 mp->MaterialColor[5] = MaterialMagenta;
783 mp->MaterialColor[6] = MaterialRed;
784 mp->MaterialColor[7] = MaterialGreen;
785 mp->MaterialColor[8] = MaterialBlue;
786 mp->MaterialColor[9] = MaterialWhite;
787 mp->MaterialColor[10] = MaterialCyan;
788 mp->MaterialColor[11] = MaterialYellow;
789 mp->MaterialColor[12] = MaterialMagenta;
790 mp->MaterialColor[13] = MaterialRed;
791 mp->MaterialColor[14] = MaterialGreen;
792 mp->MaterialColor[15] = MaterialBlue;
793 mp->MaterialColor[16] = MaterialCyan;
794 mp->MaterialColor[17] = MaterialYellow;
795 mp->MaterialColor[18] = MaterialMagenta;
796 mp->MaterialColor[19] = MaterialGray;
797 mp->edgedivisions = icodivisions;
801 mp->draw_object = draw_tetra;
802 mp->MaterialColor[0] = MaterialRed;
803 mp->MaterialColor[1] = MaterialGreen;
804 mp->MaterialColor[2] = MaterialBlue;
805 mp->MaterialColor[3] = MaterialWhite;
806 mp->edgedivisions = tetradivisions;
810 if (MI_WIN_IS_MONO(mi)) {
813 for (loop = 0; loop < 20; loop++)
814 mp->MaterialColor[loop] = MaterialGray;
819 init_morph3d(ModeInfo * mi)
821 int screen = MI_SCREEN(mi);
824 if (morph3d == NULL) {
825 if ((morph3d = (morph3dstruct *) calloc(MI_NUM_SCREENS(mi),
826 sizeof (morph3dstruct))) == NULL)
829 mp = &morph3d[screen];
830 mp->step = NRAND(90);
831 mp->VisibleSpikes = 1;
833 mp->glx_context = init_GL(mi);
835 reshape(mi, MI_WIN_WIDTH(mi), MI_WIN_HEIGHT(mi));
836 mp->object = MI_BATCHCOUNT(mi);
837 if (mp->object <= 0 || mp->object > 5)
838 mp->object = NRAND(5) + 1;
843 change_morph3d(ModeInfo * mi)
845 morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
847 mp->object = (mp->object) % 5 + 1;
852 release_morph3d(ModeInfo * mi)
854 if (morph3d != NULL) {
855 (void) free((void *) morph3d);