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.
34 ** $Date: 2002/11/01 23:45:31 $ $Revision: 1.3 $
35 ** $Header: /home/krh/git/sync/mesa-cvs-repo/Mesa/src/glu/sgi/libutil/quad.c,v 1.3 2002/11/01 23:45:31 brianp Exp $
46 /* Make it not a power of two to avoid cache thrashing on the chip */
47 #define CACHE_SIZE 240
49 #define PI 3.14159265358979323846
53 GLboolean textureCoords
;
56 void (GLAPIENTRY
*errorCallback
)( GLint
);
59 GLUquadric
* GLAPIENTRY
64 newstate
= (GLUquadric
*) malloc(sizeof(GLUquadric
));
65 if (newstate
== NULL
) {
66 /* Can't report an error at this point... */
69 newstate
->normals
= GLU_SMOOTH
;
70 newstate
->textureCoords
= GL_FALSE
;
71 newstate
->orientation
= GLU_OUTSIDE
;
72 newstate
->drawStyle
= GLU_FILL
;
73 newstate
->errorCallback
= NULL
;
79 gluDeleteQuadric(GLUquadric
*state
)
84 static void gluQuadricError(GLUquadric
*qobj
, GLenum which
)
86 if (qobj
->errorCallback
) {
87 qobj
->errorCallback(which
);
92 gluQuadricCallback(GLUquadric
*qobj
, GLenum which
, _GLUfuncptr fn
)
96 qobj
->errorCallback
= (void (GLAPIENTRY
*)(GLint
)) fn
;
99 gluQuadricError(qobj
, GLU_INVALID_ENUM
);
105 gluQuadricNormals(GLUquadric
*qobj
, GLenum normals
)
113 gluQuadricError(qobj
, GLU_INVALID_ENUM
);
116 qobj
->normals
= normals
;
120 gluQuadricTexture(GLUquadric
*qobj
, GLboolean textureCoords
)
122 qobj
->textureCoords
= textureCoords
;
126 gluQuadricOrientation(GLUquadric
*qobj
, GLenum orientation
)
128 switch(orientation
) {
133 gluQuadricError(qobj
, GLU_INVALID_ENUM
);
136 qobj
->orientation
= orientation
;
140 gluQuadricDrawStyle(GLUquadric
*qobj
, GLenum drawStyle
)
149 gluQuadricError(qobj
, GLU_INVALID_ENUM
);
152 qobj
->drawStyle
= drawStyle
;
156 gluCylinder(GLUquadric
*qobj
, GLdouble baseRadius
, GLdouble topRadius
,
157 GLdouble height
, GLint slices
, GLint stacks
)
160 GLfloat sinCache
[CACHE_SIZE
];
161 GLfloat cosCache
[CACHE_SIZE
];
162 GLfloat sinCache2
[CACHE_SIZE
];
163 GLfloat cosCache2
[CACHE_SIZE
];
164 GLfloat sinCache3
[CACHE_SIZE
];
165 GLfloat cosCache3
[CACHE_SIZE
];
168 GLfloat sintemp
, costemp
;
172 GLfloat xyNormalRatio
;
173 GLfloat radiusLow
, radiusHigh
;
174 int needCache2
, needCache3
;
176 if (slices
>= CACHE_SIZE
) slices
= CACHE_SIZE
-1;
178 if (slices
< 2 || stacks
< 1 || baseRadius
< 0.0 || topRadius
< 0.0 ||
180 gluQuadricError(qobj
, GLU_INVALID_VALUE
);
184 /* Compute length (needed for normal calculations) */
185 deltaRadius
= baseRadius
- topRadius
;
186 length
= SQRT(deltaRadius
*deltaRadius
+ height
*height
);
188 gluQuadricError(qobj
, GLU_INVALID_VALUE
);
192 /* Cache is the vertex locations cache */
193 /* Cache2 is the various normals at the vertices themselves */
194 /* Cache3 is the various normals for the faces */
195 needCache2
= needCache3
= 0;
196 if (qobj
->normals
== GLU_SMOOTH
) {
200 if (qobj
->normals
== GLU_FLAT
) {
201 if (qobj
->drawStyle
!= GLU_POINT
) {
204 if (qobj
->drawStyle
== GLU_LINE
) {
209 zNormal
= deltaRadius
/ length
;
210 xyNormalRatio
= height
/ length
;
212 for (i
= 0; i
< slices
; i
++) {
213 angle
= 2 * PI
* i
/ slices
;
215 if (qobj
->orientation
== GLU_OUTSIDE
) {
216 sinCache2
[i
] = xyNormalRatio
* SIN(angle
);
217 cosCache2
[i
] = xyNormalRatio
* COS(angle
);
219 sinCache2
[i
] = -xyNormalRatio
* SIN(angle
);
220 cosCache2
[i
] = -xyNormalRatio
* COS(angle
);
223 sinCache
[i
] = SIN(angle
);
224 cosCache
[i
] = COS(angle
);
228 for (i
= 0; i
< slices
; i
++) {
229 angle
= 2 * PI
* (i
-0.5) / slices
;
230 if (qobj
->orientation
== GLU_OUTSIDE
) {
231 sinCache3
[i
] = xyNormalRatio
* SIN(angle
);
232 cosCache3
[i
] = xyNormalRatio
* COS(angle
);
234 sinCache3
[i
] = -xyNormalRatio
* SIN(angle
);
235 cosCache3
[i
] = -xyNormalRatio
* COS(angle
);
240 sinCache
[slices
] = sinCache
[0];
241 cosCache
[slices
] = cosCache
[0];
243 sinCache2
[slices
] = sinCache2
[0];
244 cosCache2
[slices
] = cosCache2
[0];
247 sinCache3
[slices
] = sinCache3
[0];
248 cosCache3
[slices
] = cosCache3
[0];
251 switch (qobj
->drawStyle
) {
254 ** An argument could be made for using a TRIANGLE_FAN for the end
255 ** of the cylinder of either radii is 0.0 (a cone). However, a
256 ** TRIANGLE_FAN would not work in smooth shading mode (the common
257 ** case) because the normal for the apex is different for every
258 ** triangle (and TRIANGLE_FAN doesn't let me respecify that normal).
259 ** Now, my choice is GL_TRIANGLES, or leave the GL_QUAD_STRIP and
260 ** just let the GL trivially reject one of the two triangles of the
261 ** QUAD. GL_QUAD_STRIP is probably faster, so I will leave this code
264 for (j
= 0; j
< stacks
; j
++) {
265 zLow
= j
* height
/ stacks
;
266 zHigh
= (j
+ 1) * height
/ stacks
;
267 radiusLow
= baseRadius
- deltaRadius
* ((float) j
/ stacks
);
268 radiusHigh
= baseRadius
- deltaRadius
* ((float) (j
+ 1) / stacks
);
270 glBegin(GL_QUAD_STRIP
);
271 for (i
= 0; i
<= slices
; i
++) {
272 switch(qobj
->normals
) {
274 glNormal3f(sinCache3
[i
], cosCache3
[i
], zNormal
);
277 glNormal3f(sinCache2
[i
], cosCache2
[i
], zNormal
);
283 if (qobj
->orientation
== GLU_OUTSIDE
) {
284 if (qobj
->textureCoords
) {
285 glTexCoord2f(1 - (float) i
/ slices
,
288 glVertex3f(radiusLow
* sinCache
[i
],
289 radiusLow
* cosCache
[i
], zLow
);
290 if (qobj
->textureCoords
) {
291 glTexCoord2f(1 - (float) i
/ slices
,
292 (float) (j
+1) / stacks
);
294 glVertex3f(radiusHigh
* sinCache
[i
],
295 radiusHigh
* cosCache
[i
], zHigh
);
297 if (qobj
->textureCoords
) {
298 glTexCoord2f(1 - (float) i
/ slices
,
299 (float) (j
+1) / stacks
);
301 glVertex3f(radiusHigh
* sinCache
[i
],
302 radiusHigh
* cosCache
[i
], zHigh
);
303 if (qobj
->textureCoords
) {
304 glTexCoord2f(1 - (float) i
/ slices
,
307 glVertex3f(radiusLow
* sinCache
[i
],
308 radiusLow
* cosCache
[i
], zLow
);
316 for (i
= 0; i
< slices
; i
++) {
317 switch(qobj
->normals
) {
320 glNormal3f(sinCache2
[i
], cosCache2
[i
], zNormal
);
326 sintemp
= sinCache
[i
];
327 costemp
= cosCache
[i
];
328 for (j
= 0; j
<= stacks
; j
++) {
329 zLow
= j
* height
/ stacks
;
330 radiusLow
= baseRadius
- deltaRadius
* ((float) j
/ stacks
);
332 if (qobj
->textureCoords
) {
333 glTexCoord2f(1 - (float) i
/ slices
,
336 glVertex3f(radiusLow
* sintemp
,
337 radiusLow
* costemp
, zLow
);
343 for (j
= 1; j
< stacks
; j
++) {
344 zLow
= j
* height
/ stacks
;
345 radiusLow
= baseRadius
- deltaRadius
* ((float) j
/ stacks
);
347 glBegin(GL_LINE_STRIP
);
348 for (i
= 0; i
<= slices
; i
++) {
349 switch(qobj
->normals
) {
351 glNormal3f(sinCache3
[i
], cosCache3
[i
], zNormal
);
354 glNormal3f(sinCache2
[i
], cosCache2
[i
], zNormal
);
360 if (qobj
->textureCoords
) {
361 glTexCoord2f(1 - (float) i
/ slices
,
364 glVertex3f(radiusLow
* sinCache
[i
],
365 radiusLow
* cosCache
[i
], zLow
);
369 /* Intentionally fall through here... */
371 for (j
= 0; j
<= stacks
; j
+= stacks
) {
372 zLow
= j
* height
/ stacks
;
373 radiusLow
= baseRadius
- deltaRadius
* ((float) j
/ stacks
);
375 glBegin(GL_LINE_STRIP
);
376 for (i
= 0; i
<= slices
; i
++) {
377 switch(qobj
->normals
) {
379 glNormal3f(sinCache3
[i
], cosCache3
[i
], zNormal
);
382 glNormal3f(sinCache2
[i
], cosCache2
[i
], zNormal
);
388 if (qobj
->textureCoords
) {
389 glTexCoord2f(1 - (float) i
/ slices
,
392 glVertex3f(radiusLow
* sinCache
[i
], radiusLow
* cosCache
[i
],
397 for (i
= 0; i
< slices
; i
++) {
398 switch(qobj
->normals
) {
401 glNormal3f(sinCache2
[i
], cosCache2
[i
], 0.0);
407 sintemp
= sinCache
[i
];
408 costemp
= cosCache
[i
];
409 glBegin(GL_LINE_STRIP
);
410 for (j
= 0; j
<= stacks
; j
++) {
411 zLow
= j
* height
/ stacks
;
412 radiusLow
= baseRadius
- deltaRadius
* ((float) j
/ stacks
);
414 if (qobj
->textureCoords
) {
415 glTexCoord2f(1 - (float) i
/ slices
,
418 glVertex3f(radiusLow
* sintemp
,
419 radiusLow
* costemp
, zLow
);
430 gluDisk(GLUquadric
*qobj
, GLdouble innerRadius
, GLdouble outerRadius
,
431 GLint slices
, GLint loops
)
433 gluPartialDisk(qobj
, innerRadius
, outerRadius
, slices
, loops
, 0.0, 360.0);
437 gluPartialDisk(GLUquadric
*qobj
, GLdouble innerRadius
,
438 GLdouble outerRadius
, GLint slices
, GLint loops
,
439 GLdouble startAngle
, GLdouble sweepAngle
)
442 GLfloat sinCache
[CACHE_SIZE
];
443 GLfloat cosCache
[CACHE_SIZE
];
445 GLfloat sintemp
, costemp
;
447 GLfloat radiusLow
, radiusHigh
;
448 GLfloat texLow
, texHigh
;
453 if (slices
>= CACHE_SIZE
) slices
= CACHE_SIZE
-1;
454 if (slices
< 2 || loops
< 1 || outerRadius
<= 0.0 || innerRadius
< 0.0 ||
455 innerRadius
> outerRadius
) {
456 gluQuadricError(qobj
, GLU_INVALID_VALUE
);
460 if (sweepAngle
< -360.0) sweepAngle
= 360.0;
461 if (sweepAngle
> 360.0) sweepAngle
= 360.0;
462 if (sweepAngle
< 0) {
463 startAngle
+= sweepAngle
;
464 sweepAngle
= -sweepAngle
;
467 if (sweepAngle
== 360.0) {
470 slices2
= slices
+ 1;
473 /* Compute length (needed for normal calculations) */
474 deltaRadius
= outerRadius
- innerRadius
;
476 /* Cache is the vertex locations cache */
478 angleOffset
= startAngle
/ 180.0 * PI
;
479 for (i
= 0; i
<= slices
; i
++) {
480 angle
= angleOffset
+ ((PI
* sweepAngle
) / 180.0) * i
/ slices
;
481 sinCache
[i
] = SIN(angle
);
482 cosCache
[i
] = COS(angle
);
485 if (sweepAngle
== 360.0) {
486 sinCache
[slices
] = sinCache
[0];
487 cosCache
[slices
] = cosCache
[0];
490 switch(qobj
->normals
) {
493 if (qobj
->orientation
== GLU_OUTSIDE
) {
494 glNormal3f(0.0, 0.0, 1.0);
496 glNormal3f(0.0, 0.0, -1.0);
504 switch (qobj
->drawStyle
) {
506 if (innerRadius
== 0.0) {
508 /* Triangle strip for inner polygons */
509 glBegin(GL_TRIANGLE_FAN
);
510 if (qobj
->textureCoords
) {
511 glTexCoord2f(0.5, 0.5);
513 glVertex3f(0.0, 0.0, 0.0);
514 radiusLow
= outerRadius
-
515 deltaRadius
* ((float) (loops
-1) / loops
);
516 if (qobj
->textureCoords
) {
517 texLow
= radiusLow
/ outerRadius
/ 2;
520 if (qobj
->orientation
== GLU_OUTSIDE
) {
521 for (i
= slices
; i
>= 0; i
--) {
522 if (qobj
->textureCoords
) {
523 glTexCoord2f(texLow
* sinCache
[i
] + 0.5,
524 texLow
* cosCache
[i
] + 0.5);
526 glVertex3f(radiusLow
* sinCache
[i
],
527 radiusLow
* cosCache
[i
], 0.0);
530 for (i
= 0; i
<= slices
; i
++) {
531 if (qobj
->textureCoords
) {
532 glTexCoord2f(texLow
* sinCache
[i
] + 0.5,
533 texLow
* cosCache
[i
] + 0.5);
535 glVertex3f(radiusLow
* sinCache
[i
],
536 radiusLow
* cosCache
[i
], 0.0);
543 for (j
= 0; j
< finish
; j
++) {
544 radiusLow
= outerRadius
- deltaRadius
* ((float) j
/ loops
);
545 radiusHigh
= outerRadius
- deltaRadius
* ((float) (j
+ 1) / loops
);
546 if (qobj
->textureCoords
) {
547 texLow
= radiusLow
/ outerRadius
/ 2;
548 texHigh
= radiusHigh
/ outerRadius
/ 2;
551 glBegin(GL_QUAD_STRIP
);
552 for (i
= 0; i
<= slices
; i
++) {
553 if (qobj
->orientation
== GLU_OUTSIDE
) {
554 if (qobj
->textureCoords
) {
555 glTexCoord2f(texLow
* sinCache
[i
] + 0.5,
556 texLow
* cosCache
[i
] + 0.5);
558 glVertex3f(radiusLow
* sinCache
[i
],
559 radiusLow
* cosCache
[i
], 0.0);
561 if (qobj
->textureCoords
) {
562 glTexCoord2f(texHigh
* sinCache
[i
] + 0.5,
563 texHigh
* cosCache
[i
] + 0.5);
565 glVertex3f(radiusHigh
* sinCache
[i
],
566 radiusHigh
* cosCache
[i
], 0.0);
568 if (qobj
->textureCoords
) {
569 glTexCoord2f(texHigh
* sinCache
[i
] + 0.5,
570 texHigh
* cosCache
[i
] + 0.5);
572 glVertex3f(radiusHigh
* sinCache
[i
],
573 radiusHigh
* cosCache
[i
], 0.0);
575 if (qobj
->textureCoords
) {
576 glTexCoord2f(texLow
* sinCache
[i
] + 0.5,
577 texLow
* cosCache
[i
] + 0.5);
579 glVertex3f(radiusLow
* sinCache
[i
],
580 radiusLow
* cosCache
[i
], 0.0);
588 for (i
= 0; i
< slices2
; i
++) {
589 sintemp
= sinCache
[i
];
590 costemp
= cosCache
[i
];
591 for (j
= 0; j
<= loops
; j
++) {
592 radiusLow
= outerRadius
- deltaRadius
* ((float) j
/ loops
);
594 if (qobj
->textureCoords
) {
595 texLow
= radiusLow
/ outerRadius
/ 2;
597 glTexCoord2f(texLow
* sinCache
[i
] + 0.5,
598 texLow
* cosCache
[i
] + 0.5);
600 glVertex3f(radiusLow
* sintemp
, radiusLow
* costemp
, 0.0);
606 if (innerRadius
== outerRadius
) {
607 glBegin(GL_LINE_STRIP
);
609 for (i
= 0; i
<= slices
; i
++) {
610 if (qobj
->textureCoords
) {
611 glTexCoord2f(sinCache
[i
] / 2 + 0.5,
612 cosCache
[i
] / 2 + 0.5);
614 glVertex3f(innerRadius
* sinCache
[i
],
615 innerRadius
* cosCache
[i
], 0.0);
620 for (j
= 0; j
<= loops
; j
++) {
621 radiusLow
= outerRadius
- deltaRadius
* ((float) j
/ loops
);
622 if (qobj
->textureCoords
) {
623 texLow
= radiusLow
/ outerRadius
/ 2;
626 glBegin(GL_LINE_STRIP
);
627 for (i
= 0; i
<= slices
; i
++) {
628 if (qobj
->textureCoords
) {
629 glTexCoord2f(texLow
* sinCache
[i
] + 0.5,
630 texLow
* cosCache
[i
] + 0.5);
632 glVertex3f(radiusLow
* sinCache
[i
],
633 radiusLow
* cosCache
[i
], 0.0);
637 for (i
=0; i
< slices2
; i
++) {
638 sintemp
= sinCache
[i
];
639 costemp
= cosCache
[i
];
640 glBegin(GL_LINE_STRIP
);
641 for (j
= 0; j
<= loops
; j
++) {
642 radiusLow
= outerRadius
- deltaRadius
* ((float) j
/ loops
);
643 if (qobj
->textureCoords
) {
644 texLow
= radiusLow
/ outerRadius
/ 2;
647 if (qobj
->textureCoords
) {
648 glTexCoord2f(texLow
* sinCache
[i
] + 0.5,
649 texLow
* cosCache
[i
] + 0.5);
651 glVertex3f(radiusLow
* sintemp
, radiusLow
* costemp
, 0.0);
657 if (sweepAngle
< 360.0) {
658 for (i
= 0; i
<= slices
; i
+= slices
) {
659 sintemp
= sinCache
[i
];
660 costemp
= cosCache
[i
];
661 glBegin(GL_LINE_STRIP
);
662 for (j
= 0; j
<= loops
; j
++) {
663 radiusLow
= outerRadius
- deltaRadius
* ((float) j
/ loops
);
665 if (qobj
->textureCoords
) {
666 texLow
= radiusLow
/ outerRadius
/ 2;
667 glTexCoord2f(texLow
* sinCache
[i
] + 0.5,
668 texLow
* cosCache
[i
] + 0.5);
670 glVertex3f(radiusLow
* sintemp
, radiusLow
* costemp
, 0.0);
675 for (j
= 0; j
<= loops
; j
+= loops
) {
676 radiusLow
= outerRadius
- deltaRadius
* ((float) j
/ loops
);
677 if (qobj
->textureCoords
) {
678 texLow
= radiusLow
/ outerRadius
/ 2;
681 glBegin(GL_LINE_STRIP
);
682 for (i
= 0; i
<= slices
; i
++) {
683 if (qobj
->textureCoords
) {
684 glTexCoord2f(texLow
* sinCache
[i
] + 0.5,
685 texLow
* cosCache
[i
] + 0.5);
687 glVertex3f(radiusLow
* sinCache
[i
],
688 radiusLow
* cosCache
[i
], 0.0);
691 if (innerRadius
== outerRadius
) break;
700 gluSphere(GLUquadric
*qobj
, GLdouble radius
, GLint slices
, GLint stacks
)
703 GLfloat sinCache1a
[CACHE_SIZE
];
704 GLfloat cosCache1a
[CACHE_SIZE
];
705 GLfloat sinCache2a
[CACHE_SIZE
];
706 GLfloat cosCache2a
[CACHE_SIZE
];
707 GLfloat sinCache3a
[CACHE_SIZE
];
708 GLfloat cosCache3a
[CACHE_SIZE
];
709 GLfloat sinCache1b
[CACHE_SIZE
];
710 GLfloat cosCache1b
[CACHE_SIZE
];
711 GLfloat sinCache2b
[CACHE_SIZE
];
712 GLfloat cosCache2b
[CACHE_SIZE
];
713 GLfloat sinCache3b
[CACHE_SIZE
];
714 GLfloat cosCache3b
[CACHE_SIZE
];
717 GLfloat sintemp1
, sintemp2
, sintemp3
, sintemp4
;
718 GLfloat costemp1
, costemp2
, costemp3
, costemp4
;
719 GLboolean needCache2
, needCache3
;
722 if (slices
>= CACHE_SIZE
) slices
= CACHE_SIZE
-1;
723 if (stacks
>= CACHE_SIZE
) stacks
= CACHE_SIZE
-1;
724 if (slices
< 2 || stacks
< 1 || radius
< 0.0) {
725 gluQuadricError(qobj
, GLU_INVALID_VALUE
);
729 /* Cache is the vertex locations cache */
730 /* Cache2 is the various normals at the vertices themselves */
731 /* Cache3 is the various normals for the faces */
732 needCache2
= needCache3
= GL_FALSE
;
734 if (qobj
->normals
== GLU_SMOOTH
) {
735 needCache2
= GL_TRUE
;
738 if (qobj
->normals
== GLU_FLAT
) {
739 if (qobj
->drawStyle
!= GLU_POINT
) {
740 needCache3
= GL_TRUE
;
742 if (qobj
->drawStyle
== GLU_LINE
) {
743 needCache2
= GL_TRUE
;
747 for (i
= 0; i
< slices
; i
++) {
748 angle
= 2 * PI
* i
/ slices
;
749 sinCache1a
[i
] = SIN(angle
);
750 cosCache1a
[i
] = COS(angle
);
752 sinCache2a
[i
] = sinCache1a
[i
];
753 cosCache2a
[i
] = cosCache1a
[i
];
757 for (j
= 0; j
<= stacks
; j
++) {
758 angle
= PI
* j
/ stacks
;
760 if (qobj
->orientation
== GLU_OUTSIDE
) {
761 sinCache2b
[j
] = SIN(angle
);
762 cosCache2b
[j
] = COS(angle
);
764 sinCache2b
[j
] = -SIN(angle
);
765 cosCache2b
[j
] = -COS(angle
);
768 sinCache1b
[j
] = radius
* SIN(angle
);
769 cosCache1b
[j
] = radius
* COS(angle
);
771 /* Make sure it comes to a point */
773 sinCache1b
[stacks
] = 0;
776 for (i
= 0; i
< slices
; i
++) {
777 angle
= 2 * PI
* (i
-0.5) / slices
;
778 sinCache3a
[i
] = SIN(angle
);
779 cosCache3a
[i
] = COS(angle
);
781 for (j
= 0; j
<= stacks
; j
++) {
782 angle
= PI
* (j
- 0.5) / stacks
;
783 if (qobj
->orientation
== GLU_OUTSIDE
) {
784 sinCache3b
[j
] = SIN(angle
);
785 cosCache3b
[j
] = COS(angle
);
787 sinCache3b
[j
] = -SIN(angle
);
788 cosCache3b
[j
] = -COS(angle
);
793 sinCache1a
[slices
] = sinCache1a
[0];
794 cosCache1a
[slices
] = cosCache1a
[0];
796 sinCache2a
[slices
] = sinCache2a
[0];
797 cosCache2a
[slices
] = cosCache2a
[0];
800 sinCache3a
[slices
] = sinCache3a
[0];
801 cosCache3a
[slices
] = cosCache3a
[0];
804 switch (qobj
->drawStyle
) {
806 /* Do ends of sphere as TRIANGLE_FAN's (if not texturing)
807 ** We don't do it when texturing because we need to respecify the
808 ** texture coordinates of the apex for every adjacent vertex (because
809 ** it isn't a constant for that point)
811 if (!(qobj
->textureCoords
)) {
815 /* Low end first (j == 0 iteration) */
816 sintemp2
= sinCache1b
[1];
817 zHigh
= cosCache1b
[1];
818 switch(qobj
->normals
) {
820 sintemp3
= sinCache3b
[1];
821 costemp3
= cosCache3b
[1];
824 sintemp3
= sinCache2b
[1];
825 costemp3
= cosCache2b
[1];
826 glNormal3f(sinCache2a
[0] * sinCache2b
[0],
827 cosCache2a
[0] * sinCache2b
[0],
833 glBegin(GL_TRIANGLE_FAN
);
834 glVertex3f(0.0, 0.0, radius
);
835 if (qobj
->orientation
== GLU_OUTSIDE
) {
836 for (i
= slices
; i
>= 0; i
--) {
837 switch(qobj
->normals
) {
839 glNormal3f(sinCache2a
[i
] * sintemp3
,
840 cosCache2a
[i
] * sintemp3
,
845 glNormal3f(sinCache3a
[i
+1] * sintemp3
,
846 cosCache3a
[i
+1] * sintemp3
,
854 glVertex3f(sintemp2
* sinCache1a
[i
],
855 sintemp2
* cosCache1a
[i
], zHigh
);
858 for (i
= 0; i
<= slices
; i
++) {
859 switch(qobj
->normals
) {
861 glNormal3f(sinCache2a
[i
] * sintemp3
,
862 cosCache2a
[i
] * sintemp3
,
866 glNormal3f(sinCache3a
[i
] * sintemp3
,
867 cosCache3a
[i
] * sintemp3
,
874 glVertex3f(sintemp2
* sinCache1a
[i
],
875 sintemp2
* cosCache1a
[i
], zHigh
);
880 /* High end next (j == stacks-1 iteration) */
881 sintemp2
= sinCache1b
[stacks
-1];
882 zHigh
= cosCache1b
[stacks
-1];
883 switch(qobj
->normals
) {
885 sintemp3
= sinCache3b
[stacks
];
886 costemp3
= cosCache3b
[stacks
];
889 sintemp3
= sinCache2b
[stacks
-1];
890 costemp3
= cosCache2b
[stacks
-1];
891 glNormal3f(sinCache2a
[stacks
] * sinCache2b
[stacks
],
892 cosCache2a
[stacks
] * sinCache2b
[stacks
],
898 glBegin(GL_TRIANGLE_FAN
);
899 glVertex3f(0.0, 0.0, -radius
);
900 if (qobj
->orientation
== GLU_OUTSIDE
) {
901 for (i
= 0; i
<= slices
; i
++) {
902 switch(qobj
->normals
) {
904 glNormal3f(sinCache2a
[i
] * sintemp3
,
905 cosCache2a
[i
] * sintemp3
,
909 glNormal3f(sinCache3a
[i
] * sintemp3
,
910 cosCache3a
[i
] * sintemp3
,
917 glVertex3f(sintemp2
* sinCache1a
[i
],
918 sintemp2
* cosCache1a
[i
], zHigh
);
921 for (i
= slices
; i
>= 0; i
--) {
922 switch(qobj
->normals
) {
924 glNormal3f(sinCache2a
[i
] * sintemp3
,
925 cosCache2a
[i
] * sintemp3
,
930 glNormal3f(sinCache3a
[i
+1] * sintemp3
,
931 cosCache3a
[i
+1] * sintemp3
,
939 glVertex3f(sintemp2
* sinCache1a
[i
],
940 sintemp2
* cosCache1a
[i
], zHigh
);
948 for (j
= start
; j
< finish
; j
++) {
949 zLow
= cosCache1b
[j
];
950 zHigh
= cosCache1b
[j
+1];
951 sintemp1
= sinCache1b
[j
];
952 sintemp2
= sinCache1b
[j
+1];
953 switch(qobj
->normals
) {
955 sintemp4
= sinCache3b
[j
+1];
956 costemp4
= cosCache3b
[j
+1];
959 if (qobj
->orientation
== GLU_OUTSIDE
) {
960 sintemp3
= sinCache2b
[j
+1];
961 costemp3
= cosCache2b
[j
+1];
962 sintemp4
= sinCache2b
[j
];
963 costemp4
= cosCache2b
[j
];
965 sintemp3
= sinCache2b
[j
];
966 costemp3
= cosCache2b
[j
];
967 sintemp4
= sinCache2b
[j
+1];
968 costemp4
= cosCache2b
[j
+1];
975 glBegin(GL_QUAD_STRIP
);
976 for (i
= 0; i
<= slices
; i
++) {
977 switch(qobj
->normals
) {
979 glNormal3f(sinCache2a
[i
] * sintemp3
,
980 cosCache2a
[i
] * sintemp3
,
988 if (qobj
->orientation
== GLU_OUTSIDE
) {
989 if (qobj
->textureCoords
) {
990 glTexCoord2f(1 - (float) i
/ slices
,
991 1 - (float) (j
+1) / stacks
);
993 glVertex3f(sintemp2
* sinCache1a
[i
],
994 sintemp2
* cosCache1a
[i
], zHigh
);
996 if (qobj
->textureCoords
) {
997 glTexCoord2f(1 - (float) i
/ slices
,
998 1 - (float) j
/ stacks
);
1000 glVertex3f(sintemp1
* sinCache1a
[i
],
1001 sintemp1
* cosCache1a
[i
], zLow
);
1003 switch(qobj
->normals
) {
1005 glNormal3f(sinCache2a
[i
] * sintemp4
,
1006 cosCache2a
[i
] * sintemp4
,
1010 glNormal3f(sinCache3a
[i
] * sintemp4
,
1011 cosCache3a
[i
] * sintemp4
,
1018 if (qobj
->orientation
== GLU_OUTSIDE
) {
1019 if (qobj
->textureCoords
) {
1020 glTexCoord2f(1 - (float) i
/ slices
,
1021 1 - (float) j
/ stacks
);
1023 glVertex3f(sintemp1
* sinCache1a
[i
],
1024 sintemp1
* cosCache1a
[i
], zLow
);
1026 if (qobj
->textureCoords
) {
1027 glTexCoord2f(1 - (float) i
/ slices
,
1028 1 - (float) (j
+1) / stacks
);
1030 glVertex3f(sintemp2
* sinCache1a
[i
],
1031 sintemp2
* cosCache1a
[i
], zHigh
);
1039 for (j
= 0; j
<= stacks
; j
++) {
1040 sintemp1
= sinCache1b
[j
];
1041 costemp1
= cosCache1b
[j
];
1042 switch(qobj
->normals
) {
1045 sintemp2
= sinCache2b
[j
];
1046 costemp2
= cosCache2b
[j
];
1051 for (i
= 0; i
< slices
; i
++) {
1052 switch(qobj
->normals
) {
1055 glNormal3f(sinCache2a
[i
] * sintemp2
,
1056 cosCache2a
[i
] * sintemp2
,
1064 zLow
= j
* radius
/ stacks
;
1066 if (qobj
->textureCoords
) {
1067 glTexCoord2f(1 - (float) i
/ slices
,
1068 1 - (float) j
/ stacks
);
1070 glVertex3f(sintemp1
* sinCache1a
[i
],
1071 sintemp1
* cosCache1a
[i
], costemp1
);
1077 case GLU_SILHOUETTE
:
1078 for (j
= 1; j
< stacks
; j
++) {
1079 sintemp1
= sinCache1b
[j
];
1080 costemp1
= cosCache1b
[j
];
1081 switch(qobj
->normals
) {
1084 sintemp2
= sinCache2b
[j
];
1085 costemp2
= cosCache2b
[j
];
1091 glBegin(GL_LINE_STRIP
);
1092 for (i
= 0; i
<= slices
; i
++) {
1093 switch(qobj
->normals
) {
1095 glNormal3f(sinCache3a
[i
] * sintemp2
,
1096 cosCache3a
[i
] * sintemp2
,
1100 glNormal3f(sinCache2a
[i
] * sintemp2
,
1101 cosCache2a
[i
] * sintemp2
,
1108 if (qobj
->textureCoords
) {
1109 glTexCoord2f(1 - (float) i
/ slices
,
1110 1 - (float) j
/ stacks
);
1112 glVertex3f(sintemp1
* sinCache1a
[i
],
1113 sintemp1
* cosCache1a
[i
], costemp1
);
1117 for (i
= 0; i
< slices
; i
++) {
1118 sintemp1
= sinCache1a
[i
];
1119 costemp1
= cosCache1a
[i
];
1120 switch(qobj
->normals
) {
1123 sintemp2
= sinCache2a
[i
];
1124 costemp2
= cosCache2a
[i
];
1130 glBegin(GL_LINE_STRIP
);
1131 for (j
= 0; j
<= stacks
; j
++) {
1132 switch(qobj
->normals
) {
1134 glNormal3f(sintemp2
* sinCache3b
[j
],
1135 costemp2
* sinCache3b
[j
],
1139 glNormal3f(sintemp2
* sinCache2b
[j
],
1140 costemp2
* sinCache2b
[j
],
1148 if (qobj
->textureCoords
) {
1149 glTexCoord2f(1 - (float) i
/ slices
,
1150 1 - (float) j
/ stacks
);
1152 glVertex3f(sintemp1
* sinCache1b
[j
],
1153 costemp1
* sinCache1b
[j
], cosCache1b
[j
]);