Subversion Repositories shark

Rev

Rev 55 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
55 pj 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
#include <math.h>
48
#include <GL/gl.h>
49
#include <GL/glu.h>
50
#include "GL/glut.h"
51
 
52
/* Some <math.h> files do not define M_PI... */
53
#ifndef M_PI
54
#define M_PI 3.14159265358979323846
55
#endif
56
 
57
static GLUquadricObj *quadObj;
58
 
59
#define QUAD_OBJ_INIT() { if(!quadObj) initQuadObj(); }
60
 
61
static void
62
initQuadObj(void)
63
{
64
  quadObj = gluNewQuadric();
65
/*  if (!quadObj)
66
    __glutFatalError("out of memory."); */
67
}
68
 
69
/* CENTRY */
70
void APIENTRY
71
glutWireSphere(GLdouble radius, GLint slices, GLint stacks)
72
{
73
  QUAD_OBJ_INIT();
74
  gluQuadricDrawStyle(quadObj, GLU_LINE);
75
  gluQuadricNormals(quadObj, GLU_SMOOTH);
76
  /* If we ever changed/used the texture or orientation state
77
     of quadObj, we'd need to change it to the defaults here
78
     with gluQuadricTexture and/or gluQuadricOrientation. */
79
  gluSphere(quadObj, radius, slices, stacks);
80
}
81
 
82
void APIENTRY
83
glutSolidSphere(GLdouble radius, GLint slices, GLint stacks)
84
{
85
  QUAD_OBJ_INIT();
86
  gluQuadricDrawStyle(quadObj, GLU_FILL);
87
  gluQuadricNormals(quadObj, GLU_SMOOTH);
88
  /* If we ever changed/used the texture or orientation state
89
     of quadObj, we'd need to change it to the defaults here
90
     with gluQuadricTexture and/or gluQuadricOrientation. */
91
  gluSphere(quadObj, radius, slices, stacks);
92
}
93
 
94
void APIENTRY
95
glutWireCone(GLdouble base, GLdouble height,
96
  GLint slices, GLint stacks)
97
{
98
  QUAD_OBJ_INIT();
99
  gluQuadricDrawStyle(quadObj, GLU_LINE);
100
  gluQuadricNormals(quadObj, GLU_SMOOTH);
101
  /* If we ever changed/used the texture or orientation state
102
     of quadObj, we'd need to change it to the defaults here
103
     with gluQuadricTexture and/or gluQuadricOrientation. */
104
  gluCylinder(quadObj, base, 0.0, height, slices, stacks);
105
}
106
 
107
void APIENTRY
108
glutSolidCone(GLdouble base, GLdouble height,
109
  GLint slices, GLint stacks)
110
{
111
  QUAD_OBJ_INIT();
112
  gluQuadricDrawStyle(quadObj, GLU_FILL);
113
  gluQuadricNormals(quadObj, GLU_SMOOTH);
114
  /* If we ever changed/used the texture or orientation state
115
     of quadObj, we'd need to change it to the defaults here
116
     with gluQuadricTexture and/or gluQuadricOrientation. */
117
  gluCylinder(quadObj, base, 0.0, height, slices, stacks);
118
}
119
 
120
/* ENDCENTRY */
121
 
122
static void
123
drawBox(GLfloat size, GLenum type)
124
{
125
  static GLfloat n[6][3] =
126
  {
127
    {-1.0, 0.0, 0.0},
128
    {0.0, 1.0, 0.0},
129
    {1.0, 0.0, 0.0},
130
    {0.0, -1.0, 0.0},
131
    {0.0, 0.0, 1.0},
132
    {0.0, 0.0, -1.0}
133
  };
134
  static GLint faces[6][4] =
135
  {
136
    {0, 1, 2, 3},
137
    {3, 2, 6, 7},
138
    {7, 6, 5, 4},
139
    {4, 5, 1, 0},
140
    {5, 6, 2, 1},
141
    {7, 4, 0, 3}
142
  };
143
  GLfloat v[8][3];
144
  GLint i;
145
 
146
  v[0][0] = v[1][0] = v[2][0] = v[3][0] = -size / 2;
147
  v[4][0] = v[5][0] = v[6][0] = v[7][0] = size / 2;
148
  v[0][1] = v[1][1] = v[4][1] = v[5][1] = -size / 2;
149
  v[2][1] = v[3][1] = v[6][1] = v[7][1] = size / 2;
150
  v[0][2] = v[3][2] = v[4][2] = v[7][2] = -size / 2;
151
  v[1][2] = v[2][2] = v[5][2] = v[6][2] = size / 2;
152
 
153
  for (i = 5; i >= 0; i--) {
154
    glBegin(type);
155
    glNormal3fv(&n[i][0]);
156
    glVertex3fv(&v[faces[i][0]][0]);
157
    glVertex3fv(&v[faces[i][1]][0]);
158
    glVertex3fv(&v[faces[i][2]][0]);
159
    glVertex3fv(&v[faces[i][3]][0]);
160
    glEnd();
161
  }
162
}
163
 
