home *** CD-ROM | disk | FTP | other *** search
/ Aminet 10 / aminetcdnumber101996.iso / Aminet / gfx / x11 / Mesa_Amiwin.lha / Mesa-Amiwin / src-glu / quadric.c < prev    next >
C/C++ Source or Header  |  1995-11-17  |  18KB  |  707 lines

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