patch to import Jon Smirl's work from Bitkeeper
[mesa.git] / src / glu / mini / quadric.c
1 /* $Id: quadric.c,v 1.2 2003/08/22 20:11:43 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.3
6 * Copyright (C) 1999-2000 Brian Paul
7 *
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.
12 *
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.
17 *
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.
21 */
22
23
24 /* TODO:
25 * texture coordinate support
26 * flip normals according to orientation
27 * there's still some inside/outside orientation bugs in possibly all
28 * but the sphere function
29 */
30
31
32 #ifdef PC_HEADER
33 #include "all.h"
34 #else
35 #include <math.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include "gluP.h"
39 #endif
40
41
42
43 #ifndef M_PI
44 # define M_PI (3.1415926)
45 #endif
46
47
48 /*
49 * Convert degrees to radians:
50 */
51 #define DEG_TO_RAD(A) ((A)*(M_PI/180.0))
52
53
54 /*
55 * Sin and Cos for degree angles:
56 */
57 #define SIND( A ) sin( (A)*(M_PI/180.0) )
58 #define COSD( A) cos( (A)*(M_PI/180.0) )
59
60
61 /*
62 * Texture coordinates if texture flag is set
63 */
64 #define TXTR_COORD(x,y) if (qobj->TextureFlag) glTexCoord2f(x,y);
65
66
67
68 struct GLUquadric
69 {
70 GLenum DrawStyle; /* GLU_FILL, LINE, SILHOUETTE, or POINT */
71 GLenum Orientation; /* GLU_INSIDE or GLU_OUTSIDE */
72 GLboolean TextureFlag; /* Generate texture coords? */
73 GLenum Normals; /* GLU_NONE, GLU_FLAT, or GLU_SMOOTH */
74 void (GLCALLBACK * ErrorFunc) (GLenum err); /* Error handler callback function */
75 };
76
77
78
79 /*
80 * Process a GLU error.
81 */
82 static void
83 quadric_error(GLUquadricObj * qobj, GLenum error, const char *msg)
84 {
85 /* Call the error call back function if any */
86 if (qobj->ErrorFunc) {
87 (*qobj->ErrorFunc) (error);
88 }
89 /* Print a message to stdout if MESA_DEBUG variable is defined */
90 if (getenv("MESA_DEBUG")) {
91 fprintf(stderr, "GLUError: %s: %s\n", (char *) gluErrorString(error),
92 msg);
93 }
94 }
95
96
97
98
99 GLUquadricObj *GLAPIENTRY
100 gluNewQuadric(void)
101 {
102 GLUquadricObj *q;
103
104 q = (GLUquadricObj *) malloc(sizeof(struct GLUquadric));
105 if (q) {
106 q->DrawStyle = GLU_FILL;
107 q->Orientation = GLU_OUTSIDE;
108 q->TextureFlag = GL_FALSE;
109 q->Normals = GLU_SMOOTH;
110 q->ErrorFunc = NULL;
111 }
112 return q;
113 }
114
115
116
117 void GLAPIENTRY
118 gluDeleteQuadric(GLUquadricObj * state)
119 {
120 if (state) {
121 free((void *) state);
122 }
123 }
124
125
126
127 /*
128 * Set the drawing style to be GLU_FILL, GLU_LINE, GLU_SILHOUETTE,
129 * or GLU_POINT.
130 */
131 void GLAPIENTRY
132 gluQuadricDrawStyle(GLUquadricObj * quadObject, GLenum drawStyle)
133 {
134 if (quadObject && (drawStyle == GLU_FILL || drawStyle == GLU_LINE
135 || drawStyle == GLU_SILHOUETTE
136 || drawStyle == GLU_POINT)) {
137 quadObject->DrawStyle = drawStyle;
138 }
139 else {
140 quadric_error(quadObject, GLU_INVALID_ENUM, "qluQuadricDrawStyle");
141 }
142 }
143
144
145
146 /*
147 * Set the orientation to GLU_INSIDE or GLU_OUTSIDE.
148 */
149 void GLAPIENTRY
150 gluQuadricOrientation(GLUquadricObj * quadObject, GLenum orientation)
151 {
152 if (quadObject
153 && (orientation == GLU_INSIDE || orientation == GLU_OUTSIDE)) {
154 quadObject->Orientation = orientation;
155 }
156 else {
157 quadric_error(quadObject, GLU_INVALID_ENUM, "qluQuadricOrientation");
158 }
159 }
160
161
162
163 /*
164 * Set the error handler callback function.
165 */
166 void GLAPIENTRY
167 gluQuadricCallback(GLUquadricObj * qobj,
168 GLenum which, void (GLCALLBACK * fn) ())
169 {
170 /*
171 * UGH, this is a mess! I thought ANSI was a standard.
172 */
173 if (qobj && which == GLU_ERROR) {
174 #ifdef __CYGWIN32__
175 qobj->ErrorFunc = (void (GLCALLBACKPCAST) (GLenum)) fn;
176 #elif defined(OPENSTEP)
177 qobj->ErrorFunc = (void (*)(GLenum)) fn;
178 #elif defined(_WIN32)
179 qobj->ErrorFunc = (void (GLCALLBACK *) (int)) fn;
180 #elif defined(__STORM__)
181 qobj->ErrorFunc = (void (GLCALLBACK *) (GLenum)) fn;
182 #elif defined(__BEOS__)
183 qobj->ErrorFunc = (void (*)(GLenum)) fn;
184 #else
185 qobj->ErrorFunc = (void (GLCALLBACK *) ()) fn;
186 #endif
187 }
188 }
189
190
191 void GLAPIENTRY
192 gluQuadricNormals(GLUquadricObj * quadObject, GLenum normals)
193 {
194 if (quadObject
195 && (normals == GLU_NONE || normals == GLU_FLAT
196 || normals == GLU_SMOOTH)) {
197 quadObject->Normals = normals;
198 }
199 }
200
201
202 void GLAPIENTRY
203 gluQuadricTexture(GLUquadricObj * quadObject, GLboolean textureCoords)
204 {
205 if (quadObject) {
206 quadObject->TextureFlag = textureCoords;
207 }
208 }
209
210
211
212
213 /*
214 * Call glNormal3f after scaling normal to unit length.
215 */
216 static void
217 normal3f(GLfloat x, GLfloat y, GLfloat z)
218 {
219 }
220
221
222
223 void GLAPIENTRY
224 gluCylinder(GLUquadricObj * qobj,
225 GLdouble baseRadius, GLdouble topRadius,
226 GLdouble height, GLint slices, GLint stacks)
227 {
228 GLdouble da, r, dr, dz;
229 GLfloat x, y, z, nz, nsign;
230 GLint i, j;
231
232 if (qobj->Orientation == GLU_INSIDE) {
233 nsign = -1.0;
234 }
235 else {
236 nsign = 1.0;
237 }
238
239 da = 2.0 * M_PI / slices;
240 dr = (topRadius - baseRadius) / stacks;
241 dz = height / stacks;
242 nz = (baseRadius - topRadius) / height; /* Z component of normal vectors */
243
244 if (qobj->DrawStyle == GLU_POINT) {
245 glBegin(GL_POINTS);
246 for (i = 0; i < slices; i++) {
247 x = cos(i * da);
248 y = sin(i * da);
249 normal3f(x * nsign, y * nsign, nz * nsign);
250
251 z = 0.0;
252 r = baseRadius;
253 for (j = 0; j <= stacks; j++) {
254 glVertex3f(x * r, y * r, z);
255 z += dz;
256 r += dr;
257 }
258 }
259 glEnd();
260 }
261 else if (qobj->DrawStyle == GLU_LINE || qobj->DrawStyle == GLU_SILHOUETTE) {
262 /* Draw rings */
263 if (qobj->DrawStyle == GLU_LINE) {
264 z = 0.0;
265 r = baseRadius;
266 for (j = 0; j <= stacks; j++) {
267 glBegin(GL_LINE_LOOP);
268 for (i = 0; i < slices; i++) {
269 x = cos(i * da);
270 y = sin(i * da);
271 normal3f(x * nsign, y * nsign, nz * nsign);
272 glVertex3f(x * r, y * r, z);
273 }
274 glEnd();
275 z += dz;
276 r += dr;
277 }
278 }
279 else {
280 /* draw one ring at each end */
281 if (baseRadius != 0.0) {
282 glBegin(GL_LINE_LOOP);
283 for (i = 0; i < slices; i++) {
284 x = cos(i * da);
285 y = sin(i * da);
286 normal3f(x * nsign, y * nsign, nz * nsign);
287 glVertex3f(x * baseRadius, y * baseRadius, 0.0);
288 }
289 glEnd();
290 glBegin(GL_LINE_LOOP);
291 for (i = 0; i < slices; i++) {
292 x = cos(i * da);
293 y = sin(i * da);
294 normal3f(x * nsign, y * nsign, nz * nsign);
295 glVertex3f(x * topRadius, y * topRadius, height);
296 }
297 glEnd();
298 }
299 }
300 /* draw length lines */
301 glBegin(GL_LINES);
302 for (i = 0; i < slices; i++) {
303 x = cos(i * da);
304 y = sin(i * da);
305 normal3f(x * nsign, y * nsign, nz * nsign);
306 glVertex3f(x * baseRadius, y * baseRadius, 0.0);
307 glVertex3f(x * topRadius, y * topRadius, height);
308 }
309 glEnd();
310 }
311 else if (qobj->DrawStyle == GLU_FILL) {
312 GLfloat ds = 1.0 / slices;
313 GLfloat dt = 1.0 / stacks;
314 GLfloat t = 0.0;
315 z = 0.0;
316 r = baseRadius;
317 for (j = 0; j < stacks; j++) {
318 GLfloat s = 0.0;
319 glBegin(GL_QUAD_STRIP);
320 for (i = 0; i <= slices; i++) {
321 GLfloat x, y;
322 if (i == slices) {
323 x = sin(0.0);
324 y = cos(0.0);
325 }
326 else {
327 x = sin(i * da);
328 y = cos(i * da);
329 }
330 if (nsign == 1.0) {
331 normal3f(x * nsign, y * nsign, nz * nsign);
332 TXTR_COORD(s, t);
333 glVertex3f(x * r, y * r, z);
334 normal3f(x * nsign, y * nsign, nz * nsign);
335 TXTR_COORD(s, t + dt);
336 glVertex3f(x * (r + dr), y * (r + dr), z + dz);
337 }
338 else {
339 normal3f(x * nsign, y * nsign, nz * nsign);
340 TXTR_COORD(s, t);
341 glVertex3f(x * r, y * r, z);
342 normal3f(x * nsign, y * nsign, nz * nsign);
343 TXTR_COORD(s, t + dt);
344 glVertex3f(x * (r + dr), y * (r + dr), z + dz);
345 }
346 s += ds;
347 } /* for slices */
348 glEnd();
349 r += dr;
350 t += dt;
351 z += dz;
352 } /* for stacks */
353 }
354 }
355
356
357
358
359
360 void GLAPIENTRY
361 gluSphere(GLUquadricObj * qobj, GLdouble radius, GLint slices, GLint stacks)
362 {
363 GLfloat rho, drho, theta, dtheta;
364 GLfloat x, y, z;
365 GLfloat s, t, ds, dt;
366 GLint i, j, imin, imax;
367 GLboolean normals;
368 GLfloat nsign;
369
370 if (qobj->Normals == GLU_NONE) {
371 normals = GL_FALSE;
372 }
373 else {
374 normals = GL_TRUE;
375 }
376 if (qobj->Orientation == GLU_INSIDE) {
377 nsign = -1.0;
378 }
379 else {
380 nsign = 1.0;
381 }
382
383 drho = M_PI / (GLfloat) stacks;
384 dtheta = 2.0 * M_PI / (GLfloat) slices;
385
386 /* texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y axis */
387 /* t goes from -1.0/+1.0 at z = -radius/+radius (linear along longitudes) */
388 /* cannot use triangle fan on texturing (s coord. at top/bottom tip varies) */
389
390 if (qobj->DrawStyle == GLU_FILL) {
391 if (!qobj->TextureFlag) {
392 /* draw +Z end as a triangle fan */
393 glBegin(GL_TRIANGLE_FAN);
394 /* glNormal3f(0.0, 0.0, 1.0); */
395 glVertex3f(0.0, 0.0, nsign * radius);
396 for (j = 0; j <= slices; j++) {
397 theta = (j == slices) ? 0.0 : j * dtheta;
398 x = -sin(theta) * sin(drho);
399 y = cos(theta) * sin(drho);
400 z = nsign * cos(drho);
401 glVertex3f(x * radius, y * radius, z * radius);
402 }
403 glEnd();
404 }
405
406 ds = 1.0 / slices;
407 dt = 1.0 / stacks;
408 t = 1.0; /* because loop now runs from 0 */
409 if (qobj->TextureFlag) {
410 imin = 0;
411 imax = stacks;
412 }
413 else {
414 imin = 1;
415 imax = stacks - 1;
416 }
417
418 /* draw intermediate stacks as quad strips */
419 for (i = imin; i < imax; i++) {
420 rho = i * drho;
421 glBegin(GL_QUAD_STRIP);
422 s = 0.0;
423 for (j = 0; j <= slices; j++) {
424 theta = (j == slices) ? 0.0 : j * dtheta;
425 x = -sin(theta) * sin(rho);
426 y = cos(theta) * sin(rho);
427 z = nsign * cos(rho);
428 TXTR_COORD(s, t);
429 glVertex3f(x * radius, y * radius, z * radius);
430 x = -sin(theta) * sin(rho + drho);
431 y = cos(theta) * sin(rho + drho);
432 z = nsign * cos(rho + drho);
433 TXTR_COORD(s, t - dt);
434 s += ds;
435 glVertex3f(x * radius, y * radius, z * radius);
436 }
437 glEnd();
438 t -= dt;
439 }
440
441 if (!qobj->TextureFlag) {
442 /* draw -Z end as a triangle fan */
443 glBegin(GL_TRIANGLE_FAN);
444 glVertex3f(0.0, 0.0, -radius * nsign);
445 rho = M_PI - drho;
446 s = 1.0;
447 t = dt;
448 for (j = slices; j >= 0; j--) {
449 theta = (j == slices) ? 0.0 : j * dtheta;
450 x = -sin(theta) * sin(rho);
451 y = cos(theta) * sin(rho);
452 z = nsign * cos(rho);
453 s -= ds;
454 glVertex3f(x * radius, y * radius, z * radius);
455 }
456 glEnd();
457 }
458 }
459 else if (qobj->DrawStyle == GLU_LINE || qobj->DrawStyle == GLU_SILHOUETTE) {
460 /* draw stack lines */
461 for (i = 1; i < stacks; i++) { /* stack line at i==stacks-1 was missing here */
462 rho = i * drho;
463 glBegin(GL_LINE_LOOP);
464 for (j = 0; j < slices; j++) {
465 theta = j * dtheta;
466 x = cos(theta) * sin(rho);
467 y = sin(theta) * sin(rho);
468 z = cos(rho);
469 glVertex3f(x * radius, y * radius, z * radius);
470 }
471 glEnd();
472 }
473 /* draw slice lines */
474 for (j = 0; j < slices; j++) {
475 theta = j * dtheta;
476 glBegin(GL_LINE_STRIP);
477 for (i = 0; i <= stacks; i++) {
478 rho = i * drho;
479 x = cos(theta) * sin(rho);
480 y = sin(theta) * sin(rho);
481 z = cos(rho);
482 glVertex3f(x * radius, y * radius, z * radius);
483 }
484 glEnd();
485 }
486 }
487 else if (qobj->DrawStyle == GLU_POINT) {
488 /* top and bottom-most points */
489 glBegin(GL_POINTS);
490 glVertex3f(0.0, 0.0, radius);
491 glVertex3f(0.0, 0.0, -radius);
492
493 /* loop over stacks */
494 for (i = 1; i < stacks - 1; i++) {
495 rho = i * drho;
496 for (j = 0; j < slices; j++) {
497 theta = j * dtheta;
498 x = cos(theta) * sin(rho);
499 y = sin(theta) * sin(rho);
500 z = cos(rho);
501 glVertex3f(x * radius, y * radius, z * radius);
502 }
503 }
504 glEnd();
505 }
506
507 }
508
509
510
511 void GLAPIENTRY
512 gluDisk(GLUquadricObj * qobj,
513 GLdouble innerRadius, GLdouble outerRadius, GLint slices, GLint loops)
514 {
515 GLfloat da, dr;
516 #if 0
517 GLdouble a, da;
518 GLfloat r, dr;
519 GLfloat x, y;
520 GLfloat r1, r2, dtc;
521 GLint s, l;
522 #endif
523
524
525 da = 2.0 * M_PI / slices;
526 dr = (outerRadius - innerRadius) / (GLfloat) loops;
527
528 switch (qobj->DrawStyle) {
529 case GLU_FILL:
530 {
531 /* texture of a gluDisk is a cut out of the texture unit square
532 * x, y in [-outerRadius, +outerRadius]; s, t in [0, 1]
533 * (linear mapping)
534 */
535 GLfloat dtc = 2.0f * outerRadius;
536 GLfloat sa, ca;
537 GLfloat r1 = innerRadius;
538 GLint l;
539 for (l = 0; l < loops; l++) {
540 GLfloat r2 = r1 + dr;
541 if (qobj->Orientation == GLU_OUTSIDE) {
542 GLint s;
543 glBegin(GL_QUAD_STRIP);
544 for (s = 0; s <= slices; s++) {
545 GLfloat a;
546 if (s == slices)
547 a = 0.0;
548 else
549 a = s * da;
550 sa = sin(a);
551 ca = cos(a);
552 TXTR_COORD(0.5 + sa * r2 / dtc, 0.5 + ca * r2 / dtc);
553 glVertex2f(r2 * sa, r2 * ca);
554 TXTR_COORD(0.5 + sa * r1 / dtc, 0.5 + ca * r1 / dtc);
555 glVertex2f(r1 * sa, r1 * ca);
556 }
557 glEnd();
558 }
559 else {
560 GLint s;
561 glBegin(GL_QUAD_STRIP);
562 for (s = slices; s >= 0; s--) {
563 GLfloat a;
564 if (s == slices)
565 a = 0.0;
566 else
567 a = s * da;
568 sa = sin(a);
569 ca = cos(a);
570 TXTR_COORD(0.5 - sa * r2 / dtc, 0.5 + ca * r2 / dtc);
571 glVertex2f(r2 * sa, r2 * ca);
572 TXTR_COORD(0.5 - sa * r1 / dtc, 0.5 + ca * r1 / dtc);
573 glVertex2f(r1 * sa, r1 * ca);
574 }
575 glEnd();
576 }
577 r1 = r2;
578 }
579 break;
580 }
581 case GLU_LINE:
582 {
583 GLint l, s;
584 /* draw loops */
585 for (l = 0; l <= loops; l++) {
586 GLfloat r = innerRadius + l * dr;
587 glBegin(GL_LINE_LOOP);
588 for (s = 0; s < slices; s++) {
589 GLfloat a = s * da;
590 glVertex2f(r * sin(a), r * cos(a));
591 }
592 glEnd();
593 }
594 /* draw spokes */
595 for (s = 0; s < slices; s++) {
596 GLfloat a = s * da;
597 GLfloat x = sin(a);
598 GLfloat y = cos(a);
599 glBegin(GL_LINE_STRIP);
600 for (l = 0; l <= loops; l++) {
601 GLfloat r = innerRadius + l * dr;
602 glVertex2f(r * x, r * y);
603 }
604 glEnd();
605 }
606 break;
607 }
608 case GLU_POINT:
609 {
610 GLint s;
611 glBegin(GL_POINTS);
612 for (s = 0; s < slices; s++) {
613 GLfloat a = s * da;
614 GLfloat x = sin(a);
615 GLfloat y = cos(a);
616 GLint l;
617 for (l = 0; l <= loops; l++) {
618 GLfloat r = innerRadius * l * dr;
619 glVertex2f(r * x, r * y);
620 }
621 }
622 glEnd();
623 break;
624 }
625 case GLU_SILHOUETTE:
626 {
627 if (innerRadius != 0.0) {
628 GLfloat a;
629 glBegin(GL_LINE_LOOP);
630 for (a = 0.0; a < 2.0 * M_PI; a += da) {
631 GLfloat x = innerRadius * sin(a);
632 GLfloat y = innerRadius * cos(a);
633 glVertex2f(x, y);
634 }
635 glEnd();
636 }
637 {
638 GLfloat a;
639 glBegin(GL_LINE_LOOP);
640 for (a = 0; a < 2.0 * M_PI; a += da) {
641 GLfloat x = outerRadius * sin(a);
642 GLfloat y = outerRadius * cos(a);
643 glVertex2f(x, y);
644 }
645 glEnd();
646 }
647 break;
648 }
649 default:
650 abort();
651 }
652 }
653
654
655
656 void GLAPIENTRY
657 gluPartialDisk(GLUquadricObj * qobj, GLdouble innerRadius,
658 GLdouble outerRadius, GLint slices, GLint loops,
659 GLdouble startAngle, GLdouble sweepAngle)
660 {
661 if (qobj->DrawStyle == GLU_POINT) {
662 GLint loop, slice;
663 GLdouble radius, delta_radius;
664 GLdouble angle, delta_angle;
665 delta_radius = (outerRadius - innerRadius) / (loops - 1);
666 delta_angle = DEG_TO_RAD((sweepAngle) / (slices - 1));
667 glBegin(GL_POINTS);
668 radius = innerRadius;
669 for (loop = 0; loop < loops; loop++) {
670 angle = DEG_TO_RAD(startAngle);
671 for (slice = 0; slice < slices; slice++) {
672 glVertex2f(radius * sin(angle), radius * cos(angle));
673 angle += delta_angle;
674 }
675 radius += delta_radius;
676 }
677 glEnd();
678 }
679 else if (qobj->DrawStyle == GLU_LINE) {
680 GLint loop, slice;
681 GLdouble radius, delta_radius;
682 GLdouble angle, delta_angle;
683 delta_radius = (outerRadius - innerRadius) / loops;
684 delta_angle = DEG_TO_RAD(sweepAngle / slices);
685 /* draw rings */
686 radius = innerRadius;
687 for (loop = 0; loop < loops; loop++) {
688 angle = DEG_TO_RAD(startAngle);
689 glBegin(GL_LINE_STRIP);
690 for (slice = 0; slice <= slices; slice++) {
691 glVertex2f(radius * sin(angle), radius * cos(angle));
692 angle += delta_angle;
693 }
694 glEnd();
695 radius += delta_radius;
696 }
697 /* draw spokes */
698 angle = DEG_TO_RAD(startAngle);
699 for (slice = 0; slice <= slices; slice++) {
700 radius = innerRadius;
701 glBegin(GL_LINE_STRIP);
702 for (loop = 0; loop < loops; loop++) {
703 glVertex2f(radius * sin(angle), radius * cos(angle));
704 radius += delta_radius;
705 }
706 glEnd();
707 angle += delta_angle;
708 }
709 }
710 else if (qobj->DrawStyle == GLU_SILHOUETTE) {
711 GLint slice;
712 GLdouble angle, delta_angle;
713 delta_angle = DEG_TO_RAD(sweepAngle / slices);
714 /* draw outer ring */
715 glBegin(GL_LINE_STRIP);
716 angle = DEG_TO_RAD(startAngle);
717 for (slice = 0; slice <= slices; slice++) {
718 glVertex2f(outerRadius * sin(angle), outerRadius * cos(angle));
719 angle += delta_angle;
720 }
721 glEnd();
722 /* draw inner ring */
723 if (innerRadius > 0.0) {
724 glBegin(GL_LINE_STRIP);
725 angle = DEG_TO_RAD(startAngle);
726 for (slice = 0; slice < slices; slice++) {
727 glVertex2f(innerRadius * sin(angle), innerRadius * cos(angle));
728 angle += delta_angle;
729 }
730 glEnd();
731 }
732 /* draw spokes */
733 if (sweepAngle < 360.0) {
734 GLdouble stopAngle = startAngle + sweepAngle;
735 glBegin(GL_LINES);
736 glVertex2f(innerRadius * SIND(startAngle),
737 innerRadius * COSD(startAngle));
738 glVertex2f(outerRadius * SIND(startAngle),
739 outerRadius * COSD(startAngle));
740 glVertex2f(innerRadius * SIND(stopAngle),
741 innerRadius * COSD(stopAngle));
742 glVertex2f(outerRadius * SIND(stopAngle),
743 outerRadius * COSD(stopAngle));
744 glEnd();
745 }
746 }
747 else if (qobj->DrawStyle == GLU_FILL) {
748 GLint loop, slice;
749 GLdouble radius, delta_radius;
750 GLdouble angle, delta_angle;
751 delta_radius = (outerRadius - innerRadius) / loops;
752 delta_angle = DEG_TO_RAD(sweepAngle / slices);
753 radius = innerRadius;
754 for (loop = 0; loop < loops; loop++) {
755 glBegin(GL_QUAD_STRIP);
756 angle = DEG_TO_RAD(startAngle);
757 for (slice = 0; slice <= slices; slice++) {
758 if (qobj->Orientation == GLU_OUTSIDE) {
759 glVertex2f((radius + delta_radius) * sin(angle),
760 (radius + delta_radius) * cos(angle));
761 glVertex2f(radius * sin(angle), radius * cos(angle));
762 }
763 else {
764 glVertex2f(radius * sin(angle), radius * cos(angle));
765 glVertex2f((radius + delta_radius) * sin(angle),
766 (radius + delta_radius) * cos(angle));
767 }
768 angle += delta_angle;
769 }
770 glEnd();
771 radius += delta_radius;
772 }
773 }
774 }