164
/* CENTRY */
165
void APIENTRY
166
glutWireCube(GLdouble size)
167
{
168
  drawBox(size, GL_LINE_LOOP);
169
}
170
 
171
void APIENTRY
172
glutSolidCube(GLdouble size)
173
{
174
  drawBox(size, GL_QUADS);
175
}
176
 
177
/* ENDCENTRY */
178
 
179
static void
180
doughnut(GLfloat r, GLfloat R, GLint nsides, GLint rings)
181
{
182
  int i, j;
183
  GLfloat theta, phi, theta1;
184
  GLfloat cosTheta, sinTheta;
185
  GLfloat cosTheta1, sinTheta1;
186
  GLfloat ringDelta, sideDelta;
187
 
188
  ringDelta = 2.0 * M_PI / rings;
189
  sideDelta = 2.0 * M_PI / nsides;
190
 
191
  theta = 0.0;
192
  cosTheta = 1.0;
193
  sinTheta = 0.0;
194
  for (i = rings - 1; i >= 0; i--) {
195
    theta1 = theta + ringDelta;
196
    cosTheta1 = cos(theta1);
197
    sinTheta1 = sin(theta1);
198
    glBegin(GL_QUAD_STRIP);
199
    phi = 0.0;
200
    for (j = nsides; j >= 0; j--) {
201
      GLfloat cosPhi, sinPhi, dist;
202
 
203
      phi += sideDelta;
204
      cosPhi = cos(phi);
205
      sinPhi = sin(phi);
206
      dist = R + r * cosPhi;
207
 
208
      glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
209
      glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
210
      glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
211
      glVertex3f(cosTheta * dist, -sinTheta * dist,  r * sinPhi);
212
    }
213
    glEnd();
214
    theta = theta1;
215
    cosTheta = cosTheta1;
216
    sinTheta = sinTheta1;
217
  }
218
}
219
 
220
/* CENTRY */
221
void APIENTRY
222
glutWireTorus(GLdouble innerRadius, GLdouble outerRadius,
223
  GLint nsides, GLint rings)
224
{
225
  glPushAttrib(GL_POLYGON_BIT);
226
  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
227
  doughnut(innerRadius, outerRadius, nsides, rings);
228
  glPopAttrib();
229
}
230
 
231
void APIENTRY
232
glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius,
233
  GLint nsides, GLint rings)
234
{
235
  doughnut(innerRadius, outerRadius, nsides, rings);
236
}
237
 
238
/* ENDCENTRY */
239
 
240
static GLfloat dodec[20][3];
241
 
