2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice including the dates of first publication and
13 * either this permission notice or a reference to
14 * http://oss.sgi.com/projects/FreeB/
15 * shall be included in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * Except as contained in this notice, the name of Silicon Graphics, Inc.
26 * shall not be used in advertising or otherwise to promote the sale, use or
27 * other dealings in this Software without prior written authorization from
28 * Silicon Graphics, Inc.
39 /* Make it not a power of two to avoid cache thrashing on the chip */
40 #define CACHE_SIZE 240
43 #define PI 3.14159265358979323846
47 GLboolean textureCoords;
50 void (GLAPIENTRY *errorCallback)( GLint );
53 GLUquadric * GLAPIENTRY
58 newstate = (GLUquadric *) malloc(sizeof(GLUquadric));
59 if (newstate == NULL) {
60 /* Can't report an error at this point... */
63 newstate->normals = GLU_SMOOTH;
64 newstate->textureCoords = GL_FALSE;
65 newstate->orientation = GLU_OUTSIDE;
66 newstate->drawStyle = GLU_FILL;
67 newstate->errorCallback = NULL;
73 gluDeleteQuadric(GLUquadric *state)
78 static void gluQuadricError(GLUquadric *qobj, GLenum which)
80 if (qobj->errorCallback) {
81 qobj->errorCallback(which);
86 gluQuadricCallback(GLUquadric *qobj, GLenum which, _GLUfuncptr fn)
90 qobj->errorCallback = (void (GLAPIENTRY *)(GLint)) fn;
93 gluQuadricError(qobj, GLU_INVALID_ENUM);
99 gluQuadricNormals(GLUquadric *qobj, GLenum normals)
107 gluQuadricError(qobj, GLU_INVALID_ENUM);
110 qobj->normals = normals;
114 gluQuadricTexture(GLUquadric *qobj, GLboolean textureCoords)
116 qobj->textureCoords = textureCoords;
120 gluQuadricOrientation(GLUquadric *qobj, GLenum orientation)
122 switch(orientation) {
127 gluQuadricError(qobj, GLU_INVALID_ENUM);
130 qobj->orientation = orientation;
134 gluQuadricDrawStyle(GLUquadric *qobj, GLenum drawStyle)
143 gluQuadricError(qobj, GLU_INVALID_ENUM);
146 qobj->drawStyle = drawStyle;
150 gluCylinder(GLUquadric *qobj, GLdouble baseRadius, GLdouble topRadius,
151 GLdouble height, GLint slices, GLint stacks)
154 GLfloat sinCache[CACHE_SIZE];
155 GLfloat cosCache[CACHE_SIZE];
156 GLfloat sinCache2[CACHE_SIZE];
157 GLfloat cosCache2[CACHE_SIZE];
158 GLfloat sinCache3[CACHE_SIZE];
159 GLfloat cosCache3[CACHE_SIZE];
162 GLfloat sintemp, costemp;
166 GLfloat xyNormalRatio;
167 GLfloat radiusLow, radiusHigh;
168 int needCache2, needCache3;
170 if (slices >= CACHE_SIZE) slices = CACHE_SIZE-1;
172 if (slices < 2 || stacks < 1 || baseRadius < 0.0 || topRadius < 0.0 ||
174 gluQuadricError(qobj, GLU_INVALID_VALUE);
178 /* Compute length (needed for normal calculations) */
179 deltaRadius = baseRadius - topRadius;
180 length = SQRT(deltaRadius*deltaRadius + height*height);
182 gluQuadricError(qobj, GLU_INVALID_VALUE);
186 /* Cache is the vertex locations cache */
187 /* Cache2 is the various normals at the vertices themselves */
188 /* Cache3 is the various normals for the faces */
189 needCache2 = needCache3 = 0;
190 if (qobj->normals == GLU_SMOOTH) {
194 if (qobj->normals == GLU_FLAT) {
195 if (qobj->drawStyle != GLU_POINT) {
198 if (qobj->drawStyle == GLU_LINE) {
203 zNormal = deltaRadius / length;
204 xyNormalRatio = height / length;
206 for (i = 0; i < slices; i++) {
207 angle = 2 * PI * i / slices;
209 if (qobj->orientation == GLU_OUTSIDE) {
210 sinCache2[i] = xyNormalRatio * SIN(angle);
211 cosCache2[i] = xyNormalRatio * COS(angle);
213 sinCache2[i] = -xyNormalRatio * SIN(angle);
214 cosCache2[i] = -xyNormalRatio * COS(angle);
217 sinCache[i] = SIN(angle);
218 cosCache[i] = COS(angle);
222 for (i = 0; i < slices; i++) {
223 angle = 2 * PI * (i-0.5) / slices;
224 if (qobj->orientation == GLU_OUTSIDE) {
225 sinCache3[i] = xyNormalRatio * SIN(angle);
226 cosCache3[i] = xyNormalRatio * COS(angle);
228 sinCache3[i] = -xyNormalRatio * SIN(angle);
229 cosCache3[i] = -xyNormalRatio * COS(angle);
234 sinCache[slices] = sinCache[0];
235 cosCache[slices] = cosCache[0];
237 sinCache2[slices] = sinCache2[0];
238 cosCache2[slices] = cosCache2[0];
241 sinCache3[slices] = sinCache3[0];
242 cosCache3[slices] = cosCache3[0];
245 switch (qobj->drawStyle) {
248 ** An argument could be made for using a TRIANGLE_FAN for the end
249 ** of the cylinder of either radii is 0.0 (a cone). However, a
250 ** TRIANGLE_FAN would not work in smooth shading mode (the common
251 ** case) because the normal for the apex is different for every
252 ** triangle (and TRIANGLE_FAN doesn't let me respecify that normal).
253 ** Now, my choice is GL_TRIANGLES, or leave the GL_QUAD_STRIP and
254 ** just let the GL trivially reject one of the two triangles of the
255 ** QUAD. GL_QUAD_STRIP is probably faster, so I will leave this code
258 for (j = 0; j < stacks; j++) {
259 zLow = j * height / stacks;
260 zHigh = (j + 1) * height / stacks;
261 radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
262 radiusHigh = baseRadius - deltaRadius * ((float) (j + 1) / stacks);
264 glBegin(GL_QUAD_STRIP);
265 for (i = 0; i <= slices; i++) {
266 switch(qobj->normals) {
268 glNormal3f(sinCache3[i], cosCache3[i], zNormal);
271 glNormal3f(sinCache2[i], cosCache2[i], zNormal);
277 if (qobj->orientation == GLU_OUTSIDE) {
278 if (qobj->textureCoords) {
279 glTexCoord2f(1 - (float) i / slices,
282 glVertex3f(radiusLow * sinCache[i],
283 radiusLow * cosCache[i], zLow);
284 if (qobj->textureCoords) {
285 glTexCoord2f(1 - (float) i / slices,
286 (float) (j+1) / stacks);
288 glVertex3f(radiusHigh * sinCache[i],
289 radiusHigh * cosCache[i], zHigh);
291 if (qobj->textureCoords) {
292 glTexCoord2f(1 - (float) i / slices,
293 (float) (j+1) / stacks);
295 glVertex3f(radiusHigh * sinCache[i],
296 radiusHigh * cosCache[i], zHigh);
297 if (qobj->textureCoords) {
298 glTexCoord2f(1 - (float) i / slices,
301 glVertex3f(radiusLow * sinCache[i],
302 radiusLow * cosCache[i], zLow);
310 for (i = 0; i < slices; i++) {
311 switch(qobj->normals) {
314 glNormal3f(sinCache2[i], cosCache2[i], zNormal);
320 sintemp = sinCache[i];
321 costemp = cosCache[i];
322 for (j = 0; j <= stacks; j++) {
323 zLow = j * height / stacks;
324 radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
326 if (qobj->textureCoords) {
327 glTexCoord2f(1 - (float) i / slices,
330 glVertex3f(radiusLow * sintemp,
331 radiusLow * costemp, zLow);
337 for (j = 1; j < stacks; j++) {
338 zLow = j * height / stacks;
339 radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
341 glBegin(GL_LINE_STRIP);
342 for (i = 0; i <= slices; i++) {
343 switch(qobj->normals) {
345 glNormal3f(sinCache3[i], cosCache3[i], zNormal);
348 glNormal3f(sinCache2[i], cosCache2[i], zNormal);
354 if (qobj->textureCoords) {
355 glTexCoord2f(1 - (float) i / slices,
358 glVertex3f(radiusLow * sinCache[i],
359 radiusLow * cosCache[i], zLow);
363 /* Intentionally fall through here... */
365 for (j = 0; j <= stacks; j += stacks) {
366 zLow = j * height / stacks;
367 radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
369 glBegin(GL_LINE_STRIP);
370 for (i = 0; i <= slices; i++) {
371 switch(qobj->normals) {
373 glNormal3f(sinCache3[i], cosCache3[i], zNormal);
376 glNormal3f(sinCache2[i], cosCache2[i], zNormal);
382 if (qobj->textureCoords) {
383 glTexCoord2f(1 - (float) i / slices,
386 glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i],
391 for (i = 0; i < slices; i++) {
392 switch(qobj->normals) {
395 glNormal3f(sinCache2[i], cosCache2[i], 0.0);
401 sintemp = sinCache[i];
402 costemp = cosCache[i];
403 glBegin(GL_LINE_STRIP);
404 for (j = 0; j <= stacks; j++) {
405 zLow = j * height / stacks;
406 radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
408 if (qobj->textureCoords) {
409 glTexCoord2f(1 - (float) i / slices,
412 glVertex3f(radiusLow * sintemp,
413 radiusLow * costemp, zLow);
424 gluDisk(GLUquadric *qobj, GLdouble innerRadius, GLdouble outerRadius,
425 GLint slices, GLint loops)
427 gluPartialDisk(qobj, innerRadius, outerRadius, slices, loops, 0.0, 360.0);
431 gluPartialDisk(GLUquadric *qobj, GLdouble innerRadius,
432 GLdouble outerRadius, GLint slices, GLint loops,
433 GLdouble startAngle, GLdouble sweepAngle)
436 GLfloat sinCache[CACHE_SIZE];
437 GLfloat cosCache[CACHE_SIZE];
439 GLfloat sintemp, costemp;
441 GLfloat radiusLow, radiusHigh;
442 GLfloat texLow = 0.0, texHigh = 0.0;
447 if (slices >= CACHE_SIZE) slices = CACHE_SIZE-1;
448 if (slices < 2 || loops < 1 || outerRadius <= 0.0 || innerRadius < 0.0 ||
449 innerRadius > outerRadius) {
450 gluQuadricError(qobj, GLU_INVALID_VALUE);
454 if (sweepAngle < -360.0) sweepAngle = 360.0;
455 if (sweepAngle > 360.0) sweepAngle = 360.0;
456 if (sweepAngle < 0) {
457 startAngle += sweepAngle;
458 sweepAngle = -sweepAngle;
461 if (sweepAngle == 360.0) {
464 slices2 = slices + 1;
467 /* Compute length (needed for normal calculations) */
468 deltaRadius = outerRadius - innerRadius;
470 /* Cache is the vertex locations cache */
472 angleOffset = startAngle / 180.0 * PI;
473 for (i = 0; i <= slices; i++) {
474 angle = angleOffset + ((PI * sweepAngle) / 180.0) * i / slices;
475 sinCache[i] = SIN(angle);
476 cosCache[i] = COS(angle);
479 if (sweepAngle == 360.0) {
480 sinCache[slices] = sinCache[0];
481 cosCache[slices] = cosCache[0];
484 switch(qobj->normals) {
487 if (qobj->orientation == GLU_OUTSIDE) {
488 glNormal3f(0.0, 0.0, 1.0);
490 glNormal3f(0.0, 0.0, -1.0);
498 switch (qobj->drawStyle) {
500 if (innerRadius == 0.0) {
502 /* Triangle strip for inner polygons */
503 glBegin(GL_TRIANGLE_FAN);
504 if (qobj->textureCoords) {
505 glTexCoord2f(0.5, 0.5);
507 glVertex3f(0.0, 0.0, 0.0);
508 radiusLow = outerRadius -
509 deltaRadius * ((float) (loops-1) / loops);
510 if (qobj->textureCoords) {
511 texLow = radiusLow / outerRadius / 2;
514 if (qobj->orientation == GLU_OUTSIDE) {
515 for (i = slices; i >= 0; i--) {
516 if (qobj->textureCoords) {
517 glTexCoord2f(texLow * sinCache[i] + 0.5,
518 texLow * cosCache[i] + 0.5);
520 glVertex3f(radiusLow * sinCache[i],
521 radiusLow * cosCache[i], 0.0);
524 for (i = 0; i <= slices; i++) {
525 if (qobj->textureCoords) {
526 glTexCoord2f(texLow * sinCache[i] + 0.5,
527 texLow * cosCache[i] + 0.5);
529 glVertex3f(radiusLow * sinCache[i],
530 radiusLow * cosCache[i], 0.0);
537 for (j = 0; j < finish; j++) {
538 radiusLow = outerRadius - deltaRadius * ((float) j / loops);
539 radiusHigh = outerRadius - deltaRadius * ((float) (j + 1) / loops);
540 if (qobj->textureCoords) {
541 texLow = radiusLow / outerRadius / 2;
542 texHigh = radiusHigh / outerRadius / 2;
545 glBegin(GL_QUAD_STRIP);
546 for (i = 0; i <= slices; i++) {
547 if (qobj->orientation == GLU_OUTSIDE) {
548 if (qobj->textureCoords) {
549 glTexCoord2f(texLow * sinCache[i] + 0.5,
550 texLow * cosCache[i] + 0.5);
552 glVertex3f(radiusLow * sinCache[i],
553 radiusLow * cosCache[i], 0.0);
555 if (qobj->textureCoords) {
556 glTexCoord2f(texHigh * sinCache[i] + 0.5,
557 texHigh * cosCache[i] + 0.5);
559 glVertex3f(radiusHigh * sinCache[i],
560 radiusHigh * cosCache[i], 0.0);
562 if (qobj->textureCoords) {
563 glTexCoord2f(texHigh * sinCache[i] + 0.5,
564 texHigh * cosCache[i] + 0.5);
566 glVertex3f(radiusHigh * sinCache[i],
567 radiusHigh * cosCache[i], 0.0);
569 if (qobj->textureCoords) {
570 glTexCoord2f(texLow * sinCache[i] + 0.5,
571 texLow * cosCache[i] + 0.5);
573 glVertex3f(radiusLow * sinCache[i],
574 radiusLow * cosCache[i], 0.0);
582 for (i = 0; i < slices2; i++) {
583 sintemp = sinCache[i];
584 costemp = cosCache[i];
585 for (j = 0; j <= loops; j++) {
586 radiusLow = outerRadius - deltaRadius * ((float) j / loops);
588 if (qobj->textureCoords) {
589 texLow = radiusLow / outerRadius / 2;
591 glTexCoord2f(texLow * sinCache[i] + 0.5,
592 texLow * cosCache[i] + 0.5);
594 glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0);
600 if (innerRadius == outerRadius) {
601 glBegin(GL_LINE_STRIP);
603 for (i = 0; i <= slices; i++) {
604 if (qobj->textureCoords) {
605 glTexCoord2f(sinCache[i] / 2 + 0.5,
606 cosCache[i] / 2 + 0.5);
608 glVertex3f(innerRadius * sinCache[i],
609 innerRadius * cosCache[i], 0.0);
614 for (j = 0; j <= loops; j++) {
615 radiusLow = outerRadius - deltaRadius * ((float) j / loops);
616 if (qobj->textureCoords) {
617 texLow = radiusLow / outerRadius / 2;
620 glBegin(GL_LINE_STRIP);
621 for (i = 0; i <= slices; i++) {
622 if (qobj->textureCoords) {
623 glTexCoord2f(texLow * sinCache[i] + 0.5,
624 texLow * cosCache[i] + 0.5);
626 glVertex3f(radiusLow * sinCache[i],
627 radiusLow * cosCache[i], 0.0);
631 for (i=0; i < slices2; i++) {
632 sintemp = sinCache[i];
633 costemp = cosCache[i];
634 glBegin(GL_LINE_STRIP);
635 for (j = 0; j <= loops; j++) {
636 radiusLow = outerRadius - deltaRadius * ((float) j / loops);
637 if (qobj->textureCoords) {
638 texLow = radiusLow / outerRadius / 2;
641 if (qobj->textureCoords) {
642 glTexCoord2f(texLow * sinCache[i] + 0.5,
643 texLow * cosCache[i] + 0.5);
645 glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0);
651 if (sweepAngle < 360.0) {
652 for (i = 0; i <= slices; i+= slices) {
653 sintemp = sinCache[i];
654 costemp = cosCache[i];
655 glBegin(GL_LINE_STRIP);
656 for (j = 0; j <= loops; j++) {
657 radiusLow = outerRadius - deltaRadius * ((float) j / loops);
659 if (qobj->textureCoords) {
660 texLow = radiusLow / outerRadius / 2;
661 glTexCoord2f(texLow * sinCache[i] + 0.5,
662 texLow * cosCache[i] + 0.5);
664 glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0);
669 for (j = 0; j <= loops; j += loops) {
670 radiusLow = outerRadius - deltaRadius * ((float) j / loops);
671 if (qobj->textureCoords) {
672 texLow = radiusLow / outerRadius / 2;
675 glBegin(GL_LINE_STRIP);
676 for (i = 0; i <= slices; i++) {
677 if (qobj->textureCoords) {
678 glTexCoord2f(texLow * sinCache[i] + 0.5,
679 texLow * cosCache[i] + 0.5);
681 glVertex3f(radiusLow * sinCache[i],
682 radiusLow * cosCache[i], 0.0);
685 if (innerRadius == outerRadius) break;
694 gluSphere(GLUquadric *qobj, GLdouble radius, GLint slices, GLint stacks)
697 GLfloat sinCache1a[CACHE_SIZE];
698 GLfloat cosCache1a[CACHE_SIZE];
699 GLfloat sinCache2a[CACHE_SIZE];
700 GLfloat cosCache2a[CACHE_SIZE];
701 GLfloat sinCache3a[CACHE_SIZE];
702 GLfloat cosCache3a[CACHE_SIZE];
703 GLfloat sinCache1b[CACHE_SIZE];
704 GLfloat cosCache1b[CACHE_SIZE];
705 GLfloat sinCache2b[CACHE_SIZE];
706 GLfloat cosCache2b[CACHE_SIZE];
707 GLfloat sinCache3b[CACHE_SIZE];
708 GLfloat cosCache3b[CACHE_SIZE];
711 GLfloat sintemp1 = 0.0, sintemp2 = 0.0, sintemp3 = 0.0, sintemp4 = 0.0;
712 GLfloat costemp1 = 0.0, costemp2 = 0.0, costemp3 = 0.0, costemp4 = 0.0;
713 GLboolean needCache2, needCache3;
716 if (slices >= CACHE_SIZE) slices = CACHE_SIZE-1;
717 if (stacks >= CACHE_SIZE) stacks = CACHE_SIZE-1;
718 if (slices < 2 || stacks < 1 || radius < 0.0) {
719 gluQuadricError(qobj, GLU_INVALID_VALUE);
723 /* Cache is the vertex locations cache */
724 /* Cache2 is the various normals at the vertices themselves */
725 /* Cache3 is the various normals for the faces */
726 needCache2 = needCache3 = GL_FALSE;
728 if (qobj->normals == GLU_SMOOTH) {
729 needCache2 = GL_TRUE;
732 if (qobj->normals == GLU_FLAT) {
733 if (qobj->drawStyle != GLU_POINT) {
734 needCache3 = GL_TRUE;
736 if (qobj->drawStyle == GLU_LINE) {
737 needCache2 = GL_TRUE;
741 for (i = 0; i < slices; i++) {
742 angle = 2 * PI * i / slices;
743 sinCache1a[i] = SIN(angle);
744 cosCache1a[i] = COS(angle);
746 sinCache2a[i] = sinCache1a[i];
747 cosCache2a[i] = cosCache1a[i];
751 for (j = 0; j <= stacks; j++) {
752 angle = PI * j / stacks;
754 if (qobj->orientation == GLU_OUTSIDE) {
755 sinCache2b[j] = SIN(angle);
756 cosCache2b[j] = COS(angle);
758 sinCache2b[j] = -SIN(angle);
759 cosCache2b[j] = -COS(angle);
762 sinCache1b[j] = radius * SIN(angle);
763 cosCache1b[j] = radius * COS(angle);
765 /* Make sure it comes to a point */
767 sinCache1b[stacks] = 0;
770 for (i = 0; i < slices; i++) {
771 angle = 2 * PI * (i-0.5) / slices;
772 sinCache3a[i] = SIN(angle);
773 cosCache3a[i] = COS(angle);
775 for (j = 0; j <= stacks; j++) {
776 angle = PI * (j - 0.5) / stacks;
777 if (qobj->orientation == GLU_OUTSIDE) {
778 sinCache3b[j] = SIN(angle);
779 cosCache3b[j] = COS(angle);
781 sinCache3b[j] = -SIN(angle);
782 cosCache3b[j] = -COS(angle);
787 sinCache1a[slices] = sinCache1a[0];
788 cosCache1a[slices] = cosCache1a[0];
790 sinCache2a[slices] = sinCache2a[0];
791 cosCache2a[slices] = cosCache2a[0];
794 sinCache3a[slices] = sinCache3a[0];
795 cosCache3a[slices] = cosCache3a[0];
798 switch (qobj->drawStyle) {
800 /* Do ends of sphere as TRIANGLE_FAN's (if not texturing)
801 ** We don't do it when texturing because we need to respecify the
802 ** texture coordinates of the apex for every adjacent vertex (because
803 ** it isn't a constant for that point)
805 if (!(qobj->textureCoords)) {
809 /* Low end first (j == 0 iteration) */
810 sintemp2 = sinCache1b[1];
811 zHigh = cosCache1b[1];
812 switch(qobj->normals) {
814 sintemp3 = sinCache3b[1];
815 costemp3 = cosCache3b[1];
818 sintemp3 = sinCache2b[1];
819 costemp3 = cosCache2b[1];
820 glNormal3f(sinCache2a[0] * sinCache2b[0],
821 cosCache2a[0] * sinCache2b[0],
827 glBegin(GL_TRIANGLE_FAN);
828 glVertex3f(0.0, 0.0, radius);
829 if (qobj->orientation == GLU_OUTSIDE) {
830 for (i = slices; i >= 0; i--) {
831 switch(qobj->normals) {
833 glNormal3f(sinCache2a[i] * sintemp3,
834 cosCache2a[i] * sintemp3,
839 glNormal3f(sinCache3a[i+1] * sintemp3,
840 cosCache3a[i+1] * sintemp3,
848 glVertex3f(sintemp2 * sinCache1a[i],
849 sintemp2 * cosCache1a[i], zHigh);
852 for (i = 0; i <= slices; i++) {
853 switch(qobj->normals) {
855 glNormal3f(sinCache2a[i] * sintemp3,
856 cosCache2a[i] * sintemp3,
860 glNormal3f(sinCache3a[i] * sintemp3,
861 cosCache3a[i] * sintemp3,
868 glVertex3f(sintemp2 * sinCache1a[i],
869 sintemp2 * cosCache1a[i], zHigh);
874 /* High end next (j == stacks-1 iteration) */
875 sintemp2 = sinCache1b[stacks-1];
876 zHigh = cosCache1b[stacks-1];
877 switch(qobj->normals) {
879 sintemp3 = sinCache3b[stacks];
880 costemp3 = cosCache3b[stacks];
883 sintemp3 = sinCache2b[stacks-1];
884 costemp3 = cosCache2b[stacks-1];
885 glNormal3f(sinCache2a[stacks] * sinCache2b[stacks],
886 cosCache2a[stacks] * sinCache2b[stacks],
892 glBegin(GL_TRIANGLE_FAN);
893 glVertex3f(0.0, 0.0, -radius);
894 if (qobj->orientation == GLU_OUTSIDE) {
895 for (i = 0; i <= slices; i++) {
896 switch(qobj->normals) {
898 glNormal3f(sinCache2a[i] * sintemp3,
899 cosCache2a[i] * sintemp3,
903 glNormal3f(sinCache3a[i] * sintemp3,
904 cosCache3a[i] * sintemp3,
911 glVertex3f(sintemp2 * sinCache1a[i],
912 sintemp2 * cosCache1a[i], zHigh);
915 for (i = slices; i >= 0; i--) {
916 switch(qobj->normals) {
918 glNormal3f(sinCache2a[i] * sintemp3,
919 cosCache2a[i] * sintemp3,
924 glNormal3f(sinCache3a[i+1] * sintemp3,
925 cosCache3a[i+1] * sintemp3,
933 glVertex3f(sintemp2 * sinCache1a[i],
934 sintemp2 * cosCache1a[i], zHigh);
942 for (j = start; j < finish; j++) {
943 zLow = cosCache1b[j];
944 zHigh = cosCache1b[j+1];
945 sintemp1 = sinCache1b[j];
946 sintemp2 = sinCache1b[j+1];
947 switch(qobj->normals) {
949 sintemp4 = sinCache3b[j+1];
950 costemp4 = cosCache3b[j+1];
953 if (qobj->orientation == GLU_OUTSIDE) {
954 sintemp3 = sinCache2b[j+1];
955 costemp3 = cosCache2b[j+1];
956 sintemp4 = sinCache2b[j];
957 costemp4 = cosCache2b[j];
959 sintemp3 = sinCache2b[j];
960 costemp3 = cosCache2b[j];
961 sintemp4 = sinCache2b[j+1];
962 costemp4 = cosCache2b[j+1];
969 glBegin(GL_QUAD_STRIP);
970 for (i = 0; i <= slices; i++) {
971 switch(qobj->normals) {
973 glNormal3f(sinCache2a[i] * sintemp3,
974 cosCache2a[i] * sintemp3,
982 if (qobj->orientation == GLU_OUTSIDE) {
983 if (qobj->textureCoords) {
984 glTexCoord2f(1 - (float) i / slices,
985 1 - (float) (j+1) / stacks);
987 glVertex3f(sintemp2 * sinCache1a[i],
988 sintemp2 * cosCache1a[i], zHigh);
990 if (qobj->textureCoords) {
991 glTexCoord2f(1 - (float) i / slices,
992 1 - (float) j / stacks);
994 glVertex3f(sintemp1 * sinCache1a[i],
995 sintemp1 * cosCache1a[i], zLow);
997 switch(qobj->normals) {
999 glNormal3f(sinCache2a[i] * sintemp4,
1000 cosCache2a[i] * sintemp4,
1004 glNormal3f(sinCache3a[i] * sintemp4,
1005 cosCache3a[i] * sintemp4,
1012 if (qobj->orientation == GLU_OUTSIDE) {
1013 if (qobj->textureCoords) {
1014 glTexCoord2f(1 - (float) i / slices,
1015 1 - (float) j / stacks);
1017 glVertex3f(sintemp1 * sinCache1a[i],
1018 sintemp1 * cosCache1a[i], zLow);
1020 if (qobj->textureCoords) {
1021 glTexCoord2f(1 - (float) i / slices,
1022 1 - (float) (j+1) / stacks);
1024 glVertex3f(sintemp2 * sinCache1a[i],
1025 sintemp2 * cosCache1a[i], zHigh);
1033 for (j = 0; j <= stacks; j++) {
1034 sintemp1 = sinCache1b[j];
1035 costemp1 = cosCache1b[j];
1036 switch(qobj->normals) {
1039 sintemp2 = sinCache2b[j];
1040 costemp2 = cosCache2b[j];
1045 for (i = 0; i < slices; i++) {
1046 switch(qobj->normals) {
1049 glNormal3f(sinCache2a[i] * sintemp2,
1050 cosCache2a[i] * sintemp2,
1058 zLow = j * radius / stacks;
1060 if (qobj->textureCoords) {
1061 glTexCoord2f(1 - (float) i / slices,
1062 1 - (float) j / stacks);
1064 glVertex3f(sintemp1 * sinCache1a[i],
1065 sintemp1 * cosCache1a[i], costemp1);
1071 case GLU_SILHOUETTE:
1072 for (j = 1; j < stacks; j++) {
1073 sintemp1 = sinCache1b[j];
1074 costemp1 = cosCache1b[j];
1075 switch(qobj->normals) {
1078 sintemp2 = sinCache2b[j];
1079 costemp2 = cosCache2b[j];
1085 glBegin(GL_LINE_STRIP);
1086 for (i = 0; i <= slices; i++) {
1087 switch(qobj->normals) {
1089 glNormal3f(sinCache3a[i] * sintemp2,
1090 cosCache3a[i] * sintemp2,
1094 glNormal3f(sinCache2a[i] * sintemp2,
1095 cosCache2a[i] * sintemp2,
1102 if (qobj->textureCoords) {
1103 glTexCoord2f(1 - (float) i / slices,
1104 1 - (float) j / stacks);
1106 glVertex3f(sintemp1 * sinCache1a[i],
1107 sintemp1 * cosCache1a[i], costemp1);
1111 for (i = 0; i < slices; i++) {
1112 sintemp1 = sinCache1a[i];
1113 costemp1 = cosCache1a[i];
1114 switch(qobj->normals) {
1117 sintemp2 = sinCache2a[i];
1118 costemp2 = cosCache2a[i];
1124 glBegin(GL_LINE_STRIP);
1125 for (j = 0; j <= stacks; j++) {
1126 switch(qobj->normals) {
1128 glNormal3f(sintemp2 * sinCache3b[j],
1129 costemp2 * sinCache3b[j],
1133 glNormal3f(sintemp2 * sinCache2b[j],
1134 costemp2 * sinCache2b[j],
1142 if (qobj->textureCoords) {
1143 glTexCoord2f(1 - (float) i / slices,
1144 1 - (float) j / stacks);
1146 glVertex3f(sintemp1 * sinCache1b[j],
1147 costemp1 * sinCache1b[j], cosCache1b[j]);