summaryrefslogtreecommitdiffstats
path: root/src/glu/mesa/quadric.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/glu/mesa/quadric.c')
-rw-r--r--src/glu/mesa/quadric.c819
1 files changed, 819 insertions, 0 deletions
diff --git a/src/glu/mesa/quadric.c b/src/glu/mesa/quadric.c
new file mode 100644
index 00000000000..0f6889b284f
--- /dev/null
+++ b/src/glu/mesa/quadric.c
@@ -0,0 +1,819 @@
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 3.3
+ * Copyright (C) 1999-2000 Brian Paul
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/* TODO:
+ * texture coordinate support
+ * flip normals according to orientation
+ * there's still some inside/outside orientation bugs in possibly all
+ * but the sphere function
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "gluP.h"
+#endif
+
+
+
+#ifndef M_PI
+# define M_PI (3.1415926)
+#endif
+
+
+/*
+ * Convert degrees to radians:
+ */
+#define DEG_TO_RAD(A) ((A)*(M_PI/180.0))
+
+
+/*
+ * Sin and Cos for degree angles:
+ */
+#define SIND( A ) sin( (A)*(M_PI/180.0) )
+#define COSD( A) cos( (A)*(M_PI/180.0) )
+
+
+/*
+ * Texture coordinates if texture flag is set
+ */
+#define TXTR_COORD(x,y) if (qobj->TextureFlag) glTexCoord2f(x,y);
+
+
+
+struct GLUquadric
+{
+ GLenum DrawStyle; /* GLU_FILL, LINE, SILHOUETTE, or POINT */
+ GLenum Orientation; /* GLU_INSIDE or GLU_OUTSIDE */
+ GLboolean TextureFlag; /* Generate texture coords? */
+ GLenum Normals; /* GLU_NONE, GLU_FLAT, or GLU_SMOOTH */
+ void (GLCALLBACK * ErrorFunc) (GLenum err); /* Error handler callback function */
+};
+
+
+
+/*
+ * Process a GLU error.
+ */
+static void
+quadric_error(GLUquadricObj * qobj, GLenum error, const char *msg)
+{
+ /* Call the error call back function if any */
+ if (qobj->ErrorFunc) {
+ (*qobj->ErrorFunc) (error);
+ }
+ /* Print a message to stdout if MESA_DEBUG variable is defined */
+ if (getenv("MESA_DEBUG")) {
+ fprintf(stderr, "GLUError: %s: %s\n", (char *) gluErrorString(error),
+ msg);
+ }
+}
+
+
+
+
+GLUquadricObj *GLAPIENTRY
+gluNewQuadric(void)
+{
+ GLUquadricObj *q;
+
+ q = (GLUquadricObj *) malloc(sizeof(struct GLUquadric));
+ if (q) {
+ q->DrawStyle = GLU_FILL;
+ q->Orientation = GLU_OUTSIDE;
+ q->TextureFlag = GL_FALSE;
+ q->Normals = GLU_SMOOTH;
+ q->ErrorFunc = NULL;
+ }
+ return q;
+}
+
+
+
+void GLAPIENTRY
+gluDeleteQuadric(GLUquadricObj * state)
+{
+ if (state) {
+ free((void *) state);
+ }
+}
+
+
+
+/*
+ * Set the drawing style to be GLU_FILL, GLU_LINE, GLU_SILHOUETTE,
+ * or GLU_POINT.
+ */
+void GLAPIENTRY
+gluQuadricDrawStyle(GLUquadricObj * quadObject, GLenum drawStyle)
+{
+ if (quadObject && (drawStyle == GLU_FILL || drawStyle == GLU_LINE
+ || drawStyle == GLU_SILHOUETTE
+ || drawStyle == GLU_POINT)) {
+ quadObject->DrawStyle = drawStyle;
+ }
+ else {
+ quadric_error(quadObject, GLU_INVALID_ENUM, "qluQuadricDrawStyle");
+ }
+}
+
+
+
+/*
+ * Set the orientation to GLU_INSIDE or GLU_OUTSIDE.
+ */
+void GLAPIENTRY
+gluQuadricOrientation(GLUquadricObj * quadObject, GLenum orientation)
+{
+ if (quadObject
+ && (orientation == GLU_INSIDE || orientation == GLU_OUTSIDE)) {
+ quadObject->Orientation = orientation;
+ }
+ else {
+ quadric_error(quadObject, GLU_INVALID_ENUM, "qluQuadricOrientation");
+ }
+}
+
+
+
+/*
+ * Set the error handler callback function.
+ */
+void GLAPIENTRY
+gluQuadricCallback(GLUquadricObj * qobj,
+ GLenum which, void (GLCALLBACK * fn) ())
+{
+ /*
+ * UGH, this is a mess! I thought ANSI was a standard.
+ */
+ if (qobj && which == GLU_ERROR) {
+#ifdef __CYGWIN32__
+ qobj->ErrorFunc = (void (GLCALLBACKPCAST) (GLenum)) fn;
+#elif defined(OPENSTEP)
+ qobj->ErrorFunc = (void (*)(GLenum)) fn;
+#elif defined(_WIN32)
+ qobj->ErrorFunc = (void (GLCALLBACK *) (int)) fn;
+#elif defined(__STORM__)
+ qobj->ErrorFunc = (void (GLCALLBACK *) (GLenum)) fn;
+#elif defined(__BEOS__)
+ qobj->ErrorFunc = (void (*)(GLenum)) fn;
+#else
+ qobj->ErrorFunc = (void (GLCALLBACK *) ()) fn;
+#endif
+ }
+}
+
+
+void GLAPIENTRY
+gluQuadricNormals(GLUquadricObj * quadObject, GLenum normals)
+{
+ if (quadObject
+ && (normals == GLU_NONE || normals == GLU_FLAT
+ || normals == GLU_SMOOTH)) {
+ quadObject->Normals = normals;
+ }
+}
+
+
+void GLAPIENTRY
+gluQuadricTexture(GLUquadricObj * quadObject, GLboolean textureCoords)
+{
+ if (quadObject) {
+ quadObject->TextureFlag = textureCoords;
+ }
+}
+
+
+
+
+/*
+ * Call glNormal3f after scaling normal to unit length.
+ */
+static void
+normal3f(GLfloat x, GLfloat y, GLfloat z)
+{
+ GLdouble mag;
+
+ mag = sqrt(x * x + y * y + z * z);
+ if (mag > 0.00001F) {
+ x /= mag;
+ y /= mag;
+ z /= mag;
+ }
+ glNormal3f(x, y, z);
+}
+
+
+
+void GLAPIENTRY
+gluCylinder(GLUquadricObj * qobj,
+ GLdouble baseRadius, GLdouble topRadius,
+ GLdouble height, GLint slices, GLint stacks)
+{
+ GLdouble da, r, dr, dz;
+ GLfloat x, y, z, nz, nsign;
+ GLint i, j;
+
+ if (qobj->Orientation == GLU_INSIDE) {
+ nsign = -1.0;
+ }
+ else {
+ nsign = 1.0;
+ }
+
+ da = 2.0 * M_PI / slices;
+ dr = (topRadius - baseRadius) / stacks;
+ dz = height / stacks;
+ nz = (baseRadius - topRadius) / height; /* Z component of normal vectors */
+
+ if (qobj->DrawStyle == GLU_POINT) {
+ glBegin(GL_POINTS);
+ for (i = 0; i < slices; i++) {
+ x = cos(i * da);
+ y = sin(i * da);
+ normal3f(x * nsign, y * nsign, nz * nsign);
+
+ z = 0.0;
+ r = baseRadius;
+ for (j = 0; j <= stacks; j++) {
+ glVertex3f(x * r, y * r, z);
+ z += dz;
+ r += dr;
+ }
+ }
+ glEnd();
+ }
+ else if (qobj->DrawStyle == GLU_LINE || qobj->DrawStyle == GLU_SILHOUETTE) {
+ /* Draw rings */
+ if (qobj->DrawStyle == GLU_LINE) {
+ z = 0.0;
+ r = baseRadius;
+ for (j = 0; j <= stacks; j++) {
+ glBegin(GL_LINE_LOOP);
+ for (i = 0; i < slices; i++) {
+ x = cos(i * da);
+ y = sin(i * da);
+ normal3f(x * nsign, y * nsign, nz * nsign);
+ glVertex3f(x * r, y * r, z);
+ }
+ glEnd();
+ z += dz;
+ r += dr;
+ }
+ }
+ else {
+ /* draw one ring at each end */
+ if (baseRadius != 0.0) {
+ glBegin(GL_LINE_LOOP);
+ for (i = 0; i < slices; i++) {
+ x = cos(i * da);
+ y = sin(i * da);
+ normal3f(x * nsign, y * nsign, nz * nsign);
+ glVertex3f(x * baseRadius, y * baseRadius, 0.0);
+ }
+ glEnd();
+ glBegin(GL_LINE_LOOP);
+ for (i = 0; i < slices; i++) {
+ x = cos(i * da);
+ y = sin(i * da);
+ normal3f(x * nsign, y * nsign, nz * nsign);
+ glVertex3f(x * topRadius, y * topRadius, height);
+ }
+ glEnd();
+ }
+ }
+ /* draw length lines */
+ glBegin(GL_LINES);
+ for (i = 0; i < slices; i++) {
+ x = cos(i * da);
+ y = sin(i * da);
+ normal3f(x * nsign, y * nsign, nz * nsign);
+ glVertex3f(x * baseRadius, y * baseRadius, 0.0);
+ glVertex3f(x * topRadius, y * topRadius, height);
+ }
+ glEnd();
+ }
+ else if (qobj->DrawStyle == GLU_FILL) {
+ GLfloat ds = 1.0 / slices;
+ GLfloat dt = 1.0 / stacks;
+ GLfloat t = 0.0;
+ z = 0.0;
+ r = baseRadius;
+ for (j = 0; j < stacks; j++) {
+ GLfloat s = 0.0;
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= slices; i++) {
+ GLfloat x, y;
+ if (i == slices) {
+ x = sin(0.0);
+ y = cos(0.0);
+ }
+ else {
+ x = sin(i * da);
+ y = cos(i * da);
+ }
+ if (nsign == 1.0) {
+ normal3f(x * nsign, y * nsign, nz * nsign);
+ TXTR_COORD(s, t);
+ glVertex3f(x * r, y * r, z);
+ normal3f(x * nsign, y * nsign, nz * nsign);
+ TXTR_COORD(s, t + dt);
+ glVertex3f(x * (r + dr), y * (r + dr), z + dz);
+ }
+ else {
+ normal3f(x * nsign, y * nsign, nz * nsign);
+ TXTR_COORD(s, t);
+ glVertex3f(x * r, y * r, z);
+ normal3f(x * nsign, y * nsign, nz * nsign);
+ TXTR_COORD(s, t + dt);
+ glVertex3f(x * (r + dr), y * (r + dr), z + dz);
+ }
+ s += ds;
+ } /* for slices */
+ glEnd();
+ r += dr;
+ t += dt;
+ z += dz;
+ } /* for stacks */
+ }
+}
+
+
+
+
+
+void GLAPIENTRY
+gluSphere(GLUquadricObj * qobj, GLdouble radius, GLint slices, GLint stacks)
+{
+ GLfloat rho, drho, theta, dtheta;
+ GLfloat x, y, z;
+ GLfloat s, t, ds, dt;
+ GLint i, j, imin, imax;
+ GLboolean normals;
+ GLfloat nsign;
+
+ if (qobj->Normals == GLU_NONE) {
+ normals = GL_FALSE;
+ }
+ else {
+ normals = GL_TRUE;
+ }
+ if (qobj->Orientation == GLU_INSIDE) {
+ nsign = -1.0;
+ }
+ else {
+ nsign = 1.0;
+ }
+
+ drho = M_PI / (GLfloat) stacks;
+ dtheta = 2.0 * M_PI / (GLfloat) slices;
+
+ /* texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y axis */
+ /* t goes from -1.0/+1.0 at z = -radius/+radius (linear along longitudes) */
+ /* cannot use triangle fan on texturing (s coord. at top/bottom tip varies) */
+
+ if (qobj->DrawStyle == GLU_FILL) {
+ if (!qobj->TextureFlag) {
+ /* draw +Z end as a triangle fan */
+ glBegin(GL_TRIANGLE_FAN);
+ glNormal3f(0.0, 0.0, 1.0);
+ glVertex3f(0.0, 0.0, nsign * radius);
+ for (j = 0; j <= slices; j++) {
+ theta = (j == slices) ? 0.0 : j * dtheta;
+ x = -sin(theta) * sin(drho);
+ y = cos(theta) * sin(drho);
+ z = nsign * cos(drho);
+ if (normals)
+ glNormal3f(x * nsign, y * nsign, z * nsign);
+ glVertex3f(x * radius, y * radius, z * radius);
+ }
+ glEnd();
+ }
+
+ ds = 1.0 / slices;
+ dt = 1.0 / stacks;
+ t = 1.0; /* because loop now runs from 0 */
+ if (qobj->TextureFlag) {
+ imin = 0;
+ imax = stacks;
+ }
+ else {
+ imin = 1;
+ imax = stacks - 1;
+ }
+
+ /* draw intermediate stacks as quad strips */
+ for (i = imin; i < imax; i++) {
+ rho = i * drho;
+ glBegin(GL_QUAD_STRIP);
+ s = 0.0;
+ for (j = 0; j <= slices; j++) {
+ theta = (j == slices) ? 0.0 : j * dtheta;
+ x = -sin(theta) * sin(rho);
+ y = cos(theta) * sin(rho);
+ z = nsign * cos(rho);
+ if (normals)
+ glNormal3f(x * nsign, y * nsign, z * nsign);
+ TXTR_COORD(s, t);
+ glVertex3f(x * radius, y * radius, z * radius);
+ x = -sin(theta) * sin(rho + drho);
+ y = cos(theta) * sin(rho + drho);
+ z = nsign * cos(rho + drho);
+ if (normals)
+ glNormal3f(x * nsign, y * nsign, z * nsign);
+ TXTR_COORD(s, t - dt);
+ s += ds;
+ glVertex3f(x * radius, y * radius, z * radius);
+ }
+ glEnd();
+ t -= dt;
+ }
+
+ if (!qobj->TextureFlag) {
+ /* draw -Z end as a triangle fan */
+ glBegin(GL_TRIANGLE_FAN);
+ glNormal3f(0.0, 0.0, -1.0);
+ glVertex3f(0.0, 0.0, -radius * nsign);
+ rho = M_PI - drho;
+ s = 1.0;
+ t = dt;
+ for (j = slices; j >= 0; j--) {
+ theta = (j == slices) ? 0.0 : j * dtheta;
+ x = -sin(theta) * sin(rho);
+ y = cos(theta) * sin(rho);
+ z = nsign * cos(rho);
+ if (normals)
+ glNormal3f(x * nsign, y * nsign, z * nsign);
+ s -= ds;
+ glVertex3f(x * radius, y * radius, z * radius);
+ }
+ glEnd();
+ }
+ }
+ else if (qobj->DrawStyle == GLU_LINE || qobj->DrawStyle == GLU_SILHOUETTE) {
+ /* draw stack lines */
+ for (i = 1; i < stacks; i++) { /* stack line at i==stacks-1 was missing here */
+ rho = i * drho;
+ glBegin(GL_LINE_LOOP);
+ for (j = 0; j < slices; j++) {
+ theta = j * dtheta;
+ x = cos(theta) * sin(rho);
+ y = sin(theta) * sin(rho);
+ z = cos(rho);
+ if (normals)
+ glNormal3f(x * nsign, y * nsign, z * nsign);
+ glVertex3f(x * radius, y * radius, z * radius);
+ }
+ glEnd();
+ }
+ /* draw slice lines */
+ for (j = 0; j < slices; j++) {
+ theta = j * dtheta;
+ glBegin(GL_LINE_STRIP);
+ for (i = 0; i <= stacks; i++) {
+ rho = i * drho;
+ x = cos(theta) * sin(rho);
+ y = sin(theta) * sin(rho);
+ z = cos(rho);
+ if (normals)
+ glNormal3f(x * nsign, y * nsign, z * nsign);
+ glVertex3f(x * radius, y * radius, z * radius);
+ }
+ glEnd();
+ }
+ }
+ else if (qobj->DrawStyle == GLU_POINT) {
+ /* top and bottom-most points */
+ glBegin(GL_POINTS);
+ if (normals)
+ glNormal3f(0.0, 0.0, nsign);
+ glVertex3d(0.0, 0.0, radius);
+ if (normals)
+ glNormal3f(0.0, 0.0, -nsign);
+ glVertex3d(0.0, 0.0, -radius);
+
+ /* loop over stacks */
+ for (i = 1; i < stacks - 1; i++) {
+ rho = i * drho;
+ for (j = 0; j < slices; j++) {
+ theta = j * dtheta;
+ x = cos(theta) * sin(rho);
+ y = sin(theta) * sin(rho);
+ z = cos(rho);
+ if (normals)
+ glNormal3f(x * nsign, y * nsign, z * nsign);
+ glVertex3f(x * radius, y * radius, z * radius);
+ }
+ }
+ glEnd();
+ }
+
+}
+
+
+
+void GLAPIENTRY
+gluDisk(GLUquadricObj * qobj,
+ GLdouble innerRadius, GLdouble outerRadius, GLint slices, GLint loops)
+{
+ GLfloat da, dr;
+#if 0
+ GLdouble a, da;
+ GLfloat r, dr;
+ GLfloat x, y;
+ GLfloat r1, r2, dtc;
+ GLint s, l;
+#endif
+
+ /* Normal vectors */
+ if (qobj->Normals != GLU_NONE) {
+ if (qobj->Orientation == GLU_OUTSIDE) {
+ glNormal3f(0.0, 0.0, +1.0);
+ }
+ else {
+ glNormal3f(0.0, 0.0, -1.0);
+ }
+ }
+
+ da = 2.0 * M_PI / slices;
+ dr = (outerRadius - innerRadius) / (GLfloat) loops;
+
+ switch (qobj->DrawStyle) {
+ case GLU_FILL:
+ {
+ /* texture of a gluDisk is a cut out of the texture unit square
+ * x, y in [-outerRadius, +outerRadius]; s, t in [0, 1]
+ * (linear mapping)
+ */
+ GLfloat dtc = 2.0f * outerRadius;
+ GLfloat sa, ca;
+ GLfloat r1 = innerRadius;
+ GLint l;
+ for (l = 0; l < loops; l++) {
+ GLfloat r2 = r1 + dr;
+ if (qobj->Orientation == GLU_OUTSIDE) {
+ GLint s;
+ glBegin(GL_QUAD_STRIP);
+ for (s = 0; s <= slices; s++) {
+ GLfloat a;
+ if (s == slices)
+ a = 0.0;
+ else
+ a = s * da;
+ sa = sin(a);
+ ca = cos(a);
+ TXTR_COORD(0.5 + sa * r2 / dtc, 0.5 + ca * r2 / dtc);
+ glVertex2f(r2 * sa, r2 * ca);
+ TXTR_COORD(0.5 + sa * r1 / dtc, 0.5 + ca * r1 / dtc);
+ glVertex2f(r1 * sa, r1 * ca);
+ }
+ glEnd();
+ }
+ else {
+ GLint s;
+ glBegin(GL_QUAD_STRIP);
+ for (s = slices; s >= 0; s--) {
+ GLfloat a;
+ if (s == slices)
+ a = 0.0;
+ else
+ a = s * da;
+ sa = sin(a);
+ ca = cos(a);
+ TXTR_COORD(0.5 - sa * r2 / dtc, 0.5 + ca * r2 / dtc);
+ glVertex2f(r2 * sa, r2 * ca);
+ TXTR_COORD(0.5 - sa * r1 / dtc, 0.5 + ca * r1 / dtc);
+ glVertex2f(r1 * sa, r1 * ca);
+ }
+ glEnd();
+ }
+ r1 = r2;
+ }
+ break;
+ }
+ case GLU_LINE:
+ {
+ GLint l, s;
+ /* draw loops */
+ for (l = 0; l <= loops; l++) {
+ GLfloat r = innerRadius + l * dr;
+ glBegin(GL_LINE_LOOP);
+ for (s = 0; s < slices; s++) {
+ GLfloat a = s * da;
+ glVertex2f(r * sin(a), r * cos(a));
+ }
+ glEnd();
+ }
+ /* draw spokes */
+ for (s = 0; s < slices; s++) {
+ GLfloat a = s * da;
+ GLfloat x = sin(a);
+ GLfloat y = cos(a);
+ glBegin(GL_LINE_STRIP);
+ for (l = 0; l <= loops; l++) {
+ GLfloat r = innerRadius + l * dr;
+ glVertex2f(r * x, r * y);
+ }
+ glEnd();
+ }
+ break;
+ }
+ case GLU_POINT:
+ {
+ GLint s;
+ glBegin(GL_POINTS);
+ for (s = 0; s < slices; s++) {
+ GLfloat a = s * da;
+ GLfloat x = sin(a);
+ GLfloat y = cos(a);
+ GLint l;
+ for (l = 0; l <= loops; l++) {
+ GLfloat r = innerRadius * l * dr;
+ glVertex2f(r * x, r * y);
+ }
+ }
+ glEnd();
+ break;
+ }
+ case GLU_SILHOUETTE:
+ {
+ if (innerRadius != 0.0) {
+ GLfloat a;
+ glBegin(GL_LINE_LOOP);
+ for (a = 0.0; a < 2.0 * M_PI; a += da) {
+ GLfloat x = innerRadius * sin(a);
+ GLfloat y = innerRadius * cos(a);
+ glVertex2f(x, y);
+ }
+ glEnd();
+ }
+ {
+ GLfloat a;
+ glBegin(GL_LINE_LOOP);
+ for (a = 0; a < 2.0 * M_PI; a += da) {
+ GLfloat x = outerRadius * sin(a);
+ GLfloat y = outerRadius * cos(a);
+ glVertex2f(x, y);
+ }
+ glEnd();
+ }
+ break;
+ }
+ default:
+ abort();
+ }
+}
+
+
+
+void GLAPIENTRY
+gluPartialDisk(GLUquadricObj * qobj, GLdouble innerRadius,
+ GLdouble outerRadius, GLint slices, GLint loops,
+ GLdouble startAngle, GLdouble sweepAngle)
+{
+ if (qobj->Normals != GLU_NONE) {
+ if (qobj->Orientation == GLU_OUTSIDE) {
+ glNormal3f(0.0, 0.0, +1.0);
+ }
+ else {
+ glNormal3f(0.0, 0.0, -1.0);
+ }
+ }
+
+ if (qobj->DrawStyle == GLU_POINT) {
+ GLint loop, slice;
+ GLdouble radius, delta_radius;
+ GLdouble angle, delta_angle;
+ delta_radius = (outerRadius - innerRadius) / (loops - 1);
+ delta_angle = DEG_TO_RAD((sweepAngle) / (slices - 1));
+ glBegin(GL_POINTS);
+ radius = innerRadius;
+ for (loop = 0; loop < loops; loop++) {
+ angle = DEG_TO_RAD(startAngle);
+ for (slice = 0; slice < slices; slice++) {
+ glVertex2d(radius * sin(angle), radius * cos(angle));
+ angle += delta_angle;
+ }
+ radius += delta_radius;
+ }
+ glEnd();
+ }
+ else if (qobj->DrawStyle == GLU_LINE) {
+ GLint loop, slice;
+ GLdouble radius, delta_radius;
+ GLdouble angle, delta_angle;
+ delta_radius = (outerRadius - innerRadius) / loops;
+ delta_angle = DEG_TO_RAD(sweepAngle / slices);
+ /* draw rings */
+ radius = innerRadius;
+ for (loop = 0; loop < loops; loop++) {
+ angle = DEG_TO_RAD(startAngle);
+ glBegin(GL_LINE_STRIP);
+ for (slice = 0; slice <= slices; slice++) {
+ glVertex2d(radius * sin(angle), radius * cos(angle));
+ angle += delta_angle;
+ }
+ glEnd();
+ radius += delta_radius;
+ }
+ /* draw spokes */
+ angle = DEG_TO_RAD(startAngle);
+ for (slice = 0; slice <= slices; slice++) {
+ radius = innerRadius;
+ glBegin(GL_LINE_STRIP);
+ for (loop = 0; loop < loops; loop++) {
+ glVertex2d(radius * sin(angle), radius * cos(angle));
+ radius += delta_radius;
+ }
+ glEnd();
+ angle += delta_angle;
+ }
+ }
+ else if (qobj->DrawStyle == GLU_SILHOUETTE) {
+ GLint slice;
+ GLdouble angle, delta_angle;
+ delta_angle = DEG_TO_RAD(sweepAngle / slices);
+ /* draw outer ring */
+ glBegin(GL_LINE_STRIP);
+ angle = DEG_TO_RAD(startAngle);
+ for (slice = 0; slice <= slices; slice++) {
+ glVertex2d(outerRadius * sin(angle), outerRadius * cos(angle));
+ angle += delta_angle;
+ }
+ glEnd();
+ /* draw inner ring */
+ if (innerRadius > 0.0) {
+ glBegin(GL_LINE_STRIP);
+ angle = DEG_TO_RAD(startAngle);
+ for (slice = 0; slice < slices; slice++) {
+ glVertex2d(innerRadius * sin(angle), innerRadius * cos(angle));
+ angle += delta_angle;
+ }
+ glEnd();
+ }
+ /* draw spokes */
+ if (sweepAngle < 360.0) {
+ GLdouble stopAngle = startAngle + sweepAngle;
+ glBegin(GL_LINES);
+ glVertex2d(innerRadius * SIND(startAngle),
+ innerRadius * COSD(startAngle));
+ glVertex2d(outerRadius * SIND(startAngle),
+ outerRadius * COSD(startAngle));
+ glVertex2d(innerRadius * SIND(stopAngle),
+ innerRadius * COSD(stopAngle));
+ glVertex2d(outerRadius * SIND(stopAngle),
+ outerRadius * COSD(stopAngle));
+ glEnd();
+ }
+ }
+ else if (qobj->DrawStyle == GLU_FILL) {
+ GLint loop, slice;
+ GLdouble radius, delta_radius;
+ GLdouble angle, delta_angle;
+ delta_radius = (outerRadius - innerRadius) / loops;
+ delta_angle = DEG_TO_RAD(sweepAngle / slices);
+ radius = innerRadius;
+ for (loop = 0; loop < loops; loop++) {
+ glBegin(GL_QUAD_STRIP);
+ angle = DEG_TO_RAD(startAngle);
+ for (slice = 0; slice <= slices; slice++) {
+ if (qobj->Orientation == GLU_OUTSIDE) {
+ glVertex2d((radius + delta_radius) * sin(angle),
+ (radius + delta_radius) * cos(angle));
+ glVertex2d(radius * sin(angle), radius * cos(angle));
+ }
+ else {
+ glVertex2d(radius * sin(angle), radius * cos(angle));
+ glVertex2d((radius + delta_radius) * sin(angle),
+ (radius + delta_radius) * cos(angle));
+ }
+ angle += delta_angle;
+ }
+ glEnd();
+ radius += delta_radius;
+ }
+ }
+}