242
static void
243
initDodecahedron(void)
244
{
245
  GLfloat alpha, beta;
246
 
247
  alpha = sqrt(2.0 / (3.0 + sqrt(5.0)));
248
  beta = 1.0 + sqrt(6.0 / (3.0 + sqrt(5.0)) -
249
    2.0 + 2.0 * sqrt(2.0 / (3.0 + sqrt(5.0))));
250
  /* *INDENT-OFF* */
251
  dodec[0][0] = -alpha; dodec[0][1] = 0; dodec[0][2] = beta;
252
  dodec[1][0] = alpha; dodec[1][1] = 0; dodec[1][2] = beta;
253
  dodec[2][0] = -1; dodec[2][1] = -1; dodec[2][2] = -1;
254
  dodec[3][0] = -1; dodec[3][1] = -1; dodec[3][2] = 1;
255
  dodec[4][0] = -1; dodec[4][1] = 1; dodec[4][2] = -1;
256
  dodec[5][0] = -1; dodec[5][1] = 1; dodec[5][2] = 1;
257
  dodec[6][0] = 1; dodec[6][1] = -1; dodec[6][2] = -1;
258
  dodec[7][0] = 1; dodec[7][1] = -1; dodec[7][2] = 1;
259
  dodec[8][0] = 1; dodec[8][1] = 1; dodec[8][2] = -1;
260
  dodec[9][0] = 1; dodec[9][1] = 1; dodec[9][2] = 1;
261
  dodec[10][0] = beta; dodec[10][1] = alpha; dodec[10][2] = 0;
262
  dodec[11][0] = beta; dodec[11][1] = -alpha; dodec[11][2] = 0;
263
  dodec[12][0] = -beta; dodec[12][1] = alpha; dodec[12][2] = 0;
264
  dodec[13][0] = -beta; dodec[13][1] = -alpha; dodec[13][2] = 0;
265
  dodec[14][0] = -alpha; dodec[14][1] = 0; dodec[14][2] = -beta;
266
  dodec[15][0] = alpha; dodec[15][1] = 0; dodec[15][2] = -beta;
267
  dodec[16][0] = 0; dodec[16][1] = beta; dodec[16][2] = alpha;
268
  dodec[17][0] = 0; dodec[17][1] = beta; dodec[17][2] = -alpha;
269
  dodec[18][0] = 0; dodec[18][1] = -beta; dodec[18][2] = alpha;
270
  dodec[19][0] = 0; dodec[19][1] = -beta; dodec[19][2] = -alpha;
271
  /* *INDENT-ON* */
272
 
273
}
274
 
183 giacomo 275
#define DIFF3(_a,_b,_c) {(_c)[0] = (_a)[0] - (_b)[0]; (_c)[1] = (_a)[1] - (_b)[1]; (_c)[2] = (_a)[2] - (_b)[2];}
55 pj 276
 
277
static void
278
crossprod(GLfloat v1[3], GLfloat v2[3], GLfloat prod[3])
279
{
280
  GLfloat p[3];         /* in case prod == v1 or v2 */
281
 
282
  p[0] = v1[1] * v2[2] - v2[1] * v1[2];
283
  p[1] = v1[2] * v2[0] - v2[2] * v1[0];
284
  p[2] = v1[0] * v2[1] - v2[0] * v1[1];
285
  prod[0] = p[0];
286
  prod[1] = p[1];
287
  prod[2] = p[2];
288
}
289
 
290
static void
291
normalize(GLfloat v[3])
292
{
293
  GLfloat d;
294
 
295
  d = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
296
  if (d == 0.0) {
297
//    __glutWarning("normalize: zero length vector");
298
    v[0] = d = 1.0;
299
  }
300
  d = 1 / d;
301
  v[0] *= d;
302
  v[1] *= d;
303
  v[2] *= d;
304
}
305
 
306
static void
307
pentagon(int a, int b, int c, int d, int e, GLenum shadeType)
308
{
309
  GLfloat n0[3], d1[3], d2[3];
310
 
311
  DIFF3(dodec[a], dodec[b], d1);
312
  DIFF3(dodec[b], dodec[c], d2);
313
  crossprod(d1, d2, n0);
314
  normalize(n0);
315
 
316
  glBegin(shadeType);
317
  glNormal3fv(n0);
318
  glVertex3fv(&dodec[a][0]);
319
  glVertex3fv(&dodec[b][0]);
320
  glVertex3fv(&dodec[c][0]);
321
  glVertex3fv(&dodec[d][0]);
322
  glVertex3fv(&dodec[e][0]);
323
  glEnd();
324
}
325
 
