2 ** License Applicability. Except to the extent portions of this file are
3 ** made subject to an alternative license as permitted in the SGI Free
4 ** Software License B, Version 1.1 (the "License"), the contents of this
5 ** file are subject only to the provisions of the License. You may not use
6 ** this file except in compliance with the License. You may obtain a copy
7 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
8 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
10 ** http://oss.sgi.com/projects/FreeB
12 ** Note that, as provided in the License, the Software is distributed on an
13 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
14 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
15 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
16 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
18 ** Original Code. The Original Code is: OpenGL Sample Implementation,
19 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
20 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
21 ** Copyright in any portions created by third parties is as indicated
22 ** elsewhere herein. All Rights Reserved.
24 ** Additional Notice Provisions: The application programming interfaces
25 ** established by SGI in conjunction with the Original Code are The
26 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
27 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
28 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
29 ** Window System(R) (Version 1.3), released October 19, 1998. This software
30 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
31 ** published by SGI, but has not been independently verified as being
32 ** compliant with the OpenGL(R) version 1.2.1 Specification.
44 /* Make it not a power of two to avoid cache thrashing on the chip */
45 #define CACHE_SIZE 240
48 #define PI 3.14159265358979323846
52 GLboolean textureCoords
;
55 void (GLAPIENTRY
*errorCallback
)( GLint
);
58 GLUquadric
* GLAPIENTRY
63 newstate
= (GLUquadric
*) malloc(sizeof(GLUquadric
));
64 if (newstate
== NULL
) {
65 /* Can't report an error at this point... */
68 newstate
->normals
= GLU_SMOOTH
;
69 newstate
->textureCoords
= GL_FALSE
;
70 newstate
->orientation
= GLU_OUTSIDE
;
71 newstate
->drawStyle
= GLU_FILL
;
72 newstate
->errorCallback
= NULL
;
78 gluDeleteQuadric(GLUquadric
*state
)
83 static void gluQuadricError(GLUquadric
*qobj
, GLenum which
)
85 if (qobj
->errorCallback
) {
86 qobj
->errorCallback(which
);
91 gluQuadricCallback(GLUquadric
*qobj
, GLenum which
, _GLUfuncptr fn
)
95 qobj
->errorCallback
= (void (GLAPIENTRY
*)(GLint
)) fn
;
98 gluQuadricError(qobj
, GLU_INVALID_ENUM
);
104 gluQuadricNormals(GLUquadric
*qobj
, GLenum normals
)
112 gluQuadricError(qobj
, GLU_INVALID_ENUM
);
115 qobj
->normals
= normals
;
119 gluQuadricTexture(GLUquadric
*qobj
, GLboolean textureCoords
)
121 qobj
->textureCoords
= textureCoords
;
125 gluQuadricOrientation(GLUquadric
*qobj
, GLenum orientation
)
127 switch(orientation
) {
132 gluQuadricError(qobj
, GLU_INVALID_ENUM
);
135 qobj
->orientation
= orientation
;
139 gluQuadricDrawStyle(GLUquadric
*qobj
, GLenum drawStyle
)
148 gluQuadricError(qobj
, GLU_INVALID_ENUM
);
151 qobj
->drawStyle
= drawStyle
;
155 gluCylinder(GLUquadric
*qobj
, GLdouble baseRadius
, GLdouble topRadius
,
156 GLdouble height
, GLint slices
, GLint stacks
)
159 GLfloat sinCache
[CACHE_SIZE
];
160 GLfloat cosCache
[CACHE_SIZE
];
161 GLfloat sinCache2
[CACHE_SIZE
];
162 GLfloat cosCache2
[CACHE_SIZE
];
163 GLfloat sinCache3
[CACHE_SIZE
];
164 GLfloat cosCache3
[CACHE_SIZE
];
167 GLfloat sintemp
, costemp
;
171 GLfloat xyNormalRatio
;
172 GLfloat radiusLow
, radiusHigh
;
173 int needCache2
, needCache3
;
175 if (slices
>= CACHE_SIZE
) slices
= CACHE_SIZE
-1;
177 if (slices
< 2 || stacks
< 1 || baseRadius
< 0.0 || topRadius
< 0.0 ||
179 gluQuadricError(qobj
, GLU_INVALID_VALUE
);
183 /* Compute length (needed for normal calculations) */
184 deltaRadius
= baseRadius
- topRadius
;
185 length
= SQRT(deltaRadius
*deltaRadius
+ height
*height
);
187 gluQuadricError(qobj
, GLU_INVALID_VALUE
);
191 /* Cache is the vertex locations cache */
192 /* Cache2 is the various normals at the vertices themselves */
193 /* Cache3 is the various normals for the faces */
194 needCache2
= needCache3
= 0;
195 if (qobj
->normals
== GLU_SMOOTH
) {
199 if (qobj
->normals
== GLU_FLAT
) {
200 if (qobj
->drawStyle
!= GLU_POINT
) {
203 if (qobj
->drawStyle
== GLU_LINE
) {
208 zNormal
= deltaRadius
/ length
;
209 xyNormalRatio
= height
/ length
;
211 for (i
= 0; i
< slices
; i
++) {
212 angle
= 2 * PI
* i
/ slices
;
214 if (qobj
->orientation
== GLU_OUTSIDE
) {
215 sinCache2
[i
] = xyNormalRatio
* SIN(angle
);
216 cosCache2
[i
] = xyNormalRatio
* COS(angle
);
218 sinCache2
[i
] = -xyNormalRatio
* SIN(angle
);
219 cosCache2
[i
] = -xyNormalRatio
* COS(angle
);
222 sinCache
[i
] = SIN(angle
);
223 cosCache
[i
] = COS(angle
);
227 for (i
= 0; i
< slices
; i
++) {
228 angle
= 2 * PI
* (i
-0.5) / slices
;
229 if (qobj
->orientation
== GLU_OUTSIDE
) {
230 sinCache3
[i
] = xyNormalRatio
* SIN(angle
);
231 cosCache3
[i
] = xyNormalRatio
* COS(angle
);
233 sinCache3
[i
] = -xyNormalRatio
* SIN(angle
);
234 cosCache3
[i
] = -xyNormalRatio
* COS(angle
);
239 sinCache
[slices
] = sinCache
[0];
240 cosCache
[slices
] = cosCache
[0];
242 sinCache2
[slices
] = sinCache2
[0];
243 cosCache2
[slices
] = cosCache2
[0];
246 sinCache3
[slices
] = sinCache3
[0];
247 cosCache3
[slices
] = cosCache3
[0];
250 switch (qobj
->drawStyle
) {
253 ** An argument could be made for using a TRIANGLE_FAN for the end
254 ** of the cylinder of either radii is 0.0 (a cone). However, a
255 ** TRIANGLE_FAN would not work in smooth shading mode (the common
256 ** case) because the normal for the apex is different for every
257 ** triangle (and TRIANGLE_FAN doesn't let me respecify that normal).
258 ** Now, my choice is GL_TRIANGLES, or leave the GL_QUAD_STRIP and
259 ** just let the GL trivially reject one of the two triangles of the
260 ** QUAD. GL_QUAD_STRIP is probably faster, so I will leave this code
263 for (j
= 0; j
< stacks
; j
++) {
264 zLow
= j
* height
/ stacks
;
265 zHigh
= (j
+ 1) * height
/ stacks
;
266 radiusLow
= baseRadius
- deltaRadius
* ((float) j
/ stacks
);
267 radiusHigh
= baseRadius
- deltaRadius
* ((float) (j
+ 1) / stacks
);
269 glBegin(GL_QUAD_STRIP
);
270 for (i
= 0; i
<= slices
; i
++) {
271 switch(qobj
->normals
) {
273 glNormal3f(sinCache3
[i
], cosCache3
[i
], zNormal
);
276 glNormal3f(sinCache2
[i
], cosCache2
[i
], zNormal
);
282 if (qobj
->orientation
== GLU_OUTSIDE
) {
283 if (qobj
->textureCoords
) {
284 glTexCoord2f(1 - (float) i
/ slices
,
287 glVertex3f(radiusLow
* sinCache
[i
],
288 radiusLow
* cosCache
[i
], zLow
);
289 if (qobj
->textureCoords
) {
290 glTexCoord2f(1 - (float) i
/ slices
,
291 (float) (j
+1) / stacks
);
293 glVertex3f(radiusHigh
* sinCache
[i
],
294 radiusHigh
* cosCache
[i
], zHigh
);
296 if (qobj
->textureCoords
) {
297 glTexCoord2f(1 - (float) i
/ slices
,
298 (float) (j
+1) / stacks
);
300 glVertex3f(radiusHigh
* sinCache
[i
],
301 radiusHigh
* cosCache
[i
], zHigh
);
302 if (qobj
->textureCoords
) {
303 glTexCoord2f(1 - (float) i
/ slices
,
306 glVertex3f(radiusLow
* sinCache
[i
],
307 radiusLow
* cosCache
[i
], zLow
);
315 for (i
= 0; i
< slices
; i
++) {
316 switch(qobj
->normals
) {
319 glNormal3f(sinCache2
[i
], cosCache2
[i
], zNormal
);
325 sintemp
= sinCache
[i
];
326 costemp
= cosCache
[i
];
327 for (j
= 0; j
<= stacks
; j
++) {
328 zLow
= j
* height
/ stacks
;
329 radiusLow
= baseRadius
- deltaRadius
* ((float) j
/ stacks
);
331 if (qobj
->textureCoords
) {
332 glTexCoord2f(1 - (float) i
/ slices
,
335 glVertex3f(radiusLow
* sintemp
,
336 radiusLow
* costemp
, zLow
);
342 for (j
= 1; j
< stacks
; j
++) {
343 zLow
= j
* height
/ stacks
;
344 radiusLow
= baseRadius
- deltaRadius
* ((float) j
/ stacks
);
346 glBegin(GL_LINE_STRIP
);
347 for (i
= 0; i
<= slices
; i
++) {
348 switch(qobj
->normals
) {
350 glNormal3f(sinCache3
[i
], cosCache3
[i
], zNormal
);
353 glNormal3f(sinCache2
[i
], cosCache2
[i
], zNormal
);
359 if (qobj
->textureCoords
) {
360 glTexCoord2f(1 - (float) i
/ slices
,
363 glVertex3f(radiusLow
* sinCache
[i
],
364 radiusLow
* cosCache
[i
], zLow
);
368 /* Intentionally fall through here... */
370 for (j
= 0; j
<= stacks
; j
+= stacks
) {
371 zLow
= j
* height
/ stacks
;
372 radiusLow
= baseRadius
- deltaRadius
* ((float) j
/ stacks
);
374 glBegin(GL_LINE_STRIP
);
375 for (i
= 0; i
<= slices
; i
++) {
376 switch(qobj
->normals
) {
378 glNormal3f(sinCache3
[i
], cosCache3
[i
], zNormal
);
381 glNormal3f(sinCache2
[i
], cosCache2
[i
], zNormal
);
387 if (qobj
->textureCoords
) {
388 glTexCoord2f(1 - (float) i
/ slices
,
391 glVertex3f(radiusLow
* sinCache
[i
], radiusLow
* cosCache
[i
],
396 for (i
= 0; i
< slices
; i
++) {
397 switch(qobj
->normals
) {
400 glNormal3f(sinCache2
[i
], cosCache2
[i
], 0.0);
406 sintemp
= sinCache
[i
];
407 costemp
= cosCache
[i
];
408 glBegin(GL_LINE_STRIP
);
409 for (j
= 0; j
<= stacks
; j
++) {
410 zLow
= j
* height
/ stacks
;
411 radiusLow
= baseRadius
- deltaRadius
* ((float) j
/ stacks
);
413 if (qobj
->textureCoords
) {
414 glTexCoord2f(1 - (float) i
/ slices
,
417 glVertex3f(radiusLow
* sintemp
,
418 radiusLow
* costemp
, zLow
);
429 gluDisk(GLUquadric
*qobj
, GLdouble innerRadius
, GLdouble outerRadius
,
430 GLint slices
, GLint loops
)
432 gluPartialDisk(qobj
, innerRadius
, outerRadius
, slices
, loops
, 0.0, 360.0);
436 gluPartialDisk(GLUquadric
*qobj
, GLdouble innerRadius
,
437 GLdouble outerRadius
, GLint slices
, GLint loops
,
438 GLdouble startAngle
, GLdouble sweepAngle
)
441 GLfloat sinCache
[CACHE_SIZE
];
442 GLfloat cosCache
[CACHE_SIZE
];
444 GLfloat sintemp
, costemp
;
446 GLfloat radiusLow
, radiusHigh
;
447 GLfloat texLow
= 0.0, texHigh
= 0.0;
452 if (slices
>= CACHE_SIZE
) slices
= CACHE_SIZE
-1;
453 if (slices
< 2 || loops
< 1 || outerRadius
<= 0.0 || innerRadius
< 0.0 ||
454 innerRadius
> outerRadius
) {
455 gluQuadricError(qobj
, GLU_INVALID_VALUE
);
459 if (sweepAngle
< -360.0) sweepAngle
= 360.0;
460 if (sweepAngle
> 360.0) sweepAngle
= 360.0;
461 if (sweepAngle
< 0) {
462 startAngle
+= sweepAngle
;
463 sweepAngle
= -sweepAngle
;
466 if (sweepAngle
== 360.0) {
469 slices2
= slices
+ 1;
472 /* Compute length (needed for normal calculations) */
473 deltaRadius
= outerRadius
- innerRadius
;
475 /* Cache is the vertex locations cache */
477 angleOffset
= startAngle
/ 180.0 * PI
;
478 for (i
= 0; i
<= slices
; i
++) {
479 angle
= angleOffset
+ ((PI
* sweepAngle
) / 180.0) * i
/ slices
;
480 sinCache
[i
] = SIN(angle
);
481 cosCache
[i
] = COS(angle
);
484 if (sweepAngle
== 360.0) {
485 sinCache
[slices
] = sinCache
[0];
486 cosCache
[slices
] = cosCache
[0];
489 switch(qobj
->normals
) {
492 if (qobj
->orientation
== GLU_OUTSIDE
) {
493 glNormal3f(0.0, 0.0, 1.0);
495 glNormal3f(0.0, 0.0, -1.0);
503 switch (qobj
->drawStyle
) {
505 if (innerRadius
== 0.0) {
507 /* Triangle strip for inner polygons */
508 glBegin(GL_TRIANGLE_FAN
);
509 if (qobj
->textureCoords
) {
510 glTexCoord2f(0.5, 0.5);
512 glVertex3f(0.0, 0.0, 0.0);
513 radiusLow
= outerRadius
-
514 deltaRadius
* ((float) (loops
-1) / loops
);
515 if (qobj
->textureCoords
) {
516 texLow
= radiusLow
/ outerRadius
/ 2;
519 if (qobj
->orientation
== GLU_OUTSIDE
) {
520 for (i
= slices
; i
>= 0; i
--) {
521 if (qobj
->textureCoords
) {
522 glTexCoord2f(texLow
* sinCache
[i
] + 0.5,
523 texLow
* cosCache
[i
] + 0.5);
525 glVertex3f(radiusLow
* sinCache
[i
],
526 radiusLow
* cosCache
[i
], 0.0);
529 for (i
= 0; i
<= slices
; i
++) {
530 if (qobj
->textureCoords
) {
531 glTexCoord2f(texLow
* sinCache
[i
] + 0.5,
532 texLow
* cosCache
[i
] + 0.5);
534 glVertex3f(radiusLow
* sinCache
[i
],
535 radiusLow
* cosCache
[i
], 0.0);
542 for (j
= 0; j
< finish
; j
++) {
543 radiusLow
= outerRadius
- deltaRadius
* ((float) j
/ loops
);
544 radiusHigh
= outerRadius
- deltaRadius
* ((float) (j
+ 1) / loops
);
545 if (qobj
->textureCoords
) {
546 texLow
= radiusLow
/ outerRadius
/ 2;
547 texHigh
= radiusHigh
/ outerRadius
/ 2;
550 glBegin(GL_QUAD_STRIP
);
551 for (i
= 0; i
<= slices
; i
++) {
552 if (qobj
->orientation
== GLU_OUTSIDE
) {
553 if (qobj
->textureCoords
) {
554 glTexCoord2f(texLow
* sinCache
[i
] + 0.5,
555 texLow
* cosCache
[i
] + 0.5);
557 glVertex3f(radiusLow
* sinCache
[i
],
558 radiusLow
* cosCache
[i
], 0.0);
560 if (qobj
->textureCoords
) {
561 glTexCoord2f(texHigh
* sinCache
[i
] + 0.5,
562 texHigh
* cosCache
[i
] + 0.5);
564 glVertex3f(radiusHigh
* sinCache
[i
],
565 radiusHigh
* cosCache
[i
], 0.0);
567 if (qobj
->textureCoords
) {
568 glTexCoord2f(texHigh
* sinCache
[i
] + 0.5,
569 texHigh
* cosCache
[i
] + 0.5);
571 glVertex3f(radiusHigh
* sinCache
[i
],
572 radiusHigh
* cosCache
[i
], 0.0);
574 if (qobj
->textureCoords
) {
575 glTexCoord2f(texLow
* sinCache
[i
] + 0.5,
576 texLow
* cosCache
[i
] + 0.5);
578 glVertex3f(radiusLow
* sinCache
[i
],
579 radiusLow
* cosCache
[i
], 0.0);
587 for (i
= 0; i
< slices2
; i
++) {
588 sintemp
= sinCache
[i
];
589 costemp
= cosCache
[i
];
590 for (j
= 0; j
<= loops
; j
++) {
591 radiusLow
= outerRadius
- deltaRadius
* ((float) j
/ loops
);
593 if (qobj
->textureCoords
) {
594 texLow
= radiusLow
/ outerRadius
/ 2;
596 glTexCoord2f(texLow
* sinCache
[i
] + 0.5,
597 texLow
* cosCache
[i
] + 0.5);
599 glVertex3f(radiusLow
* sintemp
, radiusLow
* costemp
, 0.0);
605 if (innerRadius
== outerRadius
) {
606 glBegin(GL_LINE_STRIP
);
608 for (i
= 0; i
<= slices
; i
++) {
609 if (qobj
->textureCoords
) {
610 glTexCoord2f(sinCache
[i
] / 2 + 0.5,
611 cosCache
[i
] / 2 + 0.5);
613 glVertex3f(innerRadius
* sinCache
[i
],
614 innerRadius
* cosCache
[i
], 0.0);
619 for (j
= 0; j
<= loops
; j
++) {
620 radiusLow
= outerRadius
- deltaRadius
* ((float) j
/ loops
);
621 if (qobj
->textureCoords
) {
622 texLow
= radiusLow
/ outerRadius
/ 2;
625 glBegin(GL_LINE_STRIP
);
626 for (i
= 0; i
<= slices
; i
++) {
627 if (qobj
->textureCoords
) {
628 glTexCoord2f(texLow
* sinCache
[i
] + 0.5,
629 texLow
* cosCache
[i
] + 0.5);
631 glVertex3f(radiusLow
* sinCache
[i
],
632 radiusLow
* cosCache
[i
], 0.0);
636 for (i
=0; i
< slices2
; i
++) {
637 sintemp
= sinCache
[i
];
638 costemp
= cosCache
[i
];
639 glBegin(GL_LINE_STRIP
);
640 for (j
= 0; j
<= loops
; j
++) {
641 radiusLow
= outerRadius
- deltaRadius
* ((float) j
/ loops
);
642 if (qobj
->textureCoords
) {
643 texLow
= radiusLow
/ outerRadius
/ 2;
646 if (qobj
->textureCoords
) {
647 glTexCoord2f(texLow
* sinCache
[i
] + 0.5,
648 texLow
* cosCache
[i
] + 0.5);
650 glVertex3f(radiusLow
* sintemp
, radiusLow
* costemp
, 0.0);
656 if (sweepAngle
< 360.0) {
657 for (i
= 0; i
<= slices
; i
+= slices
) {
658 sintemp
= sinCache
[i
];
659 costemp
= cosCache
[i
];
660 glBegin(GL_LINE_STRIP
);
661 for (j
= 0; j
<= loops
; j
++) {
662 radiusLow
= outerRadius
- deltaRadius
* ((float) j
/ loops
);
664 if (qobj
->textureCoords
) {
665 texLow
= radiusLow
/ outerRadius
/ 2;
666 glTexCoord2f(texLow
* sinCache
[i
] + 0.5,
667 texLow
* cosCache
[i
] + 0.5);
669 glVertex3f(radiusLow
* sintemp
, radiusLow
* costemp
, 0.0);
674 for (j
= 0; j
<= loops
; j
+= loops
) {
675 radiusLow
= outerRadius
- deltaRadius
* ((float) j
/ loops
);
676 if (qobj
->textureCoords
) {
677 texLow
= radiusLow
/ outerRadius
/ 2;
680 glBegin(GL_LINE_STRIP
);
681 for (i
= 0; i
<= slices
; i
++) {
682 if (qobj
->textureCoords
) {
683 glTexCoord2f(texLow
* sinCache
[i
] + 0.5,
684 texLow
* cosCache
[i
] + 0.5);
686 glVertex3f(radiusLow
* sinCache
[i
],
687 radiusLow
* cosCache
[i
], 0.0);
690 if (innerRadius
== outerRadius
) break;
699 gluSphere(GLUquadric
*qobj
, GLdouble radius
, GLint slices
, GLint stacks
)
702 GLfloat sinCache1a
[CACHE_SIZE
];
703 GLfloat cosCache1a
[CACHE_SIZE
];
704 GLfloat sinCache2a
[CACHE_SIZE
];
705 GLfloat cosCache2a
[CACHE_SIZE
];
706 GLfloat sinCache3a
[CACHE_SIZE
];
707 GLfloat cosCache3a
[CACHE_SIZE
];
708 GLfloat sinCache1b
[CACHE_SIZE
];
709 GLfloat cosCache1b
[CACHE_SIZE
];
710 GLfloat sinCache2b
[CACHE_SIZE
];
711 GLfloat cosCache2b
[CACHE_SIZE
];
712 GLfloat sinCache3b
[CACHE_SIZE
];
713 GLfloat cosCache3b
[CACHE_SIZE
];
716 GLfloat sintemp1
= 0.0, sintemp2
= 0.0, sintemp3
= 0.0, sintemp4
= 0.0;
717 GLfloat costemp1
= 0.0, costemp2
= 0.0, costemp3
= 0.0, costemp4
= 0.0;
718 GLboolean needCache2
, needCache3
;
721 if (slices
>= CACHE_SIZE
) slices
= CACHE_SIZE
-1;
722 if (stacks
>= CACHE_SIZE
) stacks
= CACHE_SIZE
-1;
723 if (slices
< 2 || stacks
< 1 || radius
< 0.0) {
724 gluQuadricError(qobj
, GLU_INVALID_VALUE
);
728 /* Cache is the vertex locations cache */
729 /* Cache2 is the various normals at the vertices themselves */
730 /* Cache3 is the various normals for the faces */
731 needCache2
= needCache3
= GL_FALSE
;
733 if (qobj
->normals
== GLU_SMOOTH
) {
734 needCache2
= GL_TRUE
;
737 if (qobj
->normals
== GLU_FLAT
) {
738 if (qobj
->drawStyle
!= GLU_POINT
) {
739 needCache3
= GL_TRUE
;
741 if (qobj
->drawStyle
== GLU_LINE
) {
742 needCache2
= GL_TRUE
;
746 for (i
= 0; i
< slices
; i
++) {
747 angle
= 2 * PI
* i
/ slices
;
748 sinCache1a
[i
] = SIN(angle
);
749 cosCache1a
[i
] = COS(angle
);
751 sinCache2a
[i
] = sinCache1a
[i
];
752 cosCache2a
[i
] = cosCache1a
[i
];
756 for (j
= 0; j
<= stacks
; j
++) {
757 angle
= PI
* j
/ stacks
;
759 if (qobj
->orientation
== GLU_OUTSIDE
) {
760 sinCache2b
[j
] = SIN(angle
);
761 cosCache2b
[j
] = COS(angle
);
763 sinCache2b
[j
] = -SIN(angle
);
764 cosCache2b
[j
] = -COS(angle
);
767 sinCache1b
[j
] = radius
* SIN(angle
);
768 cosCache1b
[j
] = radius
* COS(angle
);
770 /* Make sure it comes to a point */
772 sinCache1b
[stacks
] = 0;
775 for (i
= 0; i
< slices
; i
++) {
776 angle
= 2 * PI
* (i
-0.5) / slices
;
777 sinCache3a
[i
] = SIN(angle
);
778 cosCache3a
[i
] = COS(angle
);
780 for (j
= 0; j
<= stacks
; j
++) {
781 angle
= PI
* (j
- 0.5) / stacks
;
782 if (qobj
->orientation
== GLU_OUTSIDE
) {
783 sinCache3b
[j
] = SIN(angle
);
784 cosCache3b
[j
] = COS(angle
);
786 sinCache3b
[j
] = -SIN(angle
);
787 cosCache3b
[j
] = -COS(angle
);
792 sinCache1a
[slices
] = sinCache1a
[0];
793 cosCache1a
[slices
] = cosCache1a
[0];
795 sinCache2a
[slices
] = sinCache2a
[0];
796 cosCache2a
[slices
] = cosCache2a
[0];
799 sinCache3a
[slices
] = sinCache3a
[0];
800 cosCache3a
[slices
] = cosCache3a
[0];
803 switch (qobj
->drawStyle
) {
805 /* Do ends of sphere as TRIANGLE_FAN's (if not texturing)
806 ** We don't do it when texturing because we need to respecify the
807 ** texture coordinates of the apex for every adjacent vertex (because
808 ** it isn't a constant for that point)
810 if (!(qobj
->textureCoords
)) {
814 /* Low end first (j == 0 iteration) */
815 sintemp2
= sinCache1b
[1];
816 zHigh
= cosCache1b
[1];
817 switch(qobj
->normals
) {
819 sintemp3
= sinCache3b
[1];
820 costemp3
= cosCache3b
[1];
823 sintemp3
= sinCache2b
[1];
824 costemp3
= cosCache2b
[1];
825 glNormal3f(sinCache2a
[0] * sinCache2b
[0],
826 cosCache2a
[0] * sinCache2b
[0],
832 glBegin(GL_TRIANGLE_FAN
);
833 glVertex3f(0.0, 0.0, radius
);
834 if (qobj
->orientation
== GLU_OUTSIDE
) {
835 for (i
= slices
; i
>= 0; i
--) {
836 switch(qobj
->normals
) {
838 glNormal3f(sinCache2a
[i
] * sintemp3
,
839 cosCache2a
[i
] * sintemp3
,
844 glNormal3f(sinCache3a
[i
+1] * sintemp3
,
845 cosCache3a
[i
+1] * sintemp3
,
853 glVertex3f(sintemp2
* sinCache1a
[i
],
854 sintemp2
* cosCache1a
[i
], zHigh
);
857 for (i
= 0; i
<= slices
; i
++) {
858 switch(qobj
->normals
) {
860 glNormal3f(sinCache2a
[i
] * sintemp3
,
861 cosCache2a
[i
] * sintemp3
,
865 glNormal3f(sinCache3a
[i
] * sintemp3
,
866 cosCache3a
[i
] * sintemp3
,
873 glVertex3f(sintemp2
* sinCache1a
[i
],
874 sintemp2
* cosCache1a
[i
], zHigh
);
879 /* High end next (j == stacks-1 iteration) */
880 sintemp2
= sinCache1b
[stacks
-1];
881 zHigh
= cosCache1b
[stacks
-1];
882 switch(qobj
->normals
) {
884 sintemp3
= sinCache3b
[stacks
];
885 costemp3
= cosCache3b
[stacks
];
888 sintemp3
= sinCache2b
[stacks
-1];
889 costemp3
= cosCache2b
[stacks
-1];
890 glNormal3f(sinCache2a
[stacks
] * sinCache2b
[stacks
],
891 cosCache2a
[stacks
] * sinCache2b
[stacks
],
897 glBegin(GL_TRIANGLE_FAN
);
898 glVertex3f(0.0, 0.0, -radius
);
899 if (qobj
->orientation
== GLU_OUTSIDE
) {
900 for (i
= 0; i
<= slices
; i
++) {
901 switch(qobj
->normals
) {
903 glNormal3f(sinCache2a
[i
] * sintemp3
,
904 cosCache2a
[i
] * sintemp3
,
908 glNormal3f(sinCache3a
[i
] * sintemp3
,
909 cosCache3a
[i
] * sintemp3
,
916 glVertex3f(sintemp2
* sinCache1a
[i
],
917 sintemp2
* cosCache1a
[i
], zHigh
);
920 for (i
= slices
; i
>= 0; i
--) {
921 switch(qobj
->normals
) {
923 glNormal3f(sinCache2a
[i
] * sintemp3
,
924 cosCache2a
[i
] * sintemp3
,
929 glNormal3f(sinCache3a
[i
+1] * sintemp3
,
930 cosCache3a
[i
+1] * sintemp3
,
938 glVertex3f(sintemp2
* sinCache1a
[i
],
939 sintemp2
* cosCache1a
[i
], zHigh
);
947 for (j
= start
; j
< finish
; j
++) {
948 zLow
= cosCache1b
[j
];
949 zHigh
= cosCache1b
[j
+1];
950 sintemp1
= sinCache1b
[j
];
951 sintemp2
= sinCache1b
[j
+1];
952 switch(qobj
->normals
) {
954 sintemp4
= sinCache3b
[j
+1];
955 costemp4
= cosCache3b
[j
+1];
958 if (qobj
->orientation
== GLU_OUTSIDE
) {
959 sintemp3
= sinCache2b
[j
+1];
960 costemp3
= cosCache2b
[j
+1];
961 sintemp4
= sinCache2b
[j
];
962 costemp4
= cosCache2b
[j
];
964 sintemp3
= sinCache2b
[j
];
965 costemp3
= cosCache2b
[j
];
966 sintemp4
= sinCache2b
[j
+1];
967 costemp4
= cosCache2b
[j
+1];
974 glBegin(GL_QUAD_STRIP
);
975 for (i
= 0; i
<= slices
; i
++) {
976 switch(qobj
->normals
) {
978 glNormal3f(sinCache2a
[i
] * sintemp3
,
979 cosCache2a
[i
] * sintemp3
,
987 if (qobj
->orientation
== GLU_OUTSIDE
) {
988 if (qobj
->textureCoords
) {
989 glTexCoord2f(1 - (float) i
/ slices
,
990 1 - (float) (j
+1) / stacks
);
992 glVertex3f(sintemp2
* sinCache1a
[i
],
993 sintemp2
* cosCache1a
[i
], zHigh
);
995 if (qobj
->textureCoords
) {
996 glTexCoord2f(1 - (float) i
/ slices
,
997 1 - (float) j
/ stacks
);
999 glVertex3f(sintemp1
* sinCache1a
[i
],
1000 sintemp1
* cosCache1a
[i
], zLow
);
1002 switch(qobj
->normals
) {
1004 glNormal3f(sinCache2a
[i
] * sintemp4
,
1005 cosCache2a
[i
] * sintemp4
,
1009 glNormal3f(sinCache3a
[i
] * sintemp4
,
1010 cosCache3a
[i
] * sintemp4
,
1017 if (qobj
->orientation
== GLU_OUTSIDE
) {
1018 if (qobj
->textureCoords
) {
1019 glTexCoord2f(1 - (float) i
/ slices
,
1020 1 - (float) j
/ stacks
);
1022 glVertex3f(sintemp1
* sinCache1a
[i
],
1023 sintemp1
* cosCache1a
[i
], zLow
);
1025 if (qobj
->textureCoords
) {
1026 glTexCoord2f(1 - (float) i
/ slices
,
1027 1 - (float) (j
+1) / stacks
);
1029 glVertex3f(sintemp2
* sinCache1a
[i
],
1030 sintemp2
* cosCache1a
[i
], zHigh
);
1038 for (j
= 0; j
<= stacks
; j
++) {
1039 sintemp1
= sinCache1b
[j
];
1040 costemp1
= cosCache1b
[j
];
1041 switch(qobj
->normals
) {
1044 sintemp2
= sinCache2b
[j
];
1045 costemp2
= cosCache2b
[j
];
1050 for (i
= 0; i
< slices
; i
++) {
1051 switch(qobj
->normals
) {
1054 glNormal3f(sinCache2a
[i
] * sintemp2
,
1055 cosCache2a
[i
] * sintemp2
,
1063 zLow
= j
* radius
/ stacks
;
1065 if (qobj
->textureCoords
) {
1066 glTexCoord2f(1 - (float) i
/ slices
,
1067 1 - (float) j
/ stacks
);
1069 glVertex3f(sintemp1
* sinCache1a
[i
],
1070 sintemp1
* cosCache1a
[i
], costemp1
);
1076 case GLU_SILHOUETTE
:
1077 for (j
= 1; j
< stacks
; j
++) {
1078 sintemp1
= sinCache1b
[j
];
1079 costemp1
= cosCache1b
[j
];
1080 switch(qobj
->normals
) {
1083 sintemp2
= sinCache2b
[j
];
1084 costemp2
= cosCache2b
[j
];
1090 glBegin(GL_LINE_STRIP
);
1091 for (i
= 0; i
<= slices
; i
++) {
1092 switch(qobj
->normals
) {
1094 glNormal3f(sinCache3a
[i
] * sintemp2
,
1095 cosCache3a
[i
] * sintemp2
,
1099 glNormal3f(sinCache2a
[i
] * sintemp2
,
1100 cosCache2a
[i
] * sintemp2
,
1107 if (qobj
->textureCoords
) {
1108 glTexCoord2f(1 - (float) i
/ slices
,
1109 1 - (float) j
/ stacks
);
1111 glVertex3f(sintemp1
* sinCache1a
[i
],
1112 sintemp1
* cosCache1a
[i
], costemp1
);
1116 for (i
= 0; i
< slices
; i
++) {
1117 sintemp1
= sinCache1a
[i
];
1118 costemp1
= cosCache1a
[i
];
1119 switch(qobj
->normals
) {
1122 sintemp2
= sinCache2a
[i
];
1123 costemp2
= cosCache2a
[i
];
1129 glBegin(GL_LINE_STRIP
);
1130 for (j
= 0; j
<= stacks
; j
++) {
1131 switch(qobj
->normals
) {
1133 glNormal3f(sintemp2
* sinCache3b
[j
],
1134 costemp2
* sinCache3b
[j
],
1138 glNormal3f(sintemp2
* sinCache2b
[j
],
1139 costemp2
* sinCache2b
[j
],
1147 if (qobj
->textureCoords
) {
1148 glTexCoord2f(1 - (float) i
/ slices
,
1149 1 - (float) j
/ stacks
);
1151 glVertex3f(sintemp1
* sinCache1b
[j
],
1152 costemp1
* sinCache1b
[j
], cosCache1b
[j
]);