]> git.mxchange.org Git - simgear.git/blob - simgear/scene/sky/clouds3d/glut_shapes.c
Clouds3D crashes because there is no Light
[simgear.git] / simgear / scene / sky / clouds3d / glut_shapes.c
1
2 /* Copyright (c) Mark J. Kilgard, 1994, 1997. */
3
4 /**
5 (c) Copyright 1993, Silicon Graphics, Inc.
6
7 ALL RIGHTS RESERVED
8
9 Permission to use, copy, modify, and distribute this software
10 for any purpose and without fee is hereby granted, provided
11 that the above copyright notice appear in all copies and that
12 both the copyright notice and this permission notice appear in
13 supporting documentation, and that the name of Silicon
14 Graphics, Inc. not be used in advertising or publicity
15 pertaining to distribution of the software without specific,
16 written prior permission.
17
18 THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU
19 "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR
20 OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
21 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  IN NO
22 EVENT SHALL SILICON GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE
23 ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR
24 CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER,
25 INCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE,
26 SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR
27 NOT SILICON GRAPHICS, INC.  HAS BEEN ADVISED OF THE POSSIBILITY
28 OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE OR
30 PERFORMANCE OF THIS SOFTWARE.
31
32 US Government Users Restricted Rights
33
34 Use, duplication, or disclosure by the Government is subject to
35 restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
36 (c)(1)(ii) of the Rights in Technical Data and Computer
37 Software clause at DFARS 252.227-7013 and/or in similar or
38 successor clauses in the FAR or the DOD or NASA FAR
39 Supplement.  Unpublished-- rights reserved under the copyright
40 laws of the United States.  Contractor/manufacturer is Silicon
41 Graphics, Inc., 2011 N.  Shoreline Blvd., Mountain View, CA
42 94039-7311.
43
44 OpenGL(TM) is a trademark of Silicon Graphics, Inc.
45 */
46
47 #ifdef HAVE_CONFIG_H
48 #  include <simgear_config.h>
49 #endif
50
51
52 #ifdef HAVE_WINDOWS_H
53 #  include <windows.h>
54 #endif
55
56
57 #include <math.h>
58
59 #include <GL/glu.h>
60
61 #include "glut_shapes.h"
62
63 /* Some <math.h> files do not define M_PI... */
64 #ifndef M_PI
65 #define M_PI 3.14159265358979323846
66 #endif
67
68 static GLUquadricObj *quadObj;
69
70 #define QUAD_OBJ_INIT() { if(!quadObj) initQuadObj(); }
71
72 static void
73 initQuadObj(void)
74 {
75   quadObj = gluNewQuadric();
76   if (!quadObj)
77       /* __glutFatalError("out of memory.") */;
78 }
79
80 /* CENTRY */
81 void APIENTRY
82 glutWireSphere(GLdouble radius, GLint slices, GLint stacks)
83 {
84   QUAD_OBJ_INIT();
85   gluQuadricDrawStyle(quadObj, GLU_LINE);
86   gluQuadricNormals(quadObj, GLU_SMOOTH);
87   /* If we ever changed/used the texture or orientation state
88      of quadObj, we'd need to change it to the defaults here
89      with gluQuadricTexture and/or gluQuadricOrientation. */
90   gluSphere(quadObj, radius, slices, stacks);
91 }
92
93 void APIENTRY
94 glutSolidSphere(GLdouble radius, GLint slices, GLint stacks)
95 {
96   QUAD_OBJ_INIT();
97   gluQuadricDrawStyle(quadObj, GLU_FILL);
98   gluQuadricNormals(quadObj, GLU_SMOOTH);
99   /* If we ever changed/used the texture or orientation state
100      of quadObj, we'd need to change it to the defaults here
101      with gluQuadricTexture and/or gluQuadricOrientation. */
102   gluSphere(quadObj, radius, slices, stacks);
103 }
104
105 void APIENTRY
106 glutWireCone(GLdouble base, GLdouble height,
107   GLint slices, GLint stacks)
108 {
109   QUAD_OBJ_INIT();
110   gluQuadricDrawStyle(quadObj, GLU_LINE);
111   gluQuadricNormals(quadObj, GLU_SMOOTH);
112   /* If we ever changed/used the texture or orientation state
113      of quadObj, we'd need to change it to the defaults here
114      with gluQuadricTexture and/or gluQuadricOrientation. */
115   gluCylinder(quadObj, base, 0.0, height, slices, stacks);
116 }
117
118 void APIENTRY
119 glutSolidCone(GLdouble base, GLdouble height,
120   GLint slices, GLint stacks)
121 {
122   QUAD_OBJ_INIT();
123   gluQuadricDrawStyle(quadObj, GLU_FILL);
124   gluQuadricNormals(quadObj, GLU_SMOOTH);
125   /* If we ever changed/used the texture or orientation state
126      of quadObj, we'd need to change it to the defaults here
127      with gluQuadricTexture and/or gluQuadricOrientation. */
128   gluCylinder(quadObj, base, 0.0, height, slices, stacks);
129 }
130
131 /* ENDCENTRY */
132
133 static void
134 drawBox(GLfloat size, GLenum type)
135 {
136   static GLfloat n[6][3] =
137   {
138     {-1.0, 0.0, 0.0},
139     {0.0, 1.0, 0.0},
140     {1.0, 0.0, 0.0},
141     {0.0, -1.0, 0.0},
142     {0.0, 0.0, 1.0},
143     {0.0, 0.0, -1.0}
144   };
145   static GLint faces[6][4] =
146   {
147     {0, 1, 2, 3},
148     {3, 2, 6, 7},
149     {7, 6, 5, 4},
150     {4, 5, 1, 0},
151     {5, 6, 2, 1},
152     {7, 4, 0, 3}
153   };
154   GLfloat v[8][3];
155   GLint i;
156
157   v[0][0] = v[1][0] = v[2][0] = v[3][0] = -size / 2;
158   v[4][0] = v[5][0] = v[6][0] = v[7][0] = size / 2;
159   v[0][1] = v[1][1] = v[4][1] = v[5][1] = -size / 2;
160   v[2][1] = v[3][1] = v[6][1] = v[7][1] = size / 2;
161   v[0][2] = v[3][2] = v[4][2] = v[7][2] = -size / 2;
162   v[1][2] = v[2][2] = v[5][2] = v[6][2] = size / 2;
163
164   for (i = 5; i >= 0; i--) {
165     glBegin(type);
166     glNormal3fv(&n[i][0]);
167     glVertex3fv(&v[faces[i][0]][0]);
168     glVertex3fv(&v[faces[i][1]][0]);
169     glVertex3fv(&v[faces[i][2]][0]);
170     glVertex3fv(&v[faces[i][3]][0]);
171     glEnd();
172   }
173 }
174
175 /* CENTRY */
176 void APIENTRY
177 glutWireCube(GLdouble size)
178 {
179   drawBox(size, GL_LINE_LOOP);
180 }
181
182 void APIENTRY
183 glutSolidCube(GLdouble size)
184 {
185   drawBox(size, GL_QUADS);
186 }
187
188 /* ENDCENTRY */
189
190 static void
191 doughnut(GLfloat r, GLfloat R, GLint nsides, GLint rings)
192 {
193   int i, j;
194   GLfloat theta, phi, theta1;
195   GLfloat cosTheta, sinTheta;
196   GLfloat cosTheta1, sinTheta1;
197   GLfloat ringDelta, sideDelta;
198
199   ringDelta = 2.0 * M_PI / rings;
200   sideDelta = 2.0 * M_PI / nsides;
201
202   theta = 0.0;
203   cosTheta = 1.0;
204   sinTheta = 0.0;
205   for (i = rings - 1; i >= 0; i--) {
206     theta1 = theta + ringDelta;
207     cosTheta1 = cos(theta1);
208     sinTheta1 = sin(theta1);
209     glBegin(GL_QUAD_STRIP);
210     phi = 0.0;
211     for (j = nsides; j >= 0; j--) {
212       GLfloat cosPhi, sinPhi, dist;
213
214       phi += sideDelta;
215       cosPhi = cos(phi);
216       sinPhi = sin(phi);
217       dist = R + r * cosPhi;
218
219       glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
220       glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
221       glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
222       glVertex3f(cosTheta * dist, -sinTheta * dist,  r * sinPhi);
223     }
224     glEnd();
225     theta = theta1;
226     cosTheta = cosTheta1;
227     sinTheta = sinTheta1;
228   }
229 }
230
231 /* CENTRY */
232 void APIENTRY
233 glutWireTorus(GLdouble innerRadius, GLdouble outerRadius,
234   GLint nsides, GLint rings)
235 {
236   glPushAttrib(GL_POLYGON_BIT);
237   glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
238   doughnut(innerRadius, outerRadius, nsides, rings);
239   glPopAttrib();
240 }
241
242 void APIENTRY
243 glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius,
244   GLint nsides, GLint rings)
245 {
246   doughnut(innerRadius, outerRadius, nsides, rings);
247 }
248
249 /* ENDCENTRY */
250
251 static GLfloat dodec[20][3];
252
253 static void
254 initDodecahedron(void)
255 {
256   GLfloat alpha, beta;
257
258   alpha = sqrt(2.0 / (3.0 + sqrt(5.0)));
259   beta = 1.0 + sqrt(6.0 / (3.0 + sqrt(5.0)) -
260     2.0 + 2.0 * sqrt(2.0 / (3.0 + sqrt(5.0))));
261   /* *INDENT-OFF* */
262   dodec[0][0] = -alpha; dodec[0][1] = 0; dodec[0][2] = beta;
263   dodec[1][0] = alpha; dodec[1][1] = 0; dodec[1][2] = beta;
264   dodec[2][0] = -1; dodec[2][1] = -1; dodec[2][2] = -1;
265   dodec[3][0] = -1; dodec[3][1] = -1; dodec[3][2] = 1;
266   dodec[4][0] = -1; dodec[4][1] = 1; dodec[4][2] = -1;
267   dodec[5][0] = -1; dodec[5][1] = 1; dodec[5][2] = 1;
268   dodec[6][0] = 1; dodec[6][1] = -1; dodec[6][2] = -1;
269   dodec[7][0] = 1; dodec[7][1] = -1; dodec[7][2] = 1;
270   dodec[8][0] = 1; dodec[8][1] = 1; dodec[8][2] = -1;
271   dodec[9][0] = 1; dodec[9][1] = 1; dodec[9][2] = 1;
272   dodec[10][0] = beta; dodec[10][1] = alpha; dodec[10][2] = 0;
273   dodec[11][0] = beta; dodec[11][1] = -alpha; dodec[11][2] = 0;
274   dodec[12][0] = -beta; dodec[12][1] = alpha; dodec[12][2] = 0;
275   dodec[13][0] = -beta; dodec[13][1] = -alpha; dodec[13][2] = 0;
276   dodec[14][0] = -alpha; dodec[14][1] = 0; dodec[14][2] = -beta;
277   dodec[15][0] = alpha; dodec[15][1] = 0; dodec[15][2] = -beta;
278   dodec[16][0] = 0; dodec[16][1] = beta; dodec[16][2] = alpha;
279   dodec[17][0] = 0; dodec[17][1] = beta; dodec[17][2] = -alpha;
280   dodec[18][0] = 0; dodec[18][1] = -beta; dodec[18][2] = alpha;
281   dodec[19][0] = 0; dodec[19][1] = -beta; dodec[19][2] = -alpha;
282   /* *INDENT-ON* */
283
284 }
285
286 #define DIFF3(_a,_b,_c) { \
287     (_c)[0] = (_a)[0] - (_b)[0]; \
288     (_c)[1] = (_a)[1] - (_b)[1]; \
289     (_c)[2] = (_a)[2] - (_b)[2]; \
290 }
291
292 static void
293 crossprod(GLfloat v1[3], GLfloat v2[3], GLfloat prod[3])
294 {
295   GLfloat p[3];         /* in case prod == v1 or v2 */
296
297   p[0] = v1[1] * v2[2] - v2[1] * v1[2];
298   p[1] = v1[2] * v2[0] - v2[2] * v1[0];
299   p[2] = v1[0] * v2[1] - v2[0] * v1[1];
300   prod[0] = p[0];
301   prod[1] = p[1];
302   prod[2] = p[2];
303 }
304
305 static void
306 normalize(GLfloat v[3])
307 {
308   GLfloat d;
309
310   d = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
311   if (d == 0.0) {
312     /* __glutWarning("normalize: zero length vector"); */
313     v[0] = d = 1.0;
314   }
315   d = 1 / d;
316   v[0] *= d;
317   v[1] *= d;
318   v[2] *= d;
319 }
320
321 static void
322 pentagon(int a, int b, int c, int d, int e, GLenum shadeType)
323 {
324   GLfloat n0[3], d1[3], d2[3];
325
326   DIFF3(dodec[a], dodec[b], d1);
327   DIFF3(dodec[b], dodec[c], d2);
328   crossprod(d1, d2, n0);
329   normalize(n0);
330
331   glBegin(shadeType);
332   glNormal3fv(n0);
333   glVertex3fv(&dodec[a][0]);
334   glVertex3fv(&dodec[b][0]);
335   glVertex3fv(&dodec[c][0]);
336   glVertex3fv(&dodec[d][0]);
337   glVertex3fv(&dodec[e][0]);
338   glEnd();
339 }
340
341 static void
342 dodecahedron(GLenum type)
343 {
344   static int inited = 0;
345
346   if (inited == 0) {
347     inited = 1;
348     initDodecahedron();
349   }
350   pentagon(0, 1, 9, 16, 5, type);
351   pentagon(1, 0, 3, 18, 7, type);
352   pentagon(1, 7, 11, 10, 9, type);
353   pentagon(11, 7, 18, 19, 6, type);
354   pentagon(8, 17, 16, 9, 10, type);
355   pentagon(2, 14, 15, 6, 19, type);
356   pentagon(2, 13, 12, 4, 14, type);
357   pentagon(2, 19, 18, 3, 13, type);
358   pentagon(3, 0, 5, 12, 13, type);
359   pentagon(6, 15, 8, 10, 11, type);
360   pentagon(4, 17, 8, 15, 14, type);
361   pentagon(4, 12, 5, 16, 17, type);
362 }
363
364 /* CENTRY */
365 void APIENTRY
366 glutWireDodecahedron(void)
367 {
368   dodecahedron(GL_LINE_LOOP);
369 }
370
371 void APIENTRY
372 glutSolidDodecahedron(void)
373 {
374   dodecahedron(GL_TRIANGLE_FAN);
375 }
376
377 /* ENDCENTRY */
378
379 static void
380 recorditem(GLfloat * n1, GLfloat * n2, GLfloat * n3,
381   GLenum shadeType)
382 {
383   GLfloat q0[3], q1[3];
384
385   DIFF3(n1, n2, q0);
386   DIFF3(n2, n3, q1);
387   crossprod(q0, q1, q1);
388   normalize(q1);
389
390   glBegin(shadeType);
391   glNormal3fv(q1);
392   glVertex3fv(n1);
393   glVertex3fv(n2);
394   glVertex3fv(n3);
395   glEnd();
396 }
397
398 static void
399 subdivide(GLfloat * v0, GLfloat * v1, GLfloat * v2,
400   GLenum shadeType)
401 {
402   int depth;
403   GLfloat w0[3], w1[3], w2[3];
404   GLfloat l;
405   int i, j, k, n;
406
407   depth = 1;
408   for (i = 0; i < depth; i++) {
409     for (j = 0; i + j < depth; j++) {
410       k = depth - i - j;
411       for (n = 0; n < 3; n++) {
412         w0[n] = (i * v0[n] + j * v1[n] + k * v2[n]) / depth;
413         w1[n] = ((i + 1) * v0[n] + j * v1[n] + (k - 1) * v2[n])
414           / depth;
415         w2[n] = (i * v0[n] + (j + 1) * v1[n] + (k - 1) * v2[n])
416           / depth;
417       }
418       l = sqrt(w0[0] * w0[0] + w0[1] * w0[1] + w0[2] * w0[2]);
419       w0[0] /= l;
420       w0[1] /= l;
421       w0[2] /= l;
422       l = sqrt(w1[0] * w1[0] + w1[1] * w1[1] + w1[2] * w1[2]);
423       w1[0] /= l;
424       w1[1] /= l;
425       w1[2] /= l;
426       l = sqrt(w2[0] * w2[0] + w2[1] * w2[1] + w2[2] * w2[2]);
427       w2[0] /= l;
428       w2[1] /= l;
429       w2[2] /= l;
430       recorditem(w1, w0, w2, shadeType);
431     }
432   }
433 }
434
435 static void
436 drawtriangle(int i, GLfloat data[][3], int ndx[][3],
437   GLenum shadeType)
438 {
439   GLfloat *x0, *x1, *x2;
440
441   x0 = data[ndx[i][0]];
442   x1 = data[ndx[i][1]];
443   x2 = data[ndx[i][2]];
444   subdivide(x0, x1, x2, shadeType);
445 }
446
447 /* octahedron data: The octahedron produced is centered at the
448    origin and has radius 1.0 */
449 static GLfloat odata[6][3] =
450 {
451   {1.0, 0.0, 0.0},
452   {-1.0, 0.0, 0.0},
453   {0.0, 1.0, 0.0},
454   {0.0, -1.0, 0.0},
455   {0.0, 0.0, 1.0},
456   {0.0, 0.0, -1.0}
457 };
458
459 static int ondex[8][3] =
460 {
461   {0, 4, 2},
462   {1, 2, 4},
463   {0, 3, 4},
464   {1, 4, 3},
465   {0, 2, 5},
466   {1, 5, 2},
467   {0, 5, 3},
468   {1, 3, 5}
469 };
470
471 static void
472 octahedron(GLenum shadeType)
473 {
474   int i;
475
476   for (i = 7; i >= 0; i--) {
477     drawtriangle(i, odata, ondex, shadeType);
478   }
479 }
480
481 /* CENTRY */
482 void APIENTRY
483 glutWireOctahedron(void)
484 {
485   octahedron(GL_LINE_LOOP);
486 }
487
488 void APIENTRY
489 glutSolidOctahedron(void)
490 {
491   octahedron(GL_TRIANGLES);
492 }
493
494 /* ENDCENTRY */
495
496 /* icosahedron data: These numbers are rigged to make an
497    icosahedron of radius 1.0 */
498
499 #define X .525731112119133606
500 #define Z .850650808352039932
501
502 static GLfloat idata[12][3] =
503 {
504   {-X, 0, Z},
505   {X, 0, Z},
506   {-X, 0, -Z},
507   {X, 0, -Z},
508   {0, Z, X},
509   {0, Z, -X},
510   {0, -Z, X},
511   {0, -Z, -X},
512   {Z, X, 0},
513   {-Z, X, 0},
514   {Z, -X, 0},
515   {-Z, -X, 0}
516 };
517
518 static int index[20][3] =
519 {
520   {0, 4, 1},
521   {0, 9, 4},
522   {9, 5, 4},
523   {4, 5, 8},
524   {4, 8, 1},
525   {8, 10, 1},
526   {8, 3, 10},
527   {5, 3, 8},
528   {5, 2, 3},
529   {2, 7, 3},
530   {7, 10, 3},
531   {7, 6, 10},
532   {7, 11, 6},
533   {11, 0, 6},
534   {0, 1, 6},
535   {6, 1, 10},
536   {9, 0, 11},
537   {9, 11, 2},
538   {9, 2, 5},
539   {7, 2, 11},
540 };
541
542 static void
543 icosahedron(GLenum shadeType)
544 {
545   int i;
546
547   for (i = 19; i >= 0; i--) {
548     drawtriangle(i, idata, index, shadeType);
549   }
550 }
551
552 /* CENTRY */
553 void APIENTRY
554 glutWireIcosahedron(void)
555 {
556   icosahedron(GL_LINE_LOOP);
557 }
558
559 void APIENTRY
560 glutSolidIcosahedron(void)
561 {
562   icosahedron(GL_TRIANGLES);
563 }
564
565 /* ENDCENTRY */
566
567 /* tetrahedron data: */
568
569 #define T       1.73205080756887729
570
571 static GLfloat tdata[4][3] =
572 {
573   {T, T, T},
574   {T, -T, -T},
575   {-T, T, -T},
576   {-T, -T, T}
577 };
578
579 static int tndex[4][3] =
580 {
581   {0, 1, 3},
582   {2, 1, 0},
583   {3, 2, 0},
584   {1, 2, 3}
585 };
586
587 static void
588 tetrahedron(GLenum shadeType)
589 {
590   int i;
591
592   for (i = 3; i >= 0; i--)
593     drawtriangle(i, tdata, tndex, shadeType);
594 }
595
596 /* CENTRY */
597 void APIENTRY
598 glutWireTetrahedron(void)
599 {
600   tetrahedron(GL_LINE_LOOP);
601 }
602
603 void APIENTRY
604 glutSolidTetrahedron(void)
605 {
606   tetrahedron(GL_TRIANGLES);
607 }
608
609 /* ENDCENTRY */