1 /* $Id: quadric.c,v 1.1 1999/08/19 00:55:42 jtg Exp $ */
4 * Mesa 3-D graphics library
6 * Copyright (C) 1995-1999 Brian Paul
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the Free
20 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 * Revision 1.1 1999/08/19 00:55:42 jtg
29 * Revision 1.19 1999/02/27 13:55:31 brianp
30 * fixed BeOS-related GLU typedef problems
32 * Revision 1.18 1999/01/03 03:23:15 brianp
33 * now using GLAPIENTRY and GLCALLBACK keywords (Ted Jump)
35 * Revision 1.17 1999/01/03 03:19:15 brianp
36 * rewrote some of gluCylinder
38 * Revision 1.16 1998/06/01 01:08:36 brianp
39 * small update for Next/OpenStep from Alexander Mai
41 * Revision 1.15 1998/03/15 18:28:54 brianp
42 * reimplemented gluDisk() point and line mode
44 * Revision 1.14 1998/03/15 18:14:17 brianp
45 * fixed a compiler cast warning
47 * Revision 1.13 1998/02/07 14:28:34 brianp
48 * another change to gluQuadricCallback(), this time for StormC compiler
50 * Revision 1.12 1998/02/05 00:43:19 brianp
51 * Yes, still another change to gluQuadricCallback()!
53 * Revision 1.11 1998/02/04 00:27:43 brianp
54 * yet another change to gluQuadricCallback()!
56 * Revision 1.10 1998/02/04 00:23:23 brianp
57 * fixed CALLBACK problem in gluQuadricCallback() (Stephane Rehel)
59 * Revision 1.9 1998/02/04 00:20:09 brianp
60 * added missing (int) in ErrorFunc cast
62 * Revision 1.8 1998/01/16 03:37:51 brianp
63 * fixed another assignment warning in gluQuadricCallback()
65 * Revision 1.7 1998/01/16 03:35:26 brianp
66 * fixed Windows compilation warnings (Theodore Jump)
68 * Revision 1.6 1997/10/29 02:02:20 brianp
69 * various MS Windows compiler changes (David Bucciarelli, v20 3dfx driver)
71 * Revision 1.5 1997/09/17 01:51:48 brianp
72 * changed glu*Callback() functions to match prototype in glu.h
74 * Revision 1.4 1997/07/24 01:28:44 brianp
75 * changed precompiled header symbol from PCH to PC_HEADER
77 * Revision 1.3 1997/05/28 02:29:38 brianp
78 * added support for precompiled headers (PCH), inserted APIENTRY keyword
80 * Revision 1.2 1997/03/12 02:15:38 brianp
81 * fixed problem in gluPartialDisk() reported by Kenneth H. Carpenter
83 * Revision 1.1 1996/09/27 01:19:39 brianp
90 * texture coordinate support
91 * flip normals according to orientation
92 * there's still some inside/outside orientation bugs in possibly all
93 * but the sphere function
109 # define M_PI (3.1415926)
114 * Convert degrees to radians:
116 #define DEG_TO_RAD(A) ((A)*(M_PI/180.0))
120 * Sin and Cos for degree angles:
122 #define SIND( A ) sin( (A)*(M_PI/180.0) )
123 #define COSD( A) cos( (A)*(M_PI/180.0) )
127 * Texture coordinates if texture flag is set
129 #define TXTR_COORD(x,y) if (qobj->TextureFlag) glTexCoord2f(x,y);
134 GLenum DrawStyle
; /* GLU_FILL, LINE, SILHOUETTE, or POINT */
135 GLenum Orientation
; /* GLU_INSIDE or GLU_OUTSIDE */
136 GLboolean TextureFlag
; /* Generate texture coords? */
137 GLenum Normals
; /* GLU_NONE, GLU_FLAT, or GLU_SMOOTH */
138 void (GLCALLBACK
*ErrorFunc
)(GLenum err
); /* Error handler callback function */
144 * Process a GLU error.
146 static void quadric_error( GLUquadricObj
*qobj
, GLenum error
, const char *msg
)
148 /* Call the error call back function if any */
149 if (qobj
->ErrorFunc
) {
150 (*qobj
->ErrorFunc
)( error
);
152 /* Print a message to stdout if MESA_DEBUG variable is defined */
153 if (getenv("MESA_DEBUG")) {
154 fprintf(stderr
,"GLUError: %s: %s\n", (char*) gluErrorString(error
), msg
);
161 GLUquadricObj
* GLAPIENTRY
gluNewQuadric( void )
165 q
= (GLUquadricObj
*) malloc( sizeof(struct GLUquadric
) );
167 q
->DrawStyle
= GLU_FILL
;
168 q
->Orientation
= GLU_OUTSIDE
;
169 q
->TextureFlag
= GL_FALSE
;
170 q
->Normals
= GLU_SMOOTH
;
178 void GLAPIENTRY
gluDeleteQuadric( GLUquadricObj
*state
)
181 free( (void *) state
);
188 * Set the drawing style to be GLU_FILL, GLU_LINE, GLU_SILHOUETTE,
191 void GLAPIENTRY
gluQuadricDrawStyle( GLUquadricObj
*quadObject
, GLenum drawStyle
)
193 if (quadObject
&& (drawStyle
==GLU_FILL
|| drawStyle
==GLU_LINE
194 || drawStyle
==GLU_SILHOUETTE
|| drawStyle
==GLU_POINT
)) {
195 quadObject
->DrawStyle
= drawStyle
;
198 quadric_error( quadObject
, GLU_INVALID_ENUM
, "qluQuadricDrawStyle" );
205 * Set the orientation to GLU_INSIDE or GLU_OUTSIDE.
207 void GLAPIENTRY
gluQuadricOrientation( GLUquadricObj
*quadObject
,
210 if (quadObject
&& (orientation
==GLU_INSIDE
|| orientation
==GLU_OUTSIDE
)) {
211 quadObject
->Orientation
= orientation
;
214 quadric_error( quadObject
, GLU_INVALID_ENUM
, "qluQuadricOrientation" );
221 * Set the error handler callback function.
223 void GLAPIENTRY
gluQuadricCallback( GLUquadricObj
*qobj
,
224 GLenum which
, void (GLCALLBACK
*fn
)() )
227 * UGH, this is a mess! I thought ANSI was a standard.
229 if (qobj
&& which
==GLU_ERROR
) {
231 qobj
->ErrorFunc
= (void(*)(int))fn
;
232 #elif defined(OPENSTEP)
233 qobj
->ErrorFunc
= (void(*)(GLenum
))fn
;
234 #elif defined(_WIN32)
235 qobj
->ErrorFunc
= (void(GLCALLBACK
*)(int))fn
;
236 #elif defined(__STORM__)
237 qobj
->ErrorFunc
= (void(GLCALLBACK
*)(GLenum
))fn
;
238 #elif defined(__BEOS__)
239 qobj
->ErrorFunc
= (void(*)(GLenum
))fn
;
241 qobj
->ErrorFunc
= (void(GLCALLBACK
*)())fn
;
247 void GLAPIENTRY
gluQuadricNormals( GLUquadricObj
*quadObject
, GLenum normals
)
250 && (normals
==GLU_NONE
|| normals
==GLU_FLAT
|| normals
==GLU_SMOOTH
)) {
251 quadObject
->Normals
= normals
;
256 void GLAPIENTRY
gluQuadricTexture( GLUquadricObj
*quadObject
,
257 GLboolean textureCoords
)
260 quadObject
->TextureFlag
= textureCoords
;
268 * Call glNormal3f after scaling normal to unit length.
270 static void normal3f( GLfloat x
, GLfloat y
, GLfloat z
)
274 mag
= sqrt( x
*x
+ y
*y
+ z
*z
);
280 glNormal3f( x
, y
, z
);
285 void GLAPIENTRY
gluCylinder( GLUquadricObj
*qobj
,
286 GLdouble baseRadius
, GLdouble topRadius
,
287 GLdouble height
, GLint slices
, GLint stacks
)
289 GLdouble da
, r
, dr
, dz
;
290 GLfloat x
, y
, z
, nz
, nsign
;
293 if (qobj
->Orientation
==GLU_INSIDE
) {
300 da
= 2.0*M_PI
/ slices
;
301 dr
= (topRadius
-baseRadius
) / stacks
;
302 dz
= height
/ stacks
;
303 nz
= (baseRadius
-topRadius
) / height
; /* Z component of normal vectors */
305 if (qobj
->DrawStyle
==GLU_POINT
) {
306 glBegin( GL_POINTS
);
307 for (i
=0;i
<slices
;i
++) {
310 normal3f( x
*nsign
, y
*nsign
, nz
*nsign
);
314 for (j
=0;j
<=stacks
;j
++) {
315 glVertex3f( x
*r
, y
*r
, z
);
322 else if (qobj
->DrawStyle
==GLU_LINE
|| qobj
->DrawStyle
==GLU_SILHOUETTE
) {
324 if (qobj
->DrawStyle
==GLU_LINE
) {
327 for (j
=0;j
<=stacks
;j
++) {
328 glBegin( GL_LINE_LOOP
);
329 for (i
=0;i
<slices
;i
++) {
332 normal3f( x
*nsign
, y
*nsign
, nz
*nsign
);
333 glVertex3f( x
*r
, y
*r
, z
);
341 /* draw one ring at each end */
342 if (baseRadius
!=0.0) {
343 glBegin( GL_LINE_LOOP
);
344 for (i
=0;i
<slices
;i
++) {
347 normal3f( x
*nsign
, y
*nsign
, nz
*nsign
);
348 glVertex3f( x
*baseRadius
, y
*baseRadius
, 0.0 );
351 glBegin( GL_LINE_LOOP
);
352 for (i
=0;i
<slices
;i
++) {
355 normal3f( x
*nsign
, y
*nsign
, nz
*nsign
);
356 glVertex3f( x
*topRadius
, y
*topRadius
, height
);
361 /* draw length lines */
363 for (i
=0;i
<slices
;i
++) {
366 normal3f( x
*nsign
, y
*nsign
, nz
*nsign
);
367 glVertex3f( x
*baseRadius
, y
*baseRadius
, 0.0 );
368 glVertex3f( x
*topRadius
, y
*topRadius
, height
);
372 else if (qobj
->DrawStyle
==GLU_FILL
) {
373 GLfloat ds
= 1.0 / slices
;
374 GLfloat dt
= 1.0 / stacks
;
378 for (j
=0;j
<stacks
;j
++) {
380 glBegin( GL_QUAD_STRIP
);
381 for (i
=0;i
<=slices
;i
++) {
392 normal3f( x
*nsign
, y
*nsign
, nz
*nsign
);
394 glVertex3f( x
* r
, y
* r
, z
);
395 normal3f( x
*nsign
, y
*nsign
, nz
*nsign
);
396 TXTR_COORD(s
, t
+ dt
);
397 glVertex3f( x
* (r
+ dr
), y
* (r
+ dr
), z
+ dz
);
400 normal3f( x
*nsign
, y
*nsign
, nz
*nsign
);
402 glVertex3f( x
* r
, y
* r
, z
);
403 normal3f( x
*nsign
, y
*nsign
, nz
*nsign
);
404 TXTR_COORD(s
, t
+ dt
);
405 glVertex3f( x
* (r
+ dr
), y
* (r
+ dr
), z
+ dz
);
421 void GLAPIENTRY
gluSphere( GLUquadricObj
*qobj
,
422 GLdouble radius
, GLint slices
, GLint stacks
)
424 GLfloat rho
, drho
, theta
, dtheta
;
426 GLfloat s
, t
, ds
, dt
;
427 GLint i
, j
, imin
, imax
;
431 if (qobj
->Normals
==GLU_NONE
) {
437 if (qobj
->Orientation
==GLU_INSIDE
) {
444 drho
= M_PI
/ (GLfloat
) stacks
;
445 dtheta
= 2.0 * M_PI
/ (GLfloat
) slices
;
447 /* texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y axis */
448 /* t goes from -1.0/+1.0 at z = -radius/+radius (linear along longitudes) */
449 /* cannot use triangle fan on texturing (s coord. at top/bottom tip varies) */
451 if (qobj
->DrawStyle
==GLU_FILL
) {
452 if (!qobj
->TextureFlag
) {
453 /* draw +Z end as a triangle fan */
454 glBegin( GL_TRIANGLE_FAN
);
455 glNormal3f( 0.0, 0.0, 1.0 );
457 glVertex3f( 0.0, 0.0, nsign
* radius
);
458 for (j
=0;j
<=slices
;j
++) {
459 theta
= (j
==slices
) ? 0.0 : j
* dtheta
;
460 x
= -sin(theta
) * sin(drho
);
461 y
= cos(theta
) * sin(drho
);
462 z
= nsign
* cos(drho
);
463 if (normals
) glNormal3f( x
*nsign
, y
*nsign
, z
*nsign
);
464 glVertex3f( x
*radius
, y
*radius
, z
*radius
);
471 t
= 1.0; /* because loop now runs from 0 */
472 if (qobj
->TextureFlag
) {
481 /* draw intermediate stacks as quad strips */
482 for (i
=imin
;i
<imax
;i
++) {
484 glBegin( GL_QUAD_STRIP
);
486 for (j
=0;j
<=slices
;j
++) {
487 theta
= (j
==slices
) ? 0.0 : j
* dtheta
;
488 x
= -sin(theta
) * sin(rho
);
489 y
= cos(theta
) * sin(rho
);
490 z
= nsign
* cos(rho
);
491 if (normals
) glNormal3f( x
*nsign
, y
*nsign
, z
*nsign
);
493 glVertex3f( x
*radius
, y
*radius
, z
*radius
);
494 x
= -sin(theta
) * sin(rho
+drho
);
495 y
= cos(theta
) * sin(rho
+drho
);
496 z
= nsign
* cos(rho
+drho
);
497 if (normals
) glNormal3f( x
*nsign
, y
*nsign
, z
*nsign
);
500 glVertex3f( x
*radius
, y
*radius
, z
*radius
);
506 if (!qobj
->TextureFlag
) {
507 /* draw -Z end as a triangle fan */
508 glBegin( GL_TRIANGLE_FAN
);
509 glNormal3f( 0.0, 0.0, -1.0 );
511 glVertex3f( 0.0, 0.0, -radius
*nsign
);
515 for (j
=slices
;j
>=0;j
--) {
516 theta
= (j
==slices
) ? 0.0 : j
* dtheta
;
517 x
= -sin(theta
) * sin(rho
);
518 y
= cos(theta
) * sin(rho
);
519 z
= nsign
* cos(rho
);
520 if (normals
) glNormal3f( x
*nsign
, y
*nsign
, z
*nsign
);
523 glVertex3f( x
*radius
, y
*radius
, z
*radius
);
528 else if (qobj
->DrawStyle
==GLU_LINE
|| qobj
->DrawStyle
==GLU_SILHOUETTE
) {
529 /* draw stack lines */
530 for (i
=1;i
<stacks
;i
++) { /* stack line at i==stacks-1 was missing here */
532 glBegin( GL_LINE_LOOP
);
533 for (j
=0;j
<slices
;j
++) {
535 x
= cos(theta
) * sin(rho
);
536 y
= sin(theta
) * sin(rho
);
538 if (normals
) glNormal3f( x
*nsign
, y
*nsign
, z
*nsign
);
539 glVertex3f( x
*radius
, y
*radius
, z
*radius
);
543 /* draw slice lines */
544 for (j
=0;j
<slices
;j
++) {
546 glBegin( GL_LINE_STRIP
);
547 for (i
=0;i
<=stacks
;i
++) {
549 x
= cos(theta
) * sin(rho
);
550 y
= sin(theta
) * sin(rho
);
552 if (normals
) glNormal3f( x
*nsign
, y
*nsign
, z
*nsign
);
553 glVertex3f( x
*radius
, y
*radius
, z
*radius
);
558 else if (qobj
->DrawStyle
==GLU_POINT
) {
559 /* top and bottom-most points */
560 glBegin( GL_POINTS
);
561 if (normals
) glNormal3f( 0.0, 0.0, nsign
);
562 glVertex3d( 0.0, 0.0, radius
);
563 if (normals
) glNormal3f( 0.0, 0.0, -nsign
);
564 glVertex3d( 0.0, 0.0, -radius
);
566 /* loop over stacks */
567 for (i
=1;i
<stacks
-1;i
++) {
569 for (j
=0;j
<slices
;j
++) {
571 x
= cos(theta
) * sin(rho
);
572 y
= sin(theta
) * sin(rho
);
574 if (normals
) glNormal3f( x
*nsign
, y
*nsign
, z
*nsign
);
575 glVertex3f( x
*radius
, y
*radius
, z
*radius
);
585 void GLAPIENTRY
gluDisk( GLUquadricObj
*qobj
,
586 GLdouble innerRadius
, GLdouble outerRadius
,
587 GLint slices
, GLint loops
)
599 if (qobj
->Normals
!=GLU_NONE
) {
600 if (qobj
->Orientation
==GLU_OUTSIDE
) {
601 glNormal3f( 0.0, 0.0, +1.0 );
604 glNormal3f( 0.0, 0.0, -1.0 );
608 da
= 2.0*M_PI
/ slices
;
609 dr
= (outerRadius
-innerRadius
) / (GLfloat
) loops
;
611 switch (qobj
->DrawStyle
) {
614 /* texture of a gluDisk is a cut out of the texture unit square
615 * x, y in [-outerRadius, +outerRadius]; s, t in [0, 1]
618 GLfloat dtc
= 2.0f
* outerRadius
;
620 GLfloat r1
= innerRadius
;
622 for (l
=0; l
<loops
; l
++) {
623 GLfloat r2
= r1
+ dr
;
624 if (qobj
->Orientation
==GLU_OUTSIDE
) {
626 glBegin( GL_QUAD_STRIP
);
627 for (s
=0;s
<=slices
;s
++) {
629 if (s
==slices
) a
= 0.0;
631 sa
= sin(a
); ca
= cos(a
);
632 TXTR_COORD(0.5+sa
*r2
/dtc
,0.5+ca
*r2
/dtc
);
633 glVertex2f( r2
*sa
, r2
*ca
);
634 TXTR_COORD(0.5+sa
*r1
/dtc
,0.5+ca
*r1
/dtc
);
635 glVertex2f( r1
*sa
, r1
*ca
);
641 glBegin( GL_QUAD_STRIP
);
642 for (s
=slices
;s
>=0;s
--) {
644 if (s
==slices
) a
= 0.0;
646 sa
= sin(a
); ca
= cos(a
);
647 TXTR_COORD(0.5-sa
*r2
/dtc
,0.5+ca
*r2
/dtc
);
648 glVertex2f( r2
*sa
, r2
*ca
);
649 TXTR_COORD(0.5-sa
*r1
/dtc
,0.5+ca
*r1
/dtc
);
650 glVertex2f( r1
*sa
, r1
*ca
);
662 for (l
=0; l
<=loops
; l
++) {
663 GLfloat r
= innerRadius
+ l
* dr
;
664 glBegin( GL_LINE_LOOP
);
665 for (s
=0; s
<slices
; s
++) {
667 glVertex2f( r
*sin(a
), r
*cos(a
) );
672 for (s
=0; s
<slices
; s
++) {
676 glBegin( GL_LINE_STRIP
);
677 for (l
=0; l
<=loops
; l
++) {
678 GLfloat r
= innerRadius
+ l
* dr
;
679 glVertex2f( r
*x
, r
*y
);
688 glBegin( GL_POINTS
);
689 for (s
=0; s
<slices
; s
++) {
694 for (l
=0; l
<=loops
; l
++) {
695 GLfloat r
= innerRadius
* l
* dr
;
696 glVertex2f( r
*x
, r
*y
);
704 if (innerRadius
!=0.0) {
706 glBegin( GL_LINE_LOOP
);
707 for (a
=0.0; a
<2.0*M_PI
; a
+=da
) {
708 GLfloat x
= innerRadius
* sin(a
);
709 GLfloat y
= innerRadius
* cos(a
);
716 glBegin( GL_LINE_LOOP
);
717 for (a
=0; a
<2.0*M_PI
; a
+=da
) {
718 GLfloat x
= outerRadius
* sin(a
);
719 GLfloat y
= outerRadius
* cos(a
);
733 void GLAPIENTRY
gluPartialDisk( GLUquadricObj
*qobj
, GLdouble innerRadius
,
734 GLdouble outerRadius
, GLint slices
, GLint loops
,
735 GLdouble startAngle
, GLdouble sweepAngle
)
737 if (qobj
->Normals
!=GLU_NONE
) {
738 if (qobj
->Orientation
==GLU_OUTSIDE
) {
739 glNormal3f( 0.0, 0.0, +1.0 );
742 glNormal3f( 0.0, 0.0, -1.0 );
746 if (qobj
->DrawStyle
==GLU_POINT
) {
748 GLdouble radius
, delta_radius
;
749 GLdouble angle
, delta_angle
;
750 delta_radius
= (outerRadius
- innerRadius
) / (loops
-1);
751 delta_angle
= DEG_TO_RAD((sweepAngle
) / (slices
-1));
752 glBegin( GL_POINTS
);
753 radius
= innerRadius
;
754 for (loop
=0; loop
<loops
; loop
++) {
755 angle
= DEG_TO_RAD(startAngle
);
756 for (slice
=0; slice
<slices
; slice
++) {
757 glVertex2d( radius
* sin(angle
), radius
* cos(angle
) );
758 angle
+= delta_angle
;
760 radius
+= delta_radius
;
764 else if (qobj
->DrawStyle
==GLU_LINE
) {
766 GLdouble radius
, delta_radius
;
767 GLdouble angle
, delta_angle
;
768 delta_radius
= (outerRadius
- innerRadius
) / loops
;
769 delta_angle
= DEG_TO_RAD(sweepAngle
/ slices
);
771 radius
= innerRadius
;
772 for (loop
=0; loop
<loops
; loop
++) {
773 angle
= DEG_TO_RAD(startAngle
);
774 glBegin( GL_LINE_STRIP
);
775 for (slice
=0; slice
<slices
; slice
++) {
776 glVertex2d( radius
* sin(angle
), radius
* cos(angle
) );
777 angle
+= delta_angle
;
780 radius
+= delta_radius
;
783 angle
= DEG_TO_RAD(startAngle
);
784 for (slice
=0; slice
<slices
; slice
++) {
785 radius
= innerRadius
;
786 glBegin( GL_LINE_STRIP
);
787 for (loop
=0; loop
<loops
; loop
++) {
788 glVertex2d( radius
* sin(angle
), radius
* cos(angle
) );
789 radius
+= delta_radius
;
792 angle
+= delta_angle
;
795 else if (qobj
->DrawStyle
==GLU_SILHOUETTE
) {
797 GLdouble angle
, delta_angle
;
798 delta_angle
= DEG_TO_RAD(sweepAngle
/ slices
);
799 /* draw outer ring */
800 glBegin( GL_LINE_STRIP
);
801 angle
= DEG_TO_RAD(startAngle
);
802 for (slice
=0; slice
<=slices
; slice
++) {
803 glVertex2d( outerRadius
* sin(angle
), outerRadius
* cos(angle
) );
804 angle
+= delta_angle
;
807 /* draw inner ring */
808 if (innerRadius
>0.0) {
809 glBegin( GL_LINE_STRIP
);
810 angle
= DEG_TO_RAD(startAngle
);
811 for (slice
=0; slice
<slices
; slice
++) {
812 glVertex2d( innerRadius
* sin(angle
), innerRadius
* cos(angle
) );
813 angle
+= delta_angle
;
818 if (sweepAngle
<360.0) {
819 GLdouble stopAngle
= startAngle
+ sweepAngle
;
821 glVertex2d( innerRadius
*SIND(startAngle
), innerRadius
*COSD(startAngle
) );
822 glVertex2d( outerRadius
*SIND(startAngle
), outerRadius
*COSD(startAngle
) );
823 glVertex2d( innerRadius
*SIND(stopAngle
), innerRadius
*COSD(stopAngle
) );
824 glVertex2d( outerRadius
*SIND(stopAngle
), outerRadius
*COSD(stopAngle
) );
828 else if (qobj
->DrawStyle
==GLU_FILL
) {
830 GLdouble radius
, delta_radius
;
831 GLdouble angle
, delta_angle
;
832 delta_radius
= (outerRadius
- innerRadius
) / loops
;
833 delta_angle
= DEG_TO_RAD(sweepAngle
/ slices
);
834 radius
= innerRadius
;
835 for (loop
=0; loop
<loops
; loop
++) {
836 glBegin( GL_QUAD_STRIP
);
837 angle
= DEG_TO_RAD(startAngle
);
838 for (slice
=0; slice
<slices
; slice
++) {
839 if (qobj
->Orientation
==GLU_OUTSIDE
) {
840 glVertex2d( (radius
+delta_radius
)*sin(angle
),
841 (radius
+delta_radius
)*cos(angle
) );
842 glVertex2d( radius
* sin(angle
), radius
* cos(angle
) );
845 glVertex2d( radius
* sin(angle
), radius
* cos(angle
) );
846 glVertex2d( (radius
+delta_radius
)*sin(angle
),
847 (radius
+delta_radius
)*cos(angle
) );
849 angle
+= delta_angle
;
852 radius
+= delta_radius
;