326
static void
327
dodecahedron(GLenum type)
328
{
329
  static int inited = 0;
330
 
331
  if (inited == 0) {
332
    inited = 1;
333
    initDodecahedron();
334
  }
335
  pentagon(0, 1, 9, 16, 5, type);
336
  pentagon(1, 0, 3, 18, 7, type);
337
  pentagon(1, 7, 11, 10, 9, type);
338
  pentagon(11, 7, 18, 19, 6, type);
339
  pentagon(8, 17, 16, 9, 10, type);
340
  pentagon(2, 14, 15, 6, 19, type);
341
  pentagon(2, 13, 12, 4, 14, type);
342
  pentagon(2, 19, 18, 3, 13, type);
343
  pentagon(3, 0, 5, 12, 13, type);
344
  pentagon(6, 15, 8, 10, 11, type);
345
  pentagon(4, 17, 8, 15, 14, type);
346
  pentagon(4, 12, 5, 16, 17, type);
347
}
348
 
349
/* CENTRY */
350
void APIENTRY
351
glutWireDodecahedron(void)
352
{
353
  dodecahedron(GL_LINE_LOOP);
354
}
355
 
356
void APIENTRY
357
glutSolidDodecahedron(void)
358
{
359
  dodecahedron(GL_TRIANGLE_FAN);
360
}
361
 
362
/* ENDCENTRY */
363
 
364
static void
365
recorditem(GLfloat * n1, GLfloat * n2, GLfloat * n3,
366
  GLenum shadeType)
367
{
368
  GLfloat q0[3], q1[3];
369
 
370
  DIFF3(n1, n2, q0);
371
  DIFF3(n2, n3, q1);
372
  crossprod(q0, q1, q1);
373
  normalize(q1);
374
 
375
  glBegin(shadeType);
376
  glNormal3fv(q1);
377
  glVertex3fv(n1);
378
  glVertex3fv(n2);
379
  glVertex3fv(n3);
380
  glEnd();
381
}
382
 
383
static void
384
subdivide(GLfloat * v0, GLfloat * v1, GLfloat * v2,
385
  GLenum shadeType)
386
{
387
  int depth;
388
  GLfloat w0[3], w1[3], w2[3];
389
  GLfloat l;
390
  int i, j, k, n;
391
 
392
  depth = 1;
393
  for (i = 0; i < depth; i++) {
394
    for (j = 0; i + j < depth; j++) {
395
      k = depth - i - j;
396
      for (n = 0; n < 3; n++) {
397
        w0[n] = (i * v0[n] + j * v1[n] + k * v2[n]) / depth;
398
        w1[n] = ((i + 1) * v0[n] + j * v1[n] + (k - 1) * v2[n])
399
          / depth;
400
        w2[n] = (i * v0[n] + (j + 1) * v1[n] + (k - 1) * v2[n])
401
          / depth;
402
      }
403
      l = sqrt(w0[0] * w0[0] + w0[1] * w0[1] + w0[2] * w0[2]);
404
      w0[0] /= l;
405
      w0[1] /= l;
406
      w0[2] /= l;
407
      l = sqrt(w1[0] * w1[0] + w1[1] * w1[1] + w1[2] * w1[2]);
408
      w1[0] /= l;
409
      w1[1] /= l;
410
      w1[2] /= l;
411
      l = sqrt(w2[0] * w2[0] + w2[1] * w2[1] + w2[2] * w2[2]);
412
      w2[0] /= l;
413
      w2[1] /= l;
414
      w2[2] /= l;
415
      recorditem(w1, w0, w2, shadeType);
416
    }
417
  }
418
}
419
 
420
static void
421
drawtriangle(int i, GLfloat data[][3], int ndx[][3],
422
  GLenum shadeType)
423
{
424
  GLfloat *x0, *x1, *x2;
425
 
426
  x0 = data[ndx[i][0]];
427
  x1 = data[ndx[i][1]];
428
  x2 = data[ndx[i][2]];
429
  subdivide(x0, x1, x2, shadeType);
430
}
431
 
432
/* octahedron data: The octahedron produced is centered at the
433
   origin and has radius 1.0 */
434
static GLfloat odata[6][3] =
435
{
436
  {1.0, 0.0, 0.0},
437
  {-1.0, 0.0, 0.0},
438
  {0.0, 1.0, 0.0},
439
  {0.0, -1.0, 0.0},
440
  {0.0, 0.0, 1.0},
441
  {0.0, 0.0, -1.0}
442
};
443
 
