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