1 /* -*- Mode: C; tab-width: 4 -*- */
2 /* morph3d --- Shows 3D morphing objects */
4 #if !defined( lint ) && !defined( SABER )
5 static const char sccsid[] = "@(#)morph3d.c 4.07 97/11/24 xlockmore";
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.
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.
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.
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.
33 * Thanks goes also to Brian Paul for making it possible and inexpensive
34 * to use OpenGL at home.
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)
39 * Since I'm not a native English speaker, my apologies for any grammatical
42 * My e-mail addresses are
47 * Marcelo F. Vianna (Feb-13-1997)
50 * 27-Jul-97: Speed ups by Marcelo F. Vianna.
51 * 08-May-97: Speed ups by Marcelo F. Vianna.
56 * PURIFY 3.0a on SunOS4 reports an unitialized memory read on each of
57 * the glCallList() functions below when using MesaGL 2.1. This has
58 * been fixed in MesaGL 2.2 and later releases.
62 * due to a Bug/feature in VMS X11/Intrinsic.h has to be placed before xlock.
63 * otherwise caddr_t is not defined correctly
66 #include <X11/Intrinsic.h>
69 # define PROGCLASS "Morph3d"
70 # define HACK_INIT init_morph3d
71 # define HACK_DRAW draw_morph3d
72 # define morph3d_opts xlockmore_opts
73 # define DEFAULTS "*delay: 1000 \n" \
75 # include "xlockmore.h" /* from the xscreensaver distribution */
76 #else /* !STANDALONE */
77 # include "xlock.h" /* from the xlockmore distribution */
78 #endif /* !STANDALONE */
82 ModeSpecOpt morph3d_opts =
83 {0, NULL, 0, NULL, NULL};
86 ModStruct morph3d_description =
87 {"morph3d", "init_morph3d", "draw_morph3d", "release_morph3d",
88 "draw_morph3d", "change_morph3d", NULL, &morph3d_opts,
89 1000, 0, 1, 1, 4, 1.0, "",
90 "Shows GL morphing polyhedra", 0, NULL};
94 #define Scale4Window 0.3
95 #define Scale4Iconic 1.0
97 #define VectMul(X1,Y1,Z1,X2,Y2,Z2) (Y1)*(Z2)-(Z1)*(Y2),(Z1)*(X2)-(X1)*(Z2),(X1)*(Y2)-(Y1)*(X2)
98 #define sqr(A) ((A)*(A))
100 /* Increasing this values produces better image quality, the price is speed. */
101 #define tetradivisions 23
102 #define cubedivisions 20
103 #define octadivisions 21
104 #define dodecadivisions 10
105 #define icodivisions 15
107 #define tetraangle 109.47122063449069174
108 #define cubeangle 90.000000000000000000
109 #define octaangle 109.47122063449069174
110 #define dodecaangle 63.434948822922009981
111 #define icoangle 41.810314895778596167
116 #define SQRT2 1.4142135623730951455
117 #define SQRT3 1.7320508075688771932
118 #define SQRT5 2.2360679774997898051
119 #define SQRT6 2.4494897427831778813
120 #define SQRT15 3.8729833462074170214
121 #define cossec36_2 0.8506508083520399322
122 #define cos72 0.3090169943749474241
123 #define sin72 0.9510565162951535721
124 #define cos36 0.8090169943749474241
125 #define sin36 0.5877852522924731292
127 /*************************************************************************/
136 void (*draw_object) (ModeInfo * mi);
138 float *MaterialColor[20];
139 GLXContext *glx_context;
142 static float front_shininess[] =
144 static float front_specular[] =
145 {0.7, 0.7, 0.7, 1.0};
146 static float ambient[] =
147 {0.0, 0.0, 0.0, 1.0};
148 static float diffuse[] =
149 {1.0, 1.0, 1.0, 1.0};
150 static float position0[] =
151 {1.0, 1.0, 1.0, 0.0};
152 static float position1[] =
153 {-1.0, -1.0, 1.0, 0.0};
154 static float lmodel_ambient[] =
155 {0.5, 0.5, 0.5, 1.0};
156 static float lmodel_twoside[] =
159 static float MaterialRed[] =
160 {0.7, 0.0, 0.0, 1.0};
161 static float MaterialGreen[] =
162 {0.1, 0.5, 0.2, 1.0};
163 static float MaterialBlue[] =
164 {0.0, 0.0, 0.7, 1.0};
165 static float MaterialCyan[] =
166 {0.2, 0.5, 0.7, 1.0};
167 static float MaterialYellow[] =
168 {0.7, 0.7, 0.0, 1.0};
169 static float MaterialMagenta[] =
170 {0.6, 0.2, 0.5, 1.0};
171 static float MaterialWhite[] =
172 {0.7, 0.7, 0.7, 1.0};
173 static float MaterialGray[] =
174 {0.5, 0.5, 0.5, 1.0};
176 static morph3dstruct *morph3d = NULL;
178 #define TRIANGLE(Edge, Amp, Divisions, Z, VS) \
180 GLfloat Xf,Yf,Xa,Yb,Xf2,Yf2,Yf_2,Yb2,Yb_2; \
181 GLfloat Factor=0.0,Factor1,Factor2; \
182 GLfloat VertX,VertY,VertZ,NeiAX,NeiAY,NeiAZ,NeiBX,NeiBY,NeiBZ; \
185 GLfloat Vr=(Edge)*SQRT3/3; \
186 GLfloat AmpVr2=(Amp)/sqr(Vr); \
187 GLfloat Zf=(Edge)*(Z); \
189 Ax=(Edge)*(+0.5/(Divisions)), Ay=(Edge)*(-SQRT3/(2*Divisions)); \
191 Yf=Vr+Ay; Yb=Yf+0.001; \
192 for (Ri=1; Ri<=(Divisions); Ri++) { \
193 glBegin(GL_TRIANGLE_STRIP); \
194 Xf=(float)Ri*Ax; Xa=Xf+0.001; \
195 Yf2=sqr(Yf); Yf_2=sqr(Yf-Ay); \
196 Yb2=sqr(Yb); Yb_2=sqr(Yb-Ay); \
197 for (Ti=0; Ti<Ri; Ti++) { \
198 Factor=1-(((Xf2=sqr(Xf))+Yf2)*AmpVr2); \
199 Factor1=1-((sqr(Xa)+Yf2)*AmpVr2); \
200 Factor2=1-((Xf2+Yb2)*AmpVr2); \
201 VertX=Factor*Xf; VertY=Factor*Yf; VertZ=Factor*Zf; \
202 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ; \
203 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
204 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
205 glVertex3f(VertX, VertY, VertZ); \
207 Xf-=Ax; Yf-=Ay; Xa-=Ax; Yb-=Ay; \
209 Factor=1-(((Xf2=sqr(Xf))+Yf_2)*AmpVr2); \
210 Factor1=1-((sqr(Xa)+Yf_2)*AmpVr2); \
211 Factor2=1-((Xf2+Yb_2)*AmpVr2); \
212 VertX=Factor*Xf; VertY=Factor*Yf; VertZ=Factor*Zf; \
213 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ; \
214 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
215 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
216 glVertex3f(VertX, VertY, VertZ); \
218 Xf-=Ax; Yf+=Ay; Xa-=Ax; Yb+=Ay; \
220 Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2); \
221 Factor1=1-((sqr(Xa)+Yf2)*AmpVr2); \
222 Factor2=1-((Xf2+sqr(Yb))*AmpVr2); \
223 VertX=Factor*Xf; VertY=Factor*Yf; VertZ=Factor*Zf; \
224 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ; \
225 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
226 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
227 glVertex3f(VertX, VertY, VertZ); \
234 #define SQUARE(Edge, Amp, Divisions, Z, VS) \
237 GLfloat Xf,Yf,Y,Xf2,Yf2,Y2,Xa,Xa2,Yb; \
238 GLfloat Factor=0.0,Factor1,Factor2; \
239 GLfloat VertX,VertY,VertZ,NeiAX,NeiAY,NeiAZ,NeiBX,NeiBY,NeiBZ; \
240 GLfloat Zf=(Edge)*(Z); \
241 GLfloat AmpVr2=(Amp)/sqr((Edge)*SQRT2/2); \
243 for (Yi=0; Yi<(Divisions); Yi++) { \
244 Yf=-((Edge)/2.0) + ((float)Yi)/(Divisions)*(Edge); \
246 Y=Yf+1.0/(Divisions)*(Edge); \
248 glBegin(GL_QUAD_STRIP); \
249 for (Xi=0; Xi<=(Divisions); Xi++) { \
250 Xf=-((Edge)/2.0) + ((float)Xi)/(Divisions)*(Edge); \
253 Xa=Xf+0.001; Yb=Y+0.001; \
254 Factor=1-((Xf2+Y2)*AmpVr2); \
255 Factor1=1-(((Xa2=sqr(Xa))+Y2)*AmpVr2); \
256 Factor2=1-((Xf2+sqr(Yb))*AmpVr2); \
257 VertX=Factor*Xf; VertY=Factor*Y; VertZ=Factor*Zf; \
258 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Y-VertY; NeiAZ=Factor1*Zf-VertZ; \
259 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
260 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
261 glVertex3f(VertX, VertY, VertZ); \
264 Factor=1-((Xf2+Yf2)*AmpVr2); \
265 Factor1=1-((Xa2+Yf2)*AmpVr2); \
266 Factor2=1-((Xf2+sqr(Yb))*AmpVr2); \
267 VertX=Factor*Xf; VertY=Factor*Yf; VertZ=Factor*Zf; \
268 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ; \
269 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
270 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
271 glVertex3f(VertX, VertY, VertZ); \
278 #define PENTAGON(Edge, Amp, Divisions, Z, VS) \
281 GLfloat Xf,Yf,Xa,Yb,Xf2,Yf2; \
282 GLfloat Factor=0.0,Factor1,Factor2; \
283 GLfloat VertX,VertY,VertZ,NeiAX,NeiAY,NeiAZ,NeiBX,NeiBY,NeiBZ; \
284 GLfloat Zf=(Edge)*(Z); \
285 GLfloat AmpVr2=(Amp)/sqr((Edge)*cossec36_2); \
287 static GLfloat x[6],y[6]; \
288 static int arrayninit=1; \
291 for(Fi=0;Fi<6;Fi++) { \
292 x[Fi]=-cos( Fi*2*Pi/5 + Pi/10 )/(Divisions)*cossec36_2*(Edge); \
293 y[Fi]=sin( Fi*2*Pi/5 + Pi/10 )/(Divisions)*cossec36_2*(Edge); \
298 for (Ri=1; Ri<=(Divisions); Ri++) { \
299 for (Fi=0; Fi<5; Fi++) { \
300 glBegin(GL_TRIANGLE_STRIP); \
301 for (Ti=0; Ti<Ri; Ti++) { \
302 Xf=(float)(Ri-Ti)*x[Fi] + (float)Ti*x[Fi+1]; \
303 Yf=(float)(Ri-Ti)*y[Fi] + (float)Ti*y[Fi+1]; \
304 Xa=Xf+0.001; Yb=Yf+0.001; \
305 Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2); \
306 Factor1=1-((sqr(Xa)+Yf2)*AmpVr2); \
307 Factor2=1-((Xf2+sqr(Yb))*AmpVr2); \
308 VertX=Factor*Xf; VertY=Factor*Yf; VertZ=Factor*Zf; \
309 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ; \
310 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
311 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
312 glVertex3f(VertX, VertY, VertZ); \
314 Xf-=x[Fi]; Yf-=y[Fi]; Xa-=x[Fi]; Yb-=y[Fi]; \
316 Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2); \
317 Factor1=1-((sqr(Xa)+Yf2)*AmpVr2); \
318 Factor2=1-((Xf2+sqr(Yb))*AmpVr2); \
319 VertX=Factor*Xf; VertY=Factor*Yf; VertZ=Factor*Zf; \
320 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ; \
321 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
322 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
323 glVertex3f(VertX, VertY, VertZ); \
326 Xf=(float)Ri*x[Fi+1]; \
327 Yf=(float)Ri*y[Fi+1]; \
328 Xa=Xf+0.001; Yb=Yf+0.001; \
329 Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2); \
330 Factor1=1-((sqr(Xa)+Yf2)*AmpVr2); \
331 Factor2=1-((Xf2+sqr(Yb))*AmpVr2); \
332 VertX=Factor*Xf; VertY=Factor*Yf; VertZ=Factor*Zf; \
333 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ; \
334 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
335 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
336 glVertex3f(VertX, VertY, VertZ); \
344 draw_tetra(ModeInfo * mi)
348 morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
350 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[0]);
352 list = glGenLists(1);
353 glNewList(list, GL_COMPILE_AND_EXECUTE);
354 TRIANGLE(2, mp->seno, mp->edgedivisions, 0.5 / SQRT6, mp->VisibleSpikes);
358 glRotatef(180, 0, 0, 1);
359 glRotatef(-tetraangle, 1, 0, 0);
360 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[1]);
364 glRotatef(180, 0, 1, 0);
365 glRotatef(-180 + tetraangle, 0.5, SQRT3 / 2, 0);
366 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[2]);
369 glRotatef(180, 0, 1, 0);
370 glRotatef(-180 + tetraangle, 0.5, -SQRT3 / 2, 0);
371 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[3]);
374 glDeleteLists(list, 1);
378 draw_cube(ModeInfo * mi)
382 morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
385 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[0]);
387 list = glGenLists(1);
388 glNewList(list, GL_COMPILE_AND_EXECUTE);
389 SQUARE(2, mp->seno, mp->edgedivisions, 0.5, mp->VisibleSpikes)
392 glRotatef(cubeangle, 1, 0, 0);
393 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[1]);
395 glRotatef(cubeangle, 1, 0, 0);
396 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[2]);
398 glRotatef(cubeangle, 1, 0, 0);
399 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[3]);
401 glRotatef(cubeangle, 0, 1, 0);
402 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[4]);
404 glRotatef(2 * cubeangle, 0, 1, 0);
405 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[5]);
408 glDeleteLists(list, 1);
412 draw_octa(ModeInfo * mi)
416 morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
418 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[0]);
420 list = glGenLists(1);
421 glNewList(list, GL_COMPILE_AND_EXECUTE);
422 TRIANGLE(2, mp->seno, mp->edgedivisions, 1 / SQRT6, mp->VisibleSpikes);
426 glRotatef(180, 0, 0, 1);
427 glRotatef(-180 + octaangle, 1, 0, 0);
428 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[1]);
432 glRotatef(180, 0, 1, 0);
433 glRotatef(-octaangle, 0.5, SQRT3 / 2, 0);
434 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[2]);
438 glRotatef(180, 0, 1, 0);
439 glRotatef(-octaangle, 0.5, -SQRT3 / 2, 0);
440 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[3]);
443 glRotatef(180, 1, 0, 0);
444 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[4]);
447 glRotatef(180, 0, 0, 1);
448 glRotatef(-180 + octaangle, 1, 0, 0);
449 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[5]);
453 glRotatef(180, 0, 1, 0);
454 glRotatef(-octaangle, 0.5, SQRT3 / 2, 0);
455 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[6]);
458 glRotatef(180, 0, 1, 0);
459 glRotatef(-octaangle, 0.5, -SQRT3 / 2, 0);
460 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[7]);
463 glDeleteLists(list, 1);
467 draw_dodeca(ModeInfo * mi)
471 morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
473 #define TAU ((SQRT5+1)/2)
475 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[0]);
477 list = glGenLists(1);
478 glNewList(list, GL_COMPILE_AND_EXECUTE);
479 PENTAGON(1, mp->seno, mp->edgedivisions, sqr(TAU) * sqrt((TAU + 2) / 5) / 2, mp->VisibleSpikes);
483 glRotatef(180, 0, 0, 1);
485 glRotatef(-dodecaangle, 1, 0, 0);
486 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[1]);
490 glRotatef(-dodecaangle, cos72, sin72, 0);
491 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[2]);
495 glRotatef(-dodecaangle, cos72, -sin72, 0);
496 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[3]);
500 glRotatef(dodecaangle, cos36, -sin36, 0);
501 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[4]);
504 glRotatef(dodecaangle, cos36, sin36, 0);
505 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[5]);
508 glRotatef(180, 1, 0, 0);
509 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[6]);
511 glRotatef(180, 0, 0, 1);
513 glRotatef(-dodecaangle, 1, 0, 0);
514 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[7]);
518 glRotatef(-dodecaangle, cos72, sin72, 0);
519 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[8]);
523 glRotatef(-dodecaangle, cos72, -sin72, 0);
524 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[9]);
528 glRotatef(dodecaangle, cos36, -sin36, 0);
529 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[10]);
532 glRotatef(dodecaangle, cos36, sin36, 0);
533 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[11]);
536 glDeleteLists(list, 1);
540 draw_icosa(ModeInfo * mi)
544 morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
546 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[0]);
548 list = glGenLists(1);
549 glNewList(list, GL_COMPILE_AND_EXECUTE);
550 TRIANGLE(1.5, mp->seno, mp->edgedivisions, (3 * SQRT3 + SQRT15) / 12, mp->VisibleSpikes);
556 glRotatef(180, 0, 0, 1);
557 glRotatef(-icoangle, 1, 0, 0);
558 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[1]);
561 glRotatef(180, 0, 1, 0);
562 glRotatef(-180 + icoangle, 0.5, SQRT3 / 2, 0);
563 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[2]);
566 glRotatef(180, 0, 1, 0);
567 glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0);
568 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[3]);
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[4]);
577 glRotatef(180, 0, 1, 0);
578 glRotatef(-180 + icoangle, 0.5, SQRT3 / 2, 0);
579 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[5]);
582 glRotatef(180, 0, 0, 1);
583 glRotatef(-icoangle, 1, 0, 0);
584 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[6]);
587 glRotatef(180, 0, 1, 0);
588 glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0);
589 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[7]);
592 glRotatef(180, 0, 1, 0);
593 glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0);
594 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[8]);
597 glRotatef(180, 0, 0, 1);
598 glRotatef(-icoangle, 1, 0, 0);
599 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[9]);
602 glRotatef(180, 1, 0, 0);
603 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[10]);
606 glRotatef(180, 0, 0, 1);
607 glRotatef(-icoangle, 1, 0, 0);
608 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[11]);
611 glRotatef(180, 0, 1, 0);
612 glRotatef(-180 + icoangle, 0.5, SQRT3 / 2, 0);
613 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[12]);
616 glRotatef(180, 0, 1, 0);
617 glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0);
618 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[13]);
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[14]);
627 glRotatef(180, 0, 1, 0);
628 glRotatef(-180 + icoangle, 0.5, SQRT3 / 2, 0);
629 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[15]);
632 glRotatef(180, 0, 0, 1);
633 glRotatef(-icoangle, 1, 0, 0);
634 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[16]);
637 glRotatef(180, 0, 1, 0);
638 glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0);
639 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[17]);
642 glRotatef(180, 0, 1, 0);
643 glRotatef(-180 + icoangle, 0.5, -SQRT3 / 2, 0);
644 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[18]);
647 glRotatef(180, 0, 0, 1);
648 glRotatef(-icoangle, 1, 0, 0);
649 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mp->MaterialColor[19]);
652 glDeleteLists(list, 1);
656 reshape(ModeInfo * mi, int width, int height)
658 morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
660 glViewport(0, 0, mp->WindW = (GLint) width, mp->WindH = (GLint) height);
661 glMatrixMode(GL_PROJECTION);
663 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 15.0);
664 glMatrixMode(GL_MODELVIEW);
670 morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
673 glClearColor(0.0, 0.0, 0.0, 1.0);
674 glColor3f(1.0, 1.0, 1.0);
676 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
677 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
678 glLightfv(GL_LIGHT0, GL_POSITION, position0);
679 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
680 glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
681 glLightfv(GL_LIGHT1, GL_POSITION, position1);
682 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
683 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
684 glEnable(GL_LIGHTING);
687 glEnable(GL_DEPTH_TEST);
688 glEnable(GL_NORMALIZE);
690 glShadeModel(GL_SMOOTH);
691 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_shininess);
692 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular);
694 switch (mp->object) {
696 mp->draw_object = draw_cube;
697 mp->MaterialColor[0] = MaterialRed;
698 mp->MaterialColor[1] = MaterialGreen;
699 mp->MaterialColor[2] = MaterialCyan;
700 mp->MaterialColor[3] = MaterialMagenta;
701 mp->MaterialColor[4] = MaterialYellow;
702 mp->MaterialColor[5] = MaterialBlue;
703 mp->edgedivisions = cubedivisions;
707 mp->draw_object = draw_octa;
708 mp->MaterialColor[0] = MaterialRed;
709 mp->MaterialColor[1] = MaterialGreen;
710 mp->MaterialColor[2] = MaterialBlue;
711 mp->MaterialColor[3] = MaterialWhite;
712 mp->MaterialColor[4] = MaterialCyan;
713 mp->MaterialColor[5] = MaterialMagenta;
714 mp->MaterialColor[6] = MaterialGray;
715 mp->MaterialColor[7] = MaterialYellow;
716 mp->edgedivisions = octadivisions;
720 mp->draw_object = draw_dodeca;
721 mp->MaterialColor[0] = MaterialRed;
722 mp->MaterialColor[1] = MaterialGreen;
723 mp->MaterialColor[2] = MaterialCyan;
724 mp->MaterialColor[3] = MaterialBlue;
725 mp->MaterialColor[4] = MaterialMagenta;
726 mp->MaterialColor[5] = MaterialYellow;
727 mp->MaterialColor[6] = MaterialGreen;
728 mp->MaterialColor[7] = MaterialCyan;
729 mp->MaterialColor[8] = MaterialRed;
730 mp->MaterialColor[9] = MaterialMagenta;
731 mp->MaterialColor[10] = MaterialBlue;
732 mp->MaterialColor[11] = MaterialYellow;
733 mp->edgedivisions = dodecadivisions;
737 mp->draw_object = draw_icosa;
738 mp->MaterialColor[0] = MaterialRed;
739 mp->MaterialColor[1] = MaterialGreen;
740 mp->MaterialColor[2] = MaterialBlue;
741 mp->MaterialColor[3] = MaterialCyan;
742 mp->MaterialColor[4] = MaterialYellow;
743 mp->MaterialColor[5] = MaterialMagenta;
744 mp->MaterialColor[6] = MaterialRed;
745 mp->MaterialColor[7] = MaterialGreen;
746 mp->MaterialColor[8] = MaterialBlue;
747 mp->MaterialColor[9] = MaterialWhite;
748 mp->MaterialColor[10] = MaterialCyan;
749 mp->MaterialColor[11] = MaterialYellow;
750 mp->MaterialColor[12] = MaterialMagenta;
751 mp->MaterialColor[13] = MaterialRed;
752 mp->MaterialColor[14] = MaterialGreen;
753 mp->MaterialColor[15] = MaterialBlue;
754 mp->MaterialColor[16] = MaterialCyan;
755 mp->MaterialColor[17] = MaterialYellow;
756 mp->MaterialColor[18] = MaterialMagenta;
757 mp->MaterialColor[19] = MaterialGray;
758 mp->edgedivisions = icodivisions;
762 mp->draw_object = draw_tetra;
763 mp->MaterialColor[0] = MaterialRed;
764 mp->MaterialColor[1] = MaterialGreen;
765 mp->MaterialColor[2] = MaterialBlue;
766 mp->MaterialColor[3] = MaterialWhite;
767 mp->edgedivisions = tetradivisions;
771 if (MI_IS_MONO(mi)) {
774 for (loop = 0; loop < 20; loop++)
775 mp->MaterialColor[loop] = MaterialGray;
780 init_morph3d(ModeInfo * mi)
782 int screen = MI_SCREEN(mi);
785 if (morph3d == NULL) {
786 if ((morph3d = (morph3dstruct *) calloc(MI_NUM_SCREENS(mi),
787 sizeof (morph3dstruct))) == NULL)
790 mp = &morph3d[screen];
791 mp->step = NRAND(90);
792 mp->VisibleSpikes = 1;
794 if ((mp->glx_context = init_GL(mi)) != NULL) {
796 reshape(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
797 mp->object = MI_COUNT(mi);
798 if (mp->object <= 0 || mp->object > 5)
799 mp->object = NRAND(5) + 1;
807 draw_morph3d(ModeInfo * mi)
809 morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
811 Display *display = MI_DISPLAY(mi);
812 Window window = MI_WINDOW(mi);
814 if (!mp->glx_context)
817 glDrawBuffer(GL_BACK);
818 glXMakeCurrent(display, window, *(mp->glx_context));
820 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
824 glTranslatef(0.0, 0.0, -10.0);
826 if (!MI_IS_ICONIC(mi)) {
827 glScalef(Scale4Window * mp->WindH / mp->WindW, Scale4Window, Scale4Window);
828 glTranslatef(2.5 * mp->WindW / mp->WindH * sin(mp->step * 1.11), 2.5 * cos(mp->step * 1.25 * 1.11), 0);
830 glScalef(Scale4Iconic * mp->WindH / mp->WindW, Scale4Iconic, Scale4Iconic);
833 glRotatef(mp->step * 100, 1, 0, 0);
834 glRotatef(mp->step * 95, 0, 1, 0);
835 glRotatef(mp->step * 90, 0, 0, 1);
837 mp->seno = (sin(mp->step) + 1.0 / 3.0) * (4.0 / 5.0) * mp->Magnitude;
839 if (mp->VisibleSpikes) {
840 #ifdef DEBUG_CULL_FACE
843 for (loop = 0; loop < 20; loop++)
844 mp->MaterialColor[loop] = MaterialGray;
846 glDisable(GL_CULL_FACE);
848 #ifdef DEBUG_CULL_FACE
851 for (loop = 0; loop < 20; loop++)
852 mp->MaterialColor[loop] = MaterialWhite;
854 glEnable(GL_CULL_FACE);
863 glXSwapBuffers(display, window);
869 change_morph3d(ModeInfo * mi)
871 morph3dstruct *mp = &morph3d[MI_SCREEN(mi)];
873 if (!mp->glx_context)
876 mp->object = (mp->object) % 5 + 1;
881 release_morph3d(ModeInfo * mi)
883 if (morph3d != NULL) {
884 (void) free((void *) morph3d);