disable the unrecognized nlsflag
[AROS-Contrib.git] / Demo / Mesa / morph3d.c
blob815c7b136ab0370305d48f9b9696202969fdaf20
2 /*-
3 * morph3d.c - Shows 3D morphing objects
5 * Converted to GLUT by brianp on 1/1/98
7 * This program was inspired on a WindowsNT(R)'s screen saver. It was written
8 * from scratch and it was not based on any other source code.
9 *
10 * Porting it to xlock (the final objective of this code since the moment I
11 * decided to create it) was possible by comparing the original Mesa's gear
12 * demo with it's ported version, so thanks for Danny Sung for his indirect
13 * help (look at gear.c in xlock source tree). NOTE: At the moment this code
14 * was sent to Brian Paul for package inclusion, the XLock Version was not
15 * available. In fact, I'll wait it to appear on the next Mesa release (If you
16 * are reading this, it means THIS release) to send it for xlock package
17 * inclusion). It will probably there be a GLUT version too.
19 * Thanks goes also to Brian Paul for making it possible and inexpensive
20 * to use OpenGL at home.
22 * Since I'm not a native english speaker, my apologies for any gramatical
23 * mistake.
25 * My e-mail addresses are
27 * vianna@cat.cbpf.br
28 * and
29 * marcelo@venus.rdc.puc-rio.br
31 * Marcelo F. Vianna (Feb-13-1997)
35 This document is VERY incomplete, but tries to describe the mathematics used
36 in the program. At this moment it just describes how the polyhedra are
37 generated. On futhurer versions, this document will be probabbly improved.
39 Since I'm not a native english speaker, my apologies for any gramatical
40 mistake.
42 Marcelo Fernandes Vianna
43 - Undergraduate in Computer Engeneering at Catholic Pontifical University
44 - of Rio de Janeiro (PUC-Rio) Brasil.
45 - e-mail: vianna@cat.cbpf.br or marcelo@venus.rdc.puc-rio.br
46 - Feb-13-1997
48 POLYHEDRA GENERATION
50 For the purpose of this program it's not sufficient to know the polyhedra
51 vertexes coordinates. Since the morphing algorithm applies a nonlinear
52 transformation over the surfaces (faces) of the polyhedron, each face has
53 to be divided into smaller ones. The morphing algorithm needs to transform
54 each vertex of these smaller faces individually. It's a very time consoming
55 task.
57 In order to reduce calculation overload, and since all the macro faces of
58 the polyhedron are transformed by the same way, the generation is made by
59 creating only one face of the polyhedron, morphing it and then rotating it
60 around the polyhedron center.
62 What we need to know is the face radius of the polyhedron (the radius of
63 the inscribed sphere) and the angle between the center of two adjacent
64 faces using the center of the sphere as the angle's vertex.
66 The face radius of the regular polyhedra are known values which I decided
67 to not waste my time calculating. Following is a table of face radius for
68 the regular polyhedra with edge length = 1:
70 TETRAHEDRON : 1/(2*sqrt(2))/sqrt(3)
71 CUBE : 1/2
72 OCTAHEDRON : 1/sqrt(6)
73 DODECAHEDRON : T^2 * sqrt((T+2)/5) / 2 -> where T=(sqrt(5)+1)/2
74 ICOSAHEDRON : (3*sqrt(3)+sqrt(15))/12
76 I've not found any reference about the mentioned angles, so I needed to
77 calculate them, not a trivial task until I figured out how :)
78 Curiously these angles are the same for the tetrahedron and octahedron.
79 A way to obtain this value is inscribing the tetrahedron inside the cube
80 by matching their vertexes. So you'll notice that the remaining unmatched
81 vertexes are in the same straight line starting in the cube/tetrahedron
82 center and crossing the center of each tetrahedron's face. At this point
83 it's easy to obtain the bigger angle of the isosceles triangle formed by
84 the center of the cube and two opposite vertexes on the same cube face.
85 The edges of this triangle have the following lenghts: sqrt(2) for the base
86 and sqrt(3)/2 for the other two other edges. So the angle we want is:
87 +-----------------------------------------------------------+
88 | 2*ARCSIN(sqrt(2)/sqrt(3)) = 109.47122063449069174 degrees |
89 +-----------------------------------------------------------+
90 For the cube this angle is obvious, but just for formality it can be
91 easily obtained because we also know it's isosceles edge lenghts:
92 sqrt(2)/2 for the base and 1/2 for the other two edges. So the angle we
93 want is:
94 +-----------------------------------------------------------+
95 | 2*ARCSIN((sqrt(2)/2)/1) = 90.000000000000000000 degrees |
96 +-----------------------------------------------------------+
97 For the octahedron we use the same idea used for the tetrahedron, but now
98 we inscribe the cube inside the octahedron so that all cubes's vertexes
99 matches excatly the center of each octahedron's face. It's now clear that
100 this angle is the same of the thetrahedron one:
101 +-----------------------------------------------------------+
102 | 2*ARCSIN(sqrt(2)/sqrt(3)) = 109.47122063449069174 degrees |
103 +-----------------------------------------------------------+
104 For the dodecahedron it's a little bit harder because it's only relationship
105 with the cube is useless to us. So we need to solve the problem by another
106 way. The concept of Face radius also exists on 2D polygons with the name
107 Edge radius:
108 Edge Radius For Pentagon (ERp)
109 ERp = (1/2)/TAN(36 degrees) * VRp = 0.6881909602355867905
110 (VRp is the pentagon's vertex radio).
111 Face Radius For Dodecahedron
112 FRd = T^2 * sqrt((T+2)/5) / 2 = 1.1135163644116068404
113 Why we need ERp? Well, ERp and FRd segments forms a 90 degrees angle,
114 completing this triangle, the lesser angle is a half of the angle we are
115 looking for, so this angle is:
116 +-----------------------------------------------------------+
117 | 2*ARCTAN(ERp/FRd) = 63.434948822922009981 degrees |
118 +-----------------------------------------------------------+
119 For the icosahedron we can use the same method used for dodecahedron (well
120 the method used for dodecahedron may be used for all regular polyhedra)
121 Edge Radius For Triangle (this one is well known: 1/3 of the triangle height)
122 ERt = sin(60)/3 = sqrt(3)/6 = 0.2886751345948128655
123 Face Radius For Icosahedron
124 FRi= (3*sqrt(3)+sqrt(15))/12 = 0.7557613140761707538
125 So the angle is:
126 +-----------------------------------------------------------+
127 | 2*ARCTAN(ERt/FRi) = 41.810314895778596167 degrees |
128 +-----------------------------------------------------------+
133 #include <stdio.h>
134 #include <stdlib.h>
135 #ifndef _WIN32
136 #include <unistd.h>
137 #endif
138 #include <GL/glut.h>
139 #include <math.h>
140 #include <string.h>
142 #define Scale 0.3
144 #define VectMul(X1,Y1,Z1,X2,Y2,Z2) (Y1)*(Z2)-(Z1)*(Y2),(Z1)*(X2)-(X1)*(Z2),(X1)*(Y2)-(Y1)*(X2)
145 #define sqr(A) ((A)*(A))
147 /* Increasing this values produces better image quality, the price is speed. */
148 /* Very low values produces erroneous/incorrect plotting */
149 #define tetradivisions 23
150 #define cubedivisions 20
151 #define octadivisions 21
152 #define dodecadivisions 10
153 #define icodivisions 15
155 #define tetraangle 109.47122063449069174
156 #define cubeangle 90.000000000000000000
157 #define octaangle 109.47122063449069174
158 #define dodecaangle 63.434948822922009981
159 #define icoangle 41.810314895778596167
161 #ifndef Pi
162 #define Pi 3.1415926535897932385
163 #endif
164 #define SQRT2 1.4142135623730951455
165 #define SQRT3 1.7320508075688771932
166 #define SQRT5 2.2360679774997898051
167 #define SQRT6 2.4494897427831778813
168 #define SQRT15 3.8729833462074170214
169 #define cossec36_2 0.8506508083520399322
170 #define cos72 0.3090169943749474241
171 #define sin72 0.9510565162951535721
172 #define cos36 0.8090169943749474241
173 #define sin36 0.5877852522924731292
175 /*************************************************************************/
177 static int mono=0;
178 static int smooth=1;
179 static int anim=1;
180 static GLint WindH, WindW;
181 static GLfloat step=0;
182 static GLfloat seno;
183 static int object;
184 static int edgedivisions;
185 static void (*draw_object)( void );
186 static float Magnitude;
187 static float *MaterialColor[20];
189 static float front_shininess[] = {60.0};
190 static float front_specular[] = { 0.7, 0.7, 0.7, 1.0 };
191 static float ambient[] = { 0.0, 0.0, 0.0, 1.0 };
192 static float diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
193 static float position0[] = { 1.0, 1.0, 1.0, 0.0 };
194 static float position1[] = {-1.0,-1.0, 1.0, 0.0 };
195 static float lmodel_ambient[] = { 0.5, 0.5, 0.5, 1.0 };
196 static float lmodel_twoside[] = {GL_TRUE};
198 static float MaterialRed[] = { 0.7, 0.0, 0.0, 1.0 };
199 static float MaterialGreen[] = { 0.1, 0.5, 0.2, 1.0 };
200 static float MaterialBlue[] = { 0.0, 0.0, 0.7, 1.0 };
201 static float MaterialCyan[] = { 0.2, 0.5, 0.7, 1.0 };
202 static float MaterialYellow[] = { 0.7, 0.7, 0.0, 1.0 };
203 static float MaterialMagenta[] = { 0.6, 0.2, 0.5, 1.0 };
204 static float MaterialWhite[] = { 0.7, 0.7, 0.7, 1.0 };
205 static float MaterialGray[] = { 0.2, 0.2, 0.2, 1.0 };
207 #define TRIANGLE(Edge, Amp, Divisions, Z) \
209 GLfloat Xf,Yf,Xa,Yb,Xf2,Yf2; \
210 GLfloat Factor,Factor1,Factor2; \
211 GLfloat VertX,VertY,VertZ,NeiAX,NeiAY,NeiAZ,NeiBX,NeiBY,NeiBZ; \
212 GLfloat Ax,Ay,Bx; \
213 int Ri,Ti; \
214 GLfloat Vr=(Edge)*SQRT3/3; \
215 GLfloat AmpVr2=(Amp)/sqr(Vr); \
216 GLfloat Zf=(Edge)*(Z); \
218 Ax=(Edge)*(+0.5/(Divisions)), Ay=(Edge)*(-SQRT3/(2*Divisions)); \
219 Bx=(Edge)*(-0.5/(Divisions)); \
221 for (Ri=1; Ri<=(Divisions); Ri++) { \
222 glBegin(GL_TRIANGLE_STRIP); \
223 for (Ti=0; Ti<Ri; Ti++) { \
224 Xf=(float)(Ri-Ti)*Ax + (float)Ti*Bx; \
225 Yf=Vr+(float)(Ri-Ti)*Ay + (float)Ti*Ay; \
226 Xa=Xf+0.001; Yb=Yf+0.001; \
227 Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2); \
228 Factor1=1-((sqr(Xa)+Yf2)*AmpVr2); \
229 Factor2=1-((Xf2+sqr(Yb))*AmpVr2); \
230 VertX=Factor*Xf; VertY=Factor*Yf; VertZ=Factor*Zf; \
231 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ; \
232 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
233 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
234 glVertex3f(VertX, VertY, VertZ); \
236 Xf=(float)(Ri-Ti-1)*Ax + (float)Ti*Bx; \
237 Yf=Vr+(float)(Ri-Ti-1)*Ay + (float)Ti*Ay; \
238 Xa=Xf+0.001; Yb=Yf+0.001; \
239 Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2); \
240 Factor1=1-((sqr(Xa)+Yf2)*AmpVr2); \
241 Factor2=1-((Xf2+sqr(Yb))*AmpVr2); \
242 VertX=Factor*Xf; VertY=Factor*Yf; VertZ=Factor*Zf; \
243 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ; \
244 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
245 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
246 glVertex3f(VertX, VertY, VertZ); \
249 Xf=(float)Ri*Bx; \
250 Yf=Vr+(float)Ri*Ay; \
251 Xa=Xf+0.001; Yb=Yf+0.001; \
252 Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2); \
253 Factor1=1-((sqr(Xa)+Yf2)*AmpVr2); \
254 Factor2=1-((Xf2+sqr(Yb))*AmpVr2); \
255 VertX=Factor*Xf; VertY=Factor*Yf; VertZ=Factor*Zf; \
256 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ; \
257 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
258 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
259 glVertex3f(VertX, VertY, VertZ); \
260 glEnd(); \
264 #define SQUARE(Edge, Amp, Divisions, Z) \
266 int Xi,Yi; \
267 GLfloat Xf,Yf,Y,Xf2,Yf2,Y2,Xa,Yb; \
268 GLfloat Factor,Factor1,Factor2; \
269 GLfloat VertX,VertY,VertZ,NeiAX,NeiAY,NeiAZ,NeiBX,NeiBY,NeiBZ; \
270 GLfloat Zf=(Edge)*(Z); \
271 GLfloat AmpVr2=(Amp)/sqr((Edge)*SQRT2/2); \
273 for (Yi=0; Yi<(Divisions); Yi++) { \
274 Yf=-((Edge)/2.0) + ((float)Yi)/(Divisions)*(Edge); \
275 Yf2=sqr(Yf); \
276 Y=Yf+1.0/(Divisions)*(Edge); \
277 Y2=sqr(Y); \
278 glBegin(GL_QUAD_STRIP); \
279 for (Xi=0; Xi<=(Divisions); Xi++) { \
280 Xf=-((Edge)/2.0) + ((float)Xi)/(Divisions)*(Edge); \
281 Xf2=sqr(Xf); \
283 Xa=Xf+0.001; Yb=Y+0.001; \
284 Factor=1-((Xf2+Y2)*AmpVr2); \
285 Factor1=1-((sqr(Xa)+Y2)*AmpVr2); \
286 Factor2=1-((Xf2+sqr(Yb))*AmpVr2); \
287 VertX=Factor*Xf; VertY=Factor*Y; VertZ=Factor*Zf; \
288 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Y-VertY; NeiAZ=Factor1*Zf-VertZ; \
289 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
290 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
291 glVertex3f(VertX, VertY, VertZ); \
293 Xa=Xf+0.001; Yb=Yf+0.001; \
294 Factor=1-((Xf2+Yf2)*AmpVr2); \
295 Factor1=1-((sqr(Xa)+Yf2)*AmpVr2); \
296 Factor2=1-((Xf2+sqr(Yb))*AmpVr2); \
297 VertX=Factor*Xf; VertY=Factor*Yf; VertZ=Factor*Zf; \
298 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ; \
299 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
300 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
301 glVertex3f(VertX, VertY, VertZ); \
303 glEnd(); \
307 #define PENTAGON(Edge, Amp, Divisions, Z) \
309 int Ri,Ti,Fi; \
310 GLfloat Xf,Yf,Xa,Yb,Xf2,Yf2; \
311 GLfloat x[6],y[6]; \
312 GLfloat Factor,Factor1,Factor2; \
313 GLfloat VertX,VertY,VertZ,NeiAX,NeiAY,NeiAZ,NeiBX,NeiBY,NeiBZ; \
314 GLfloat Zf=(Edge)*(Z); \
315 GLfloat AmpVr2=(Amp)/sqr((Edge)*cossec36_2); \
317 for(Fi=0;Fi<6;Fi++) { \
318 x[Fi]=-cos( Fi*2*Pi/5 + Pi/10 )/(Divisions)*cossec36_2*(Edge); \
319 y[Fi]=sin( Fi*2*Pi/5 + Pi/10 )/(Divisions)*cossec36_2*(Edge); \
322 for (Ri=1; Ri<=(Divisions); Ri++) { \
323 for (Fi=0; Fi<5; Fi++) { \
324 glBegin(GL_TRIANGLE_STRIP); \
325 for (Ti=0; Ti<Ri; Ti++) { \
326 Xf=(float)(Ri-Ti)*x[Fi] + (float)Ti*x[Fi+1]; \
327 Yf=(float)(Ri-Ti)*y[Fi] + (float)Ti*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); \
338 Xf=(float)(Ri-Ti-1)*x[Fi] + (float)Ti*x[Fi+1]; \
339 Yf=(float)(Ri-Ti-1)*y[Fi] + (float)Ti*y[Fi+1]; \
340 Xa=Xf+0.001; Yb=Yf+0.001; \
341 Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2); \
342 Factor1=1-((sqr(Xa)+Yf2)*AmpVr2); \
343 Factor2=1-((Xf2+sqr(Yb))*AmpVr2); \
344 VertX=Factor*Xf; VertY=Factor*Yf; VertZ=Factor*Zf; \
345 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ; \
346 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
347 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
348 glVertex3f(VertX, VertY, VertZ); \
351 Xf=(float)Ri*x[Fi+1]; \
352 Yf=(float)Ri*y[Fi+1]; \
353 Xa=Xf+0.001; Yb=Yf+0.001; \
354 Factor=1-(((Xf2=sqr(Xf))+(Yf2=sqr(Yf)))*AmpVr2); \
355 Factor1=1-((sqr(Xa)+Yf2)*AmpVr2); \
356 Factor2=1-((Xf2+sqr(Yb))*AmpVr2); \
357 VertX=Factor*Xf; VertY=Factor*Yf; VertZ=Factor*Zf; \
358 NeiAX=Factor1*Xa-VertX; NeiAY=Factor1*Yf-VertY; NeiAZ=Factor1*Zf-VertZ; \
359 NeiBX=Factor2*Xf-VertX; NeiBY=Factor2*Yb-VertY; NeiBZ=Factor2*Zf-VertZ; \
360 glNormal3f(VectMul(NeiAX, NeiAY, NeiAZ, NeiBX, NeiBY, NeiBZ)); \
361 glVertex3f(VertX, VertY, VertZ); \
362 glEnd(); \
367 static void draw_tetra( void )
369 GLuint list;
371 list = glGenLists( 1 );
372 glNewList( list, GL_COMPILE );
373 TRIANGLE(2,seno,edgedivisions,0.5/SQRT6);
374 glEndList();
376 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[0]);
380 glCallList(list);
381 glPushMatrix();
382 glRotatef(180,0,0,1);
383 glRotatef(-tetraangle,1,0,0);
384 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[1]);
385 glCallList(list);
386 glPopMatrix();
387 glPushMatrix();
388 glRotatef(180,0,1,0);
389 glRotatef(-180+tetraangle,0.5,SQRT3/2,0);
390 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[2]);
391 glCallList(list);
392 glPopMatrix();
393 glRotatef(180,0,1,0);
394 glRotatef(-180+tetraangle,0.5,-SQRT3/2,0);
395 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[3]);
396 glCallList(list);
398 glDeleteLists(list,1);
401 static void draw_cube( void )
403 GLuint list;
405 list = glGenLists( 1 );
406 glNewList( list, GL_COMPILE );
407 SQUARE(2, seno, edgedivisions, 0.5)
408 glEndList();
410 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[0]);
411 glCallList(list);
412 glRotatef(cubeangle,1,0,0);
413 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[1]);
414 glCallList(list);
415 glRotatef(cubeangle,1,0,0);
416 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[2]);
417 glCallList(list);
418 glRotatef(cubeangle,1,0,0);
419 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[3]);
420 glCallList(list);
421 glRotatef(cubeangle,0,1,0);
422 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[4]);
423 glCallList(list);
424 glRotatef(2*cubeangle,0,1,0);
425 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[5]);
426 glCallList(list);
428 glDeleteLists(list,1);
431 static void draw_octa( void )
433 GLuint list;
435 list = glGenLists( 1 );
436 glNewList( list, GL_COMPILE );
437 TRIANGLE(2,seno,edgedivisions,1/SQRT6);
438 glEndList();
440 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[0]);
441 glCallList(list);
442 glPushMatrix();
443 glRotatef(180,0,0,1);
444 glRotatef(-180+octaangle,1,0,0);
445 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[1]);
446 glCallList(list);
447 glPopMatrix();
448 glPushMatrix();
449 glRotatef(180,0,1,0);
450 glRotatef(-octaangle,0.5,SQRT3/2,0);
451 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[2]);
452 glCallList(list);
453 glPopMatrix();
454 glPushMatrix();
455 glRotatef(180,0,1,0);
456 glRotatef(-octaangle,0.5,-SQRT3/2,0);
457 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[3]);
458 glCallList(list);
459 glPopMatrix();
460 glRotatef(180,1,0,0);
461 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[4]);
462 glCallList(list);
463 glPushMatrix();
464 glRotatef(180,0,0,1);
465 glRotatef(-180+octaangle,1,0,0);
466 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[5]);
467 glCallList(list);
468 glPopMatrix();
469 glPushMatrix();
470 glRotatef(180,0,1,0);
471 glRotatef(-octaangle,0.5,SQRT3/2,0);
472 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[6]);
473 glCallList(list);
474 glPopMatrix();
475 glRotatef(180,0,1,0);
476 glRotatef(-octaangle,0.5,-SQRT3/2,0);
477 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[7]);
478 glCallList(list);
480 glDeleteLists(list,1);
483 static void draw_dodeca( void )
485 GLuint list;
487 #define TAU ((SQRT5+1)/2)
489 list = glGenLists( 1 );
490 glNewList( list, GL_COMPILE );
491 PENTAGON(1,seno,edgedivisions,sqr(TAU) * sqrt((TAU+2)/5) / 2);
492 glEndList();
494 glPushMatrix();
495 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[0]);
496 glCallList(list);
497 glRotatef(180,0,0,1);
498 glPushMatrix();
499 glRotatef(-dodecaangle,1,0,0);
500 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[1]);
501 glCallList(list);
502 glPopMatrix();
503 glPushMatrix();
504 glRotatef(-dodecaangle,cos72,sin72,0);
505 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[2]);
506 glCallList(list);
507 glPopMatrix();
508 glPushMatrix();
509 glRotatef(-dodecaangle,cos72,-sin72,0);
510 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[3]);
511 glCallList(list);
512 glPopMatrix();
513 glPushMatrix();
514 glRotatef(dodecaangle,cos36,-sin36,0);
515 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[4]);
516 glCallList(list);
517 glPopMatrix();
518 glRotatef(dodecaangle,cos36,sin36,0);
519 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[5]);
520 glCallList(list);
521 glPopMatrix();
522 glRotatef(180,1,0,0);
523 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[6]);
524 glCallList(list);
525 glRotatef(180,0,0,1);
526 glPushMatrix();
527 glRotatef(-dodecaangle,1,0,0);
528 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[7]);
529 glCallList(list);
530 glPopMatrix();
531 glPushMatrix();
532 glRotatef(-dodecaangle,cos72,sin72,0);
533 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[8]);
534 glCallList(list);
535 glPopMatrix();
536 glPushMatrix();
537 glRotatef(-dodecaangle,cos72,-sin72,0);
538 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[9]);
539 glCallList(list);
540 glPopMatrix();
541 glPushMatrix();
542 glRotatef(dodecaangle,cos36,-sin36,0);
543 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[10]);
544 glCallList(list);
545 glPopMatrix();
546 glRotatef(dodecaangle,cos36,sin36,0);
547 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[11]);
548 glCallList(list);
550 glDeleteLists(list,1);
553 static void draw_ico( void )
555 GLuint list;
557 list = glGenLists( 1 );
558 glNewList( list, GL_COMPILE );
559 TRIANGLE(1.5,seno,edgedivisions,(3*SQRT3+SQRT15)/12);
560 glEndList();
562 glPushMatrix();
564 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[0]);
565 glCallList(list);
566 glPushMatrix();
567 glRotatef(180,0,0,1);
568 glRotatef(-icoangle,1,0,0);
569 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[1]);
570 glCallList(list);
571 glPushMatrix();
572 glRotatef(180,0,1,0);
573 glRotatef(-180+icoangle,0.5,SQRT3/2,0);
574 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[2]);
575 glCallList(list);
576 glPopMatrix();
577 glRotatef(180,0,1,0);
578 glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
579 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[3]);
580 glCallList(list);
581 glPopMatrix();
582 glPushMatrix();
583 glRotatef(180,0,1,0);
584 glRotatef(-180+icoangle,0.5,SQRT3/2,0);
585 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[4]);
586 glCallList(list);
587 glPushMatrix();
588 glRotatef(180,0,1,0);
589 glRotatef(-180+icoangle,0.5,SQRT3/2,0);
590 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[5]);
591 glCallList(list);
592 glPopMatrix();
593 glRotatef(180,0,0,1);
594 glRotatef(-icoangle,1,0,0);
595 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[6]);
596 glCallList(list);
597 glPopMatrix();
598 glRotatef(180,0,1,0);
599 glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
600 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[7]);
601 glCallList(list);
602 glPushMatrix();
603 glRotatef(180,0,1,0);
604 glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
605 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[8]);
606 glCallList(list);
607 glPopMatrix();
608 glRotatef(180,0,0,1);
609 glRotatef(-icoangle,1,0,0);
610 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[9]);
611 glCallList(list);
612 glPopMatrix();
613 glRotatef(180,1,0,0);
614 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[10]);
615 glCallList(list);
616 glPushMatrix();
617 glRotatef(180,0,0,1);
618 glRotatef(-icoangle,1,0,0);
619 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[11]);
620 glCallList(list);
621 glPushMatrix();
622 glRotatef(180,0,1,0);
623 glRotatef(-180+icoangle,0.5,SQRT3/2,0);
624 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[12]);
625 glCallList(list);
626 glPopMatrix();
627 glRotatef(180,0,1,0);
628 glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
629 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[13]);
630 glCallList(list);
631 glPopMatrix();
632 glPushMatrix();
633 glRotatef(180,0,1,0);
634 glRotatef(-180+icoangle,0.5,SQRT3/2,0);
635 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[14]);
636 glCallList(list);
637 glPushMatrix();
638 glRotatef(180,0,1,0);
639 glRotatef(-180+icoangle,0.5,SQRT3/2,0);
640 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[15]);
641 glCallList(list);
642 glPopMatrix();
643 glRotatef(180,0,0,1);
644 glRotatef(-icoangle,1,0,0);
645 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[16]);
646 glCallList(list);
647 glPopMatrix();
648 glRotatef(180,0,1,0);
649 glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
650 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[17]);
651 glCallList(list);
652 glPushMatrix();
653 glRotatef(180,0,1,0);
654 glRotatef(-180+icoangle,0.5,-SQRT3/2,0);
655 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[18]);
656 glCallList(list);
657 glPopMatrix();
658 glRotatef(180,0,0,1);
659 glRotatef(-icoangle,1,0,0);
660 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor[19]);
661 glCallList(list);
663 glDeleteLists(list,1);
668 static void draw ( void ) {
669 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
671 glPushMatrix();
673 glTranslatef( 0.0, 0.0, -10.0 );
674 glScalef( Scale*WindH/WindW, Scale, Scale );
675 glTranslatef(2.5*WindW/WindH*sin(step*1.11),2.5*cos(step*1.25*1.11),0);
676 glRotatef(step*100,1,0,0);
677 glRotatef(step*95,0,1,0);
678 glRotatef(step*90,0,0,1);
680 seno=(sin(step)+1.0/3.0)*(4.0/5.0)*Magnitude;
682 draw_object();
684 glPopMatrix();
686 glFlush();
688 glutSwapBuffers();
691 static void idle_( void )
693 static double t0 = -1.;
694 double dt, t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
695 if (t0 < 0.0)
696 t0 = t;
697 dt = t - t0;
698 t0 = t;
700 step += dt;
702 glutPostRedisplay();
705 static void reshape( int width, int height )
707 glViewport(0, 0, WindW=(GLint)width, WindH=(GLint)height);
708 glMatrixMode(GL_PROJECTION);
709 glLoadIdentity();
710 glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 15.0 );
711 glMatrixMode(GL_MODELVIEW);
714 static void pinit(void);
716 static void key( unsigned char k, int x, int y )
718 (void) x;
719 (void) y;
720 switch (k) {
721 case '1': object=1; break;
722 case '2': object=2; break;
723 case '3': object=3; break;
724 case '4': object=4; break;
725 case '5': object=5; break;
726 case ' ': mono^=1; break;
727 case 's': smooth^=1; break;
728 case 'a':
729 anim^=1;
730 if (anim)
731 glutIdleFunc( idle_ );
732 else
733 glutIdleFunc(NULL);
734 break;
735 case 27:
736 exit(0);
738 pinit();
739 glutPostRedisplay();
742 static void pinit(void)
744 switch(object) {
745 case 1:
746 draw_object=draw_tetra;
747 MaterialColor[0]=MaterialRed;
748 MaterialColor[1]=MaterialGreen;
749 MaterialColor[2]=MaterialBlue;
750 MaterialColor[3]=MaterialWhite;
751 edgedivisions=tetradivisions;
752 Magnitude=2.5;
753 break;
754 case 2:
755 draw_object=draw_cube;
756 MaterialColor[0]=MaterialRed;
757 MaterialColor[1]=MaterialGreen;
758 MaterialColor[2]=MaterialCyan;
759 MaterialColor[3]=MaterialMagenta;
760 MaterialColor[4]=MaterialYellow;
761 MaterialColor[5]=MaterialBlue;
762 edgedivisions=cubedivisions;
763 Magnitude=2.0;
764 break;
765 case 3:
766 draw_object=draw_octa;
767 MaterialColor[0]=MaterialRed;
768 MaterialColor[1]=MaterialGreen;
769 MaterialColor[2]=MaterialBlue;
770 MaterialColor[3]=MaterialWhite;
771 MaterialColor[4]=MaterialCyan;
772 MaterialColor[5]=MaterialMagenta;
773 MaterialColor[6]=MaterialGray;
774 MaterialColor[7]=MaterialYellow;
775 edgedivisions=octadivisions;
776 Magnitude=2.5;
777 break;
778 case 4:
779 draw_object=draw_dodeca;
780 MaterialColor[ 0]=MaterialRed;
781 MaterialColor[ 1]=MaterialGreen;
782 MaterialColor[ 2]=MaterialCyan;
783 MaterialColor[ 3]=MaterialBlue;
784 MaterialColor[ 4]=MaterialMagenta;
785 MaterialColor[ 5]=MaterialYellow;
786 MaterialColor[ 6]=MaterialGreen;
787 MaterialColor[ 7]=MaterialCyan;
788 MaterialColor[ 8]=MaterialRed;
789 MaterialColor[ 9]=MaterialMagenta;
790 MaterialColor[10]=MaterialBlue;
791 MaterialColor[11]=MaterialYellow;
792 edgedivisions=dodecadivisions;
793 Magnitude=2.0;
794 break;
795 case 5:
796 draw_object=draw_ico;
797 MaterialColor[ 0]=MaterialRed;
798 MaterialColor[ 1]=MaterialGreen;
799 MaterialColor[ 2]=MaterialBlue;
800 MaterialColor[ 3]=MaterialCyan;
801 MaterialColor[ 4]=MaterialYellow;
802 MaterialColor[ 5]=MaterialMagenta;
803 MaterialColor[ 6]=MaterialRed;
804 MaterialColor[ 7]=MaterialGreen;
805 MaterialColor[ 8]=MaterialBlue;
806 MaterialColor[ 9]=MaterialWhite;
807 MaterialColor[10]=MaterialCyan;
808 MaterialColor[11]=MaterialYellow;
809 MaterialColor[12]=MaterialMagenta;
810 MaterialColor[13]=MaterialRed;
811 MaterialColor[14]=MaterialGreen;
812 MaterialColor[15]=MaterialBlue;
813 MaterialColor[16]=MaterialCyan;
814 MaterialColor[17]=MaterialYellow;
815 MaterialColor[18]=MaterialMagenta;
816 MaterialColor[19]=MaterialGray;
817 edgedivisions=icodivisions;
818 Magnitude=2.5;
819 break;
821 if (mono) {
822 int loop;
823 for (loop=0; loop<20; loop++) MaterialColor[loop]=MaterialGray;
825 if (smooth) {
826 glShadeModel( GL_SMOOTH );
827 } else {
828 glShadeModel( GL_FLAT );
833 #include <proto/exec.h>
834 #include <proto/dos.h>
836 #define ARG_TEMPLATE "WINPOSX=X/N/K,WINPOSY=Y/N/K"
837 #define ARG_X 0
838 #define ARG_Y 1
839 #define NUM_ARGS 2
841 static IPTR args[NUM_ARGS];
842 WORD winx = -1, winy = -1;
843 #define W 320
844 #define H 200
846 static void correctpos(void)
848 if (winx == -1) winx = 100;
849 if (winy == -1) winy = 100;
852 static void getarguments(void)
854 struct RDArgs *myargs;
856 if ((myargs = ReadArgs(ARG_TEMPLATE, args, NULL)))
859 if (args[ARG_X]) winx = *(IPTR *)args[ARG_X];
860 if (args[ARG_Y]) winy = *(IPTR *)args[ARG_Y];
862 FreeArgs(myargs);
867 int main(int argc, char **argv)
869 printf("Morph 3D - Shows morphing platonic polyhedra\n");
870 printf("Author: Marcelo Fernandes Vianna (vianna@cat.cbpf.br)\n\n");
871 printf(" [1] - Tetrahedron\n");
872 printf(" [2] - Hexahedron (Cube)\n");
873 printf(" [3] - Octahedron\n");
874 printf(" [4] - Dodecahedron\n");
875 printf(" [5] - Icosahedron\n");
876 printf("[SPACE] - Toggle colored faces\n");
877 printf("[RETURN] - Toggle smooth/flat shading\n");
878 printf(" [ESC] - Quit\n");
880 object=1;
882 getarguments();
883 correctpos();
885 glutInit(&argc, argv);
886 glutInitWindowPosition(winx, winy);
887 glutInitWindowSize(W, H);
889 glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB );
891 if (glutCreateWindow("Morph 3D - Shows morphing platonic polyhedra") <= 0) {
892 exit(0);
895 glClearDepth(1.0);
896 glClearColor( 0.0, 0.0, 0.0, 1.0 );
897 glColor3f( 1.0, 1.0, 1.0 );
899 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
900 glFlush();
901 glutSwapBuffers();
903 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
904 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
905 glLightfv(GL_LIGHT0, GL_POSITION, position0);
906 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
907 glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
908 glLightfv(GL_LIGHT1, GL_POSITION, position1);
909 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
910 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
911 glEnable(GL_LIGHTING);
912 glEnable(GL_LIGHT0);
913 glEnable(GL_LIGHT1);
914 glEnable(GL_DEPTH_TEST);
915 glEnable(GL_NORMALIZE);
917 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_shininess);
918 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular);
920 glHint(GL_FOG_HINT, GL_FASTEST);
921 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
922 glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
924 pinit();
926 glutReshapeFunc( reshape );
927 glutKeyboardFunc( key );
928 glutIdleFunc( idle_ );
929 glutDisplayFunc( draw );
930 glutMainLoop();
932 return 0;