2 * Copyright 1994-1997 Mark Kilgard, All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * GPL licensing not permitted.
12 (c) Copyright 1993, Silicon Graphics, Inc.
16 Permission to use, copy, modify, and distribute this software
17 for any purpose and without fee is hereby granted, provided
18 that the above copyright notice appear in all copies and that
19 both the copyright notice and this permission notice appear in
20 supporting documentation, and that the name of Silicon
21 Graphics, Inc. not be used in advertising or publicity
22 pertaining to distribution of the software without specific,
23 written prior permission.
25 THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU
26 "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR
27 OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
28 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO
29 EVENT SHALL SILICON GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE
30 ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR
31 CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER,
32 INCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE,
33 SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR
34 NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF THE POSSIBILITY
35 OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
36 ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE OR
37 PERFORMANCE OF THIS SOFTWARE.
39 US Government Users Restricted Rights
41 Use, duplication, or disclosure by the Government is subject to
42 restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
43 (c)(1)(ii) of the Rights in Technical Data and Computer
44 Software clause at DFARS 252.227-7013 and/or in similar or
45 successor clauses in the FAR or the DOD or NASA FAR
46 Supplement. Unpublished-- rights reserved under the copyright
47 laws of the United States. Contractor/manufacturer is Silicon
48 Graphics, Inc., 2011 N. Shoreline Blvd., Mountain View, CA
51 OpenGL(TM) is a trademark of Silicon Graphics, Inc.
57 /* Some <math.h> files do not define M_PI... */
59 #define M_PI 3.14159265358979323846
62 static GLUquadricObj
*quadObj
;
64 #define QUAD_OBJ_INIT() { if(!quadObj) initQuadObj(); }
69 quadObj
= gluNewQuadric();
71 __glutFatalError("out of memory.");
76 glutWireSphere(GLdouble radius
, GLint slices
, GLint stacks
)
79 gluQuadricDrawStyle(quadObj
, GLU_LINE
);
80 gluQuadricNormals(quadObj
, GLU_SMOOTH
);
81 /* If we ever changed/used the texture or orientation state
82 of quadObj, we'd need to change it to the defaults here
83 with gluQuadricTexture and/or gluQuadricOrientation. */
84 gluSphere(quadObj
, radius
, slices
, stacks
);
88 glutSolidSphere(GLdouble radius
, GLint slices
, GLint stacks
)
91 gluQuadricDrawStyle(quadObj
, GLU_FILL
);
92 gluQuadricNormals(quadObj
, GLU_SMOOTH
);
93 /* If we ever changed/used the texture or orientation state
94 of quadObj, we'd need to change it to the defaults here
95 with gluQuadricTexture and/or gluQuadricOrientation. */
96 gluSphere(quadObj
, radius
, slices
, stacks
);
100 glutWireCone(GLdouble base
, GLdouble height
,
101 GLint slices
, GLint stacks
)
104 gluQuadricDrawStyle(quadObj
, GLU_LINE
);
105 gluQuadricNormals(quadObj
, GLU_SMOOTH
);
106 /* If we ever changed/used the texture or orientation state
107 of quadObj, we'd need to change it to the defaults here
108 with gluQuadricTexture and/or gluQuadricOrientation. */
109 gluCylinder(quadObj
, base
, 0.0, height
, slices
, stacks
);
113 glutSolidCone(GLdouble base
, GLdouble height
,
114 GLint slices
, GLint stacks
)
117 gluQuadricDrawStyle(quadObj
, GLU_FILL
);
118 gluQuadricNormals(quadObj
, GLU_SMOOTH
);
119 /* If we ever changed/used the texture or orientation state
120 of quadObj, we'd need to change it to the defaults here
121 with gluQuadricTexture and/or gluQuadricOrientation. */
122 gluCylinder(quadObj
, base
, 0.0, height
, slices
, stacks
);
128 drawBox(GLfloat size
, GLenum type
)
130 static GLfloat n
[6][3] =
139 static GLint faces
[6][4] =
151 v
[0][0] = v
[1][0] = v
[2][0] = v
[3][0] = -size
/ 2;
152 v
[4][0] = v
[5][0] = v
[6][0] = v
[7][0] = size
/ 2;
153 v
[0][1] = v
[1][1] = v
[4][1] = v
[5][1] = -size
/ 2;
154 v
[2][1] = v
[3][1] = v
[6][1] = v
[7][1] = size
/ 2;
155 v
[0][2] = v
[3][2] = v
[4][2] = v
[7][2] = -size
/ 2;
156 v
[1][2] = v
[2][2] = v
[5][2] = v
[6][2] = size
/ 2;
158 for (i
= 5; i
>= 0; i
--) {
160 glNormal3fv(&n
[i
][0]);
161 glVertex3fv(&v
[faces
[i
][0]][0]);
162 glVertex3fv(&v
[faces
[i
][1]][0]);
163 glVertex3fv(&v
[faces
[i
][2]][0]);
164 glVertex3fv(&v
[faces
[i
][3]][0]);
171 glutWireCube(GLdouble size
)
173 drawBox(size
, GL_LINE_LOOP
);
177 glutSolidCube(GLdouble size
)
179 drawBox(size
, GL_QUADS
);
185 doughnut(GLfloat r
, GLfloat R
, GLint nsides
, GLint rings
)
188 GLfloat theta
, phi
, theta1
;
189 GLfloat cosTheta
, sinTheta
;
190 GLfloat cosTheta1
, sinTheta1
;
191 GLfloat ringDelta
, sideDelta
;
193 ringDelta
= 2.0 * M_PI
/ rings
;
194 sideDelta
= 2.0 * M_PI
/ nsides
;
199 for (i
= rings
- 1; i
>= 0; i
--) {
200 theta1
= theta
+ ringDelta
;
201 cosTheta1
= cos(theta1
);
202 sinTheta1
= sin(theta1
);
203 glBegin(GL_QUAD_STRIP
);
205 for (j
= nsides
; j
>= 0; j
--) {
206 GLfloat cosPhi
, sinPhi
, dist
;
211 dist
= R
+ r
* cosPhi
;
213 glNormal3f(cosTheta1
* cosPhi
, -sinTheta1
* cosPhi
, sinPhi
);
214 glVertex3f(cosTheta1
* dist
, -sinTheta1
* dist
, r
* sinPhi
);
215 glNormal3f(cosTheta
* cosPhi
, -sinTheta
* cosPhi
, sinPhi
);
216 glVertex3f(cosTheta
* dist
, -sinTheta
* dist
, r
* sinPhi
);
220 cosTheta
= cosTheta1
;
221 sinTheta
= sinTheta1
;
227 glutWireTorus(GLdouble innerRadius
, GLdouble outerRadius
,
228 GLint nsides
, GLint rings
)
230 glPushAttrib(GL_POLYGON_BIT
);
231 glPolygonMode(GL_FRONT_AND_BACK
, GL_LINE
);
232 doughnut(innerRadius
, outerRadius
, nsides
, rings
);
237 glutSolidTorus(GLdouble innerRadius
, GLdouble outerRadius
,
238 GLint nsides
, GLint rings
)
240 doughnut(innerRadius
, outerRadius
, nsides
, rings
);
245 static GLfloat dodec
[20][3];
248 initDodecahedron(void)
252 alpha
= sqrt(2.0 / (3.0 + sqrt(5.0)));
253 beta
= 1.0 + sqrt(6.0 / (3.0 + sqrt(5.0)) -
254 2.0 + 2.0 * sqrt(2.0 / (3.0 + sqrt(5.0))));
256 dodec
[0][0] = -alpha
; dodec
[0][1] = 0; dodec
[0][2] = beta
;
257 dodec
[1][0] = alpha
; dodec
[1][1] = 0; dodec
[1][2] = beta
;
258 dodec
[2][0] = -1; dodec
[2][1] = -1; dodec
[2][2] = -1;
259 dodec
[3][0] = -1; dodec
[3][1] = -1; dodec
[3][2] = 1;
260 dodec
[4][0] = -1; dodec
[4][1] = 1; dodec
[4][2] = -1;
261 dodec
[5][0] = -1; dodec
[5][1] = 1; dodec
[5][2] = 1;
262 dodec
[6][0] = 1; dodec
[6][1] = -1; dodec
[6][2] = -1;
263 dodec
[7][0] = 1; dodec
[7][1] = -1; dodec
[7][2] = 1;
264 dodec
[8][0] = 1; dodec
[8][1] = 1; dodec
[8][2] = -1;
265 dodec
[9][0] = 1; dodec
[9][1] = 1; dodec
[9][2] = 1;
266 dodec
[10][0] = beta
; dodec
[10][1] = alpha
; dodec
[10][2] = 0;
267 dodec
[11][0] = beta
; dodec
[11][1] = -alpha
; dodec
[11][2] = 0;
268 dodec
[12][0] = -beta
; dodec
[12][1] = alpha
; dodec
[12][2] = 0;
269 dodec
[13][0] = -beta
; dodec
[13][1] = -alpha
; dodec
[13][2] = 0;
270 dodec
[14][0] = -alpha
; dodec
[14][1] = 0; dodec
[14][2] = -beta
;
271 dodec
[15][0] = alpha
; dodec
[15][1] = 0; dodec
[15][2] = -beta
;
272 dodec
[16][0] = 0; dodec
[16][1] = beta
; dodec
[16][2] = alpha
;
273 dodec
[17][0] = 0; dodec
[17][1] = beta
; dodec
[17][2] = -alpha
;
274 dodec
[18][0] = 0; dodec
[18][1] = -beta
; dodec
[18][2] = alpha
;
275 dodec
[19][0] = 0; dodec
[19][1] = -beta
; dodec
[19][2] = -alpha
;
280 #define DIFF3(_a,_b,_c) { \
281 (_c)[0] = (_a)[0] - (_b)[0]; \
282 (_c)[1] = (_a)[1] - (_b)[1]; \
283 (_c)[2] = (_a)[2] - (_b)[2]; \
287 crossprod(GLfloat v1
[3], GLfloat v2
[3], GLfloat prod
[3])
289 GLfloat p
[3]; /* in case prod == v1 or v2 */
291 p
[0] = v1
[1] * v2
[2] - v2
[1] * v1
[2];
292 p
[1] = v1
[2] * v2
[0] - v2
[2] * v1
[0];
293 p
[2] = v1
[0] * v2
[1] - v2
[0] * v1
[1];
300 normalize(GLfloat v
[3])
304 d
= sqrt(v
[0] * v
[0] + v
[1] * v
[1] + v
[2] * v
[2]);
306 __glutWarning("normalize: zero length vector");
316 pentagon(int a
, int b
, int c
, int d
, int e
, GLenum shadeType
)
318 GLfloat n0
[3], d1
[3], d2
[3];
320 DIFF3(dodec
[a
], dodec
[b
], d1
);
321 DIFF3(dodec
[b
], dodec
[c
], d2
);
322 crossprod(d1
, d2
, n0
);
327 glVertex3fv(&dodec
[a
][0]);
328 glVertex3fv(&dodec
[b
][0]);
329 glVertex3fv(&dodec
[c
][0]);
330 glVertex3fv(&dodec
[d
][0]);
331 glVertex3fv(&dodec
[e
][0]);
336 dodecahedron(GLenum type
)
338 static int inited
= 0;
344 pentagon(0, 1, 9, 16, 5, type
);
345 pentagon(1, 0, 3, 18, 7, type
);
346 pentagon(1, 7, 11, 10, 9, type
);
347 pentagon(11, 7, 18, 19, 6, type
);
348 pentagon(8, 17, 16, 9, 10, type
);
349 pentagon(2, 14, 15, 6, 19, type
);
350 pentagon(2, 13, 12, 4, 14, type
);
351 pentagon(2, 19, 18, 3, 13, type
);
352 pentagon(3, 0, 5, 12, 13, type
);
353 pentagon(6, 15, 8, 10, 11, type
);
354 pentagon(4, 17, 8, 15, 14, type
);
355 pentagon(4, 12, 5, 16, 17, type
);
360 glutWireDodecahedron(void)
362 dodecahedron(GL_LINE_LOOP
);
366 glutSolidDodecahedron(void)
368 dodecahedron(GL_TRIANGLE_FAN
);
374 recorditem(GLfloat
* n1
, GLfloat
* n2
, GLfloat
* n3
,
377 GLfloat q0
[3], q1
[3];
381 crossprod(q0
, q1
, q1
);
393 subdivide(GLfloat
* v0
, GLfloat
* v1
, GLfloat
* v2
,
397 GLfloat w0
[3], w1
[3], w2
[3];
402 for (i
= 0; i
< depth
; i
++) {
403 for (j
= 0; i
+ j
< depth
; j
++) {
405 for (n
= 0; n
< 3; n
++) {
406 w0
[n
] = (i
* v0
[n
] + j
* v1
[n
] + k
* v2
[n
]) / depth
;
407 w1
[n
] = ((i
+ 1) * v0
[n
] + j
* v1
[n
] + (k
- 1) * v2
[n
])
409 w2
[n
] = (i
* v0
[n
] + (j
+ 1) * v1
[n
] + (k
- 1) * v2
[n
])
412 l
= sqrt(w0
[0] * w0
[0] + w0
[1] * w0
[1] + w0
[2] * w0
[2]);
416 l
= sqrt(w1
[0] * w1
[0] + w1
[1] * w1
[1] + w1
[2] * w1
[2]);
420 l
= sqrt(w2
[0] * w2
[0] + w2
[1] * w2
[1] + w2
[2] * w2
[2]);
424 recorditem(w1
, w0
, w2
, shadeType
);
430 drawtriangle(int i
, GLfloat data
[][3], int ndx
[][3],
433 GLfloat
*x0
, *x1
, *x2
;
435 x0
= data
[ndx
[i
][0]];
436 x1
= data
[ndx
[i
][1]];
437 x2
= data
[ndx
[i
][2]];
438 subdivide(x0
, x1
, x2
, shadeType
);
441 /* octahedron data: The octahedron produced is centered at the
442 origin and has radius 1.0 */
443 static GLfloat odata
[6][3] =
453 static int ondex
[8][3] =
466 octahedron(GLenum shadeType
)
470 for (i
= 7; i
>= 0; i
--) {
471 drawtriangle(i
, odata
, ondex
, shadeType
);
477 glutWireOctahedron(void)
479 octahedron(GL_LINE_LOOP
);
483 glutSolidOctahedron(void)
485 octahedron(GL_TRIANGLES
);
490 /* icosahedron data: These numbers are rigged to make an
491 icosahedron of radius 1.0 */
493 #define X .525731112119133606
494 #define Z .850650808352039932
496 static GLfloat idata
[12][3] =
512 static int iIndex
[20][3] =
537 icosahedron(GLenum shadeType
)
541 for (i
= 19; i
>= 0; i
--) {
542 drawtriangle(i
, idata
, iIndex
, shadeType
);
548 glutWireIcosahedron(void)
550 icosahedron(GL_LINE_LOOP
);
554 glutSolidIcosahedron(void)
556 icosahedron(GL_TRIANGLES
);
561 /* tetrahedron data: */
563 #define T 1.73205080756887729
565 static GLfloat tdata
[4][3] =
573 static int tndex
[4][3] =
582 tetrahedron(GLenum shadeType
)
586 for (i
= 3; i
>= 0; i
--)
587 drawtriangle(i
, tdata
, tndex
, shadeType
);
592 glutWireTetrahedron(void)
594 tetrahedron(GL_LINE_LOOP
);
598 glutSolidTetrahedron(void)
600 tetrahedron(GL_TRIANGLES
);