444
static int ondex[8][3] =
445
{
446
  {0, 4, 2},
447
  {1, 2, 4},
448
  {0, 3, 4},
449
  {1, 4, 3},
450
  {0, 2, 5},
451
  {1, 5, 2},
452
  {0, 5, 3},
453
  {1, 3, 5}
454
};
455
 
456
static void
457
octahedron(GLenum shadeType)
458
{
459
  int i;
460
 
461
  for (i = 7; i >= 0; i--) {
462
    drawtriangle(i, odata, ondex, shadeType);
463
  }
464
}
465
 
466
/* CENTRY */
467
void APIENTRY
468
glutWireOctahedron(void)
469
{
470
  octahedron(GL_LINE_LOOP);
471
}
472
 
473
void APIENTRY
474
glutSolidOctahedron(void)
475
{
476
  octahedron(GL_TRIANGLES);
477
}
478
 
479
/* ENDCENTRY */
480
 
481
/* icosahedron data: These numbers are rigged to make an
482
   icosahedron of radius 1.0 */
483
 
484
#define X .525731112119133606
485
#define Z .850650808352039932
486
 
487
static GLfloat idata[12][3] =
488
{
489
  {-X, 0, Z},
490
  {X, 0, Z},
491
  {-X, 0, -Z},
492
  {X, 0, -Z},
493
  {0, Z, X},
494
  {0, Z, -X},
495
  {0, -Z, X},
496
  {0, -Z, -X},
497
  {Z, X, 0},
498
  {-Z, X, 0},
499
  {Z, -X, 0},
500
  {-Z, -X, 0}
501
};
502
 
503
static int index[20][3] =
504
{
505
  {0, 4, 1},
506
  {0, 9, 4},
507
  {9, 5, 4},
508
  {4, 5, 8},
509
  {4, 8, 1},
510
  {8, 10, 1},
511
  {8, 3, 10},
512
  {5, 3, 8},
513
  {5, 2, 3},
514
  {2, 7, 3},
515
  {7, 10, 3},
516
  {7, 6, 10},
517
  {7, 11, 6},
518
  {11, 0, 6},
519
  {0, 1, 6},
520
  {6, 1, 10},
521
  {9, 0, 11},
522
  {9, 11, 2},
523
  {9, 2, 5},
524
  {7, 2, 11},
525
};
526
 
527
static void
528
icosahedron(GLenum shadeType)
529
{
530
  int i;
531
 
532
  for (i = 19; i >= 0; i--) {
533
    drawtriangle(i, idata, index, shadeType);
534
  }
535
}
536
 
537
/* CENTRY */
538
void APIENTRY
539
glutWireIcosahedron(void)
540
{
541
  icosahedron(GL_LINE_LOOP);
542
}
543
 
544
void APIENTRY
545
glutSolidIcosahedron(void)
546
{
547
  icosahedron(GL_TRIANGLES);
548
}
549
 
550
/* ENDCENTRY */
551
 
552
/* tetrahedron data: */
553
 
554
#define T       1.73205080756887729
555
 
556
static GLfloat tdata[4][3] =
557
{
558
  {T, T, T},
559
  {T, -T, -T},
560
  {-T, T, -T},
561
  {-T, -T, T}
562
};
563
 
564
static int tndex[4][3] =
565
{
566
  {0, 1, 3},
567
  {2, 1, 0},
568
  {3, 2, 0},
569
  {1, 2, 3}
570
};
571
 
572
static void
573
tetrahedron(GLenum shadeType)
574
{
575
  int i;
576
 
577
  for (i = 3; i >= 0; i--)
578
    drawtriangle(i, tdata, tndex, shadeType);
579
}
580
 
581
/* CENTRY */
582
void APIENTRY
583
glutWireTetrahedron(void)
584
{
585
  tetrahedron(GL_LINE_LOOP);
586
}
587
 
588
void APIENTRY
589
glutSolidTetrahedron(void)
590
{
591
  tetrahedron(GL_TRIANGLES);
592
}
593
 
594
/* ENDCENTRY */