home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / mesa-1.2.8 / src-glu / quadric.c < prev    next >
C/C++ Source or Header  |  1996-05-27  |  20KB  |  797 lines

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