-/* Rendering the 3D objects into the scene.
- */
-
-
-/* Draws an uncapped tube of the given radius extending from top to bottom,
- with faces pointing either in or out.
- */
-static int
-draw_ring (ModeInfo *mi, int segments,
- GLfloat r, GLfloat top, GLfloat bottom, Bool in_p)
-{
- int i;
- int polys = 0;
- Bool wire_p = MI_IS_WIREFRAME(mi);
- GLfloat width = M_PI * 2 / segments;
-
- if (top != bottom)
- {
- glFrontFace (in_p ? GL_CCW : GL_CW);
- glBegin (wire_p ? GL_LINES : GL_QUAD_STRIP);
- for (i = 0; i < segments + (wire_p ? 0 : 1); i++)
- {
- GLfloat th = i * width;
- GLfloat cth = cos(th);
- GLfloat sth = sin(th);
- if (in_p)
- glNormal3f (-cth, -sth, 0);
- else
- glNormal3f (cth, sth, 0);
- glVertex3f (cth * r, sth * r, top);
- glVertex3f (cth * r, sth * r, bottom);
- }
- polys += segments;
- glEnd();
- }
-
- if (wire_p)
- {
- glBegin (GL_LINE_LOOP);
- for (i = 0; i < segments; i++)
- {
- GLfloat th = i * width;
- glVertex3f (cos(th) * r, sin(th) * r, top);
- }
- glEnd();
- glBegin (GL_LINE_LOOP);
- for (i = 0; i < segments; i++)
- {
- GLfloat th = i * width;
- glVertex3f (cos(th) * r, sin(th) * r, bottom);
- }
- glEnd();
- }
-
- return polys;
-}
-
-
-/* Draws a donut-shaped disc between the given radii,
- with faces pointing either up or down.
- The first radius may be 0, in which case, a filled disc is drawn.
- */
-static int
-draw_disc (ModeInfo *mi, int segments,
- GLfloat ra, GLfloat rb, GLfloat z, Bool up_p)
-{
- int i;
- int polys = 0;
- Bool wire_p = MI_IS_WIREFRAME(mi);
- GLfloat width = M_PI * 2 / segments;
-
- if (ra < 0) abort();
- if (rb <= 0) abort();
-
- if (ra == 0)
- glFrontFace (up_p ? GL_CW : GL_CCW);
- else
- glFrontFace (up_p ? GL_CCW : GL_CW);
-
- if (ra == 0)
- glBegin (wire_p ? GL_LINES : GL_TRIANGLE_FAN);
- else
- glBegin (wire_p ? GL_LINES : GL_QUAD_STRIP);
-
- glNormal3f (0, 0, (up_p ? -1 : 1));
-
- if (ra == 0 && !wire_p)
- glVertex3f (0, 0, z);
-
- for (i = 0; i < segments + (wire_p ? 0 : 1); i++)
- {
- GLfloat th = i * width;
- GLfloat cth = cos(th);
- GLfloat sth = sin(th);
- if (wire_p || ra != 0)
- glVertex3f (cth * ra, sth * ra, z);
- glVertex3f (cth * rb, sth * rb, z);
- polys++;
- }
- glEnd();
- return polys;
-}
-
-
-/* Draws N thick radial lines between the given radii,
- with faces pointing either up or down.
- */
-static int
-draw_spokes (ModeInfo *mi, int n, GLfloat thickness, int segments,
- GLfloat ra, GLfloat rb, GLfloat z1, GLfloat z2)
-{
- int i;
- int polys = 0;
- Bool wire_p = MI_IS_WIREFRAME(mi);
- GLfloat width;
- int segments2 = 0;
- int insegs, outsegs;
- int tick;
- int state;
-
- if (ra <= 0 || rb <= 0) abort();
-
- segments *= 3;
-
- while (segments2 < segments) /* need a multiple of N >= segments */
- segments2 += n; /* (yes, this is a moronic way to find that) */
-
- insegs = ((float) (segments2 / n) + 0.5) / thickness;
- outsegs = (segments2 / n) - insegs;
- if (insegs <= 0) insegs = 1;
- if (outsegs <= 0) outsegs = 1;
-
- segments2 = (insegs + outsegs) * n;
- width = M_PI * 2 / segments2;
-
- tick = 0;
- state = 0;
- for (i = 0; i < segments2; i++, tick++)
- {
- GLfloat th1 = i * width;
- GLfloat th2 = th1 + width;
- GLfloat cth1 = cos(th1);
- GLfloat sth1 = sin(th1);
- GLfloat cth2 = cos(th2);
- GLfloat sth2 = sin(th2);
- GLfloat orb = rb;
-
- int changed = (i == 0);
-
- if (state == 0 && tick == insegs)
- tick = 0, state = 1, changed = 1;
- else if (state == 1 && tick == outsegs)
- tick = 0, state = 0, changed = 1;
-
- if ((state == 1 || /* in */
- (state == 0 && changed)) &&
- (!wire_p || wire_all_p))
- {
- /* top */
- glFrontFace (GL_CCW);
- glBegin (wire_p ? GL_LINES : GL_QUADS);
- glNormal3f (0, 0, -1);
- glVertex3f (cth1 * ra, sth1 * ra, z1);
- glVertex3f (cth1 * rb, sth1 * rb, z1);
- glVertex3f (cth2 * rb, sth2 * rb, z1);
- glVertex3f (cth2 * ra, sth2 * ra, z1);
- polys++;
- glEnd();
-
- /* bottom */
- glFrontFace (GL_CW);
- glBegin (wire_p ? GL_LINES : GL_QUADS);
- glNormal3f (0, 0, 1);
- glVertex3f (cth1 * ra, sth1 * ra, z2);
- glVertex3f (cth1 * rb, sth1 * rb, z2);
- glVertex3f (cth2 * rb, sth2 * rb, z2);
- glVertex3f (cth2 * ra, sth2 * ra, z2);
- polys++;
- glEnd();
- }
-
- if (state == 1 && changed) /* entering "in" state */
- {
- /* left */
- glFrontFace (GL_CW);
- glBegin (wire_p ? GL_LINES : GL_QUADS);
- do_normal (cth1 * rb, sth1 * rb, z1,
- cth1 * ra, sth1 * ra, z1,
- cth1 * rb, sth1 * rb, z2);
- glVertex3f (cth1 * ra, sth1 * ra, z1);
- glVertex3f (cth1 * rb, sth1 * rb, z1);
- glVertex3f (cth1 * rb, sth1 * rb, z2);
- glVertex3f (cth1 * ra, sth1 * ra, z2);
- polys++;
- glEnd();
- }
-
- if (state == 0 && changed) /* entering "out" state */
- {
- /* right */
- glFrontFace (GL_CCW);
- glBegin (wire_p ? GL_LINES : GL_QUADS);
- do_normal (cth2 * ra, sth2 * ra, z1,
- cth2 * rb, sth2 * rb, z1,
- cth2 * rb, sth2 * rb, z2);
- glVertex3f (cth2 * ra, sth2 * ra, z1);
- glVertex3f (cth2 * rb, sth2 * rb, z1);
- glVertex3f (cth2 * rb, sth2 * rb, z2);
- glVertex3f (cth2 * ra, sth2 * ra, z2);
- polys++;
- glEnd();
- }
-
- rb = orb;
- }
- glEnd();
- return polys;
-}
-
-
-/* Draws some bumps (embedded cylinders) on the gear.
- */
-static int
-draw_gear_nubs (ModeInfo *mi, gear *g)
-{
- Bool wire_p = MI_IS_WIREFRAME(mi);
- int polys = 0;
- int i;
- int steps = 20;
- double r, size, height;
- GLfloat *cc;
- int which;
- GLfloat width, off;
-
- if (! g->nubs) return 0;
-
- which = biggest_ring (g, &r, &size, &height);
- size /= 5;
- height *= 0.7;
-
- cc = (which == 1 ? g->color : g->color2);
- glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cc);
-
- width = M_PI * 2 / g->nubs;
- off = M_PI / (g->nteeth * 2); /* align first nub with a tooth */
-
- for (i = 0; i < g->nubs; i++)
- {
- GLfloat th = (i * width) + off;
- glPushMatrix();
- glTranslatef (cos(th) * r, sin(th) * r, 0);
-
- if (wire_p && !wire_all_p)
- polys += draw_ring (mi, steps/2, size, 0, 0, False);
- else
- {
- polys += draw_disc (mi, steps, 0, size, -height, True);
- polys += draw_disc (mi, steps, 0, size, height, False);
- polys += draw_ring (mi, steps, size, -height, height, False);
- }
- glPopMatrix();
- }
- return polys;
-}
-
-
-
-/* Draws a much simpler representation of a gear.
- */
-static int
-draw_gear_schematic (ModeInfo *mi, gear *g)
-{
- Bool wire_p = MI_IS_WIREFRAME(mi);
- int polys = 0;
- int i;
- GLfloat width = M_PI * 2 / g->nteeth;
-
- if (!wire_p) glDisable(GL_LIGHTING);
- glColor3f (g->color[0] * 0.6, g->color[1] * 0.6, g->color[2] * 0.6);
-
- glBegin (GL_LINES);
- for (i = 0; i < g->nteeth; i++)
- {
- GLfloat th = (i * width) + (width/4);
- glVertex3f (0, 0, -g->thickness/2);
- glVertex3f (cos(th) * g->r, sin(th) * g->r, -g->thickness/2);
- }
- polys += g->nteeth;
- glEnd();
-
- glBegin (GL_LINE_LOOP);
- for (i = 0; i < g->nteeth; i++)
- {
- GLfloat th = (i * width) + (width/4);
- glVertex3f (cos(th) * g->r, sin(th) * g->r, -g->thickness/2);
- }
- polys += g->nteeth;
- glEnd();
-
- if (!wire_p) glEnable(GL_LIGHTING);
- return polys;
-}
-
-
-/* Renders all the interior (non-toothy) parts of a gear:
- the discs, axles, etc.
- */
-static int
-draw_gear_interior (ModeInfo *mi, gear *g)
-{
- Bool wire_p = MI_IS_WIREFRAME(mi);
- int polys = 0;
-
- int steps = g->nteeth * 2;
- if (steps < 10) steps = 10;
- if (wire_p && !wire_all_p) steps /= 2;
-
- /* ring 1 (facing in) is done in draw_gear_teeth */
-
- /* ring 2 (facing in) and disc 2
- */
- if (g->inner_r2)
- {
- GLfloat ra = g->inner_r;
- GLfloat rb = g->inner_r2;
- GLfloat za = -g->thickness2/2;
- GLfloat zb = g->thickness2/2;
-
- glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, g->color2);
-
- if ((g->coax_p != 1 && !g->inner_r3) ||
- (wire_p && wire_all_p))
- polys += draw_ring (mi, steps, rb, za, zb, True); /* ring facing in */
-
- if (wire_p && wire_all_p)
- polys += draw_ring (mi, steps, ra, za, zb, True); /* ring facing in */
-
- if (g->spokes)
- polys += draw_spokes (mi, g->spokes, g->spoke_thickness,
- steps, ra, rb, za, zb);
- else if (!wire_p || wire_all_p)
- {
- polys += draw_disc (mi, steps, ra, rb, za, True); /* top plate */
- polys += draw_disc (mi, steps, ra, rb, zb, False); /* bottom plate */
- }
- }
-
- /* ring 3 (facing in and out) and disc 3
- */
- if (g->inner_r3)
- {
- GLfloat ra = g->inner_r2;
- GLfloat rb = g->inner_r3;
- GLfloat za = -g->thickness3/2;
- GLfloat zb = g->thickness3/2;
-
- glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, g->color);
-
- polys += draw_ring (mi, steps, ra, za, zb, False); /* ring facing out */
-
- if (g->coax_p != 1 || (wire_p && wire_all_p))
- polys += draw_ring (mi, steps, rb, za, zb, True); /* ring facing in */
-
- if (!wire_p || wire_all_p)
- {
- polys += draw_disc (mi, steps, ra, rb, za, True); /* top plate */
- polys += draw_disc (mi, steps, ra, rb, zb, False); /* bottom plate */
- }
- }
-
- /* axle tube
- */
- if (g->coax_p == 1)
- {
- GLfloat cap_height = g->coax_thickness/3;
-
- GLfloat ra = (g->inner_r3 ? g->inner_r3 :
- g->inner_r2 ? g->inner_r2 :
- g->inner_r);
- GLfloat za = -(g->thickness/2 + cap_height);
- GLfloat zb = g->coax_thickness/2 + plane_displacement + cap_height;
-
- glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, g->color);
-
- if (wire_p && !wire_all_p) steps /= 2;
-
- polys += draw_ring (mi, steps, ra, za, zb, False); /* ring facing out */
-
- if (!wire_p || wire_all_p)
- {
- polys += draw_disc (mi, steps, 0, ra, za, True); /* top plate */
- polys += draw_disc (mi, steps, 0, ra, zb, False); /* bottom plate */
- }
- }
- return polys;
-}
-
-
-/* Computes the vertices and normals of the teeth of a gear.
- This is the heavy lifting: there are a ton of polygons around the
- perimiter of a gear, and the normals are difficult (not radial
- or right angles.)
-
- It would be nice if we could cache this, but the numbers are
- different for essentially every gear:
-
- - Every gear has a different inner_r, so the vertices of the
- inner ring (and thus, the triangle fans on the top and bottom
- faces) are different in a non-scalable way.
-
- - If the ratio between tooth_w and tooth_h changes, the normals
- on the outside edges of the teeth are invalid (this can happen
- every time we start a new train.)
-
- So instead, we rely on OpenGL display lists to do the cacheing for
- us -- we only compute all these normals once per gear, instead of
- once per gear per frame.
- */
-static void
-gear_teeth_geometry (ModeInfo *mi, gear *g,
- int *points_per_tooth_ret,
- XYZ **points_ret,
- XYZ **normals_ret)
-{
- int i;
-
- int ppt = 15; /* points per tooth */
-
- GLfloat width = M_PI * 2 / g->nteeth;
-
- GLfloat rh = g->tooth_h;
- GLfloat tw = width;
- GLfloat fudge = (g->nteeth >= 5 ? 0 : 0.04); /* reshape small ones a bit */
-
- XYZ *points = (XYZ *) calloc (ppt * g->nteeth + 1, sizeof(*points));
- XYZ *fnormals = (XYZ *) calloc (ppt * g->nteeth + 1, sizeof(*points));
- XYZ *pnormals = (XYZ *) calloc (ppt * g->nteeth + 1, sizeof(*points));
- int npoints = 0;
-
- /* Approximate shape of an "involute" gear tooth.
-
- (TH)
- th0 th1 th2 th3 th4 th5 th6 th7 th8 th9 th10
- : : : : : : : : : : :
- : : : : : : : : : : :
- r0 ........:..:..:...___________...:..:..:......:......:..
- : : : /: : :\ : : : : :
- : : : / : : : \ : : : : :
- : : :/ : : : \: : : : :
- r1 ........:.....@...:....:....:...@..:..:......:......:..
- : : @: : : : :@ : : : :
- (R) ...........:...@.:...:....:....:...:.@..........:......:......
- : :@ : : : : : @: : : :
- r2 ........:..@..:...:....:....:...:..@:........:......:..
- : /: : : : : : :\ : : :
- :/ : : : : : : : \: : : /
- r3 ......__/..:..:...:....:....:...:..:..\______________/
- : : : : : : : : : : :
- | : : : : : : : | : :
- : : : : : : : : : : :
- | : : : : : : : | : :
- r4 ......__:_____________________________:________________
- */
-
- GLfloat R = g->r;
-
- GLfloat r[20];
- GLfloat th[20];
-
- r[0] = R + (rh * 0.5);
- r[1] = R + (rh * 0.25);
- r[2] = R - (rh * 0.25);
- r[3] = R - (rh * 0.5);
- r[4] = g->inner_r;
-
- th[0] = -tw * 0.45;
- th[1] = -tw * 0.30;
- th[2] = -tw *(0.16 - fudge);
- th[3] = -tw * 0.04;
- th[4] = 0;
- th[5] = tw * 0.04;
- th[6] = tw *(0.16 - fudge);
- th[7] = tw * 0.30;
- th[8] = tw * 0.45;
- th[9] = width / 2;
- th[10]= th[0] + width;
-
- if (!points || !fnormals || !pnormals)
- {
- fprintf (stderr, "%s: out of memory\n", progname);
- exit (1);
- }
-
- npoints = 0;
-
- /* First, compute the coordinates of every point used for every tooth.
- */
- for (i = 0; i < g->nteeth; i++)
- {
- GLfloat TH = (i * width) + (width/4);
-
-# undef PUSH
-# define PUSH(PR,PTH) \
- points[npoints].x = cos(TH+th[(PTH)]) * r[(PR)]; \
- points[npoints].y = sin(TH+th[(PTH)]) * r[(PR)]; \
- npoints++
-
- /* start1 = npoints; */
-
- PUSH(3, 0); /* tooth left 1 */
- PUSH(2, 1); /* tooth left 2 */
- PUSH(1, 2); /* tooth left 3 */
- PUSH(0, 3); /* tooth top 1 */
- PUSH(0, 5); /* tooth top 2 */
- PUSH(1, 6); /* tooth right 1 */
- PUSH(2, 7); /* tooth right 2 */
- PUSH(3, 8); /* tooth right 3 */
- PUSH(3, 10); /* gap top */
-
- /* end1 = npoints; */
-
- PUSH(4, 8); /* gap interior */
-
- /* start2 = npoints; */
-
- PUSH(4, 10); /* tooth interior 1 */
- PUSH(4, 8); /* tooth interior 2 */
- PUSH(4, 4); /* tooth bottom 1 */
- PUSH(4, 0); /* tooth bottom 2 */
-
- /* end2 = npoints; */
-
- PUSH(3, 4); /* midpoint */
-
- /* mid = npoints-1; */
-
- if (i == 0 && npoints != ppt) abort(); /* go update "ppt"! */
-# undef PUSH
- }
-
-
- /* Now compute the face normals for each facet on the tooth rim.
- */
- for (i = 0; i < npoints; i++)
- {
- XYZ p1, p2, p3;
- p1 = points[i];
- p2 = points[i+1];
- p3 = p1;
- p3.z++;
- fnormals[i] = calc_normal (p1, p2, p3);
- }
-
-
- /* From the face normals, compute the vertex normals (by averaging
- the normals of adjascent faces.)
- */
- for (i = 0; i < npoints; i++)
- {
- int a = (i == 0 ? npoints-1 : i-1);
- int b = i;
-
- /* Kludge to fix the normal on the last top point: since the
- faces go all the way around, this normal pointed clockwise
- instead of radially out. */
- int start1 = (i / ppt) * ppt;
- int end1 = start1 + 9;
- XYZ n1, n2;
-
- if (b == end1-1)
- b = (start1 + ppt == npoints ? 0 : start1 + ppt);
-
- n1 = fnormals[a]; /* normal of [i-1 - i] face */
- n2 = fnormals[b]; /* normal of [i - i+1] face */
- pnormals[i].x = (n1.x + n2.x) / 2;
- pnormals[i].y = (n1.y + n2.y) / 2;
- pnormals[i].z = (n1.z + n2.z) / 2;
- }
-
- free (fnormals);
-
- if (points_ret)
- *points_ret = points;
- else
- free (points);
-
- if (normals_ret)
- *normals_ret = pnormals;
- else
- free (pnormals);
-
- if (points_per_tooth_ret)
- *points_per_tooth_ret = ppt;
-}
-
-
-/* Renders all teeth of a gear.
- */
-static int
-draw_gear_teeth (ModeInfo *mi, gear *g)
-{
- Bool wire_p = MI_IS_WIREFRAME(mi);
- int polys = 0;
- int i;
-
- GLfloat z1 = -g->thickness/2;
- GLfloat z2 = g->thickness/2;
-
- int ppt;
- XYZ *points, *pnormals;
-
- gear_teeth_geometry (mi, g, &ppt, &points, &pnormals);
-
- glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, g->color);
-
- for (i = 0; i < g->nteeth; i++)
- {
- int j;
- GLfloat z;
-
- int start1 = i * ppt;
- int end1 = start1 + 9;
- int start2 = end1 + 1;
- int end2 = start2 + 4;
- int mid = end2;
-
- /* Outside rim of the tooth
- */
- glFrontFace (GL_CW);
- glBegin (wire_p ? GL_LINES : GL_QUAD_STRIP);
- for (j = start1; j < end1; j++)
- {
- glNormal3f (pnormals[j].x, pnormals[j].y, pnormals[j].z);
- glVertex3f (points[j].x, points[j].y, z1);
- glVertex3f (points[j].x, points[j].y, z2);
- polys++;
-
-# if 0
- /* Show the face normal vectors */
- if (wire_p)
- {
- XYZ n = fnormals[j];
- GLfloat x = (points[j].x + points[j+1].x) / 2;
- GLfloat y = (points[j].y + points[j+1].y) / 2;
- GLfloat z = (z1 + z2) / 2;
- glVertex3f (x, y, z);
- glVertex3f (x + n.x, y + n.y, z);
- }
-
- /* Show the vertex normal vectors */
- if (wire_p)
- {
- XYZ n = pnormals[j];
- GLfloat x = points[j].x;
- GLfloat y = points[j].y;
- GLfloat z = (z1 + z2) / 2;
- glVertex3f (x, y, z);
- glVertex3f (x + n.x, y + n.y, z);
- }
-# endif /* 0 */
- }
- glEnd();
-
- /* Some more lines for the outside rim of the tooth...
- */
- if (wire_p)
- {
- glBegin (GL_LINE_STRIP);
- for (j = start1; j < end1; j++)
- glVertex3f (points[j].x, points[j].y, z1);
- glEnd();
- glBegin (GL_LINE_STRIP);
- for (j = start1; j < end1; j++)
- glVertex3f (points[j].x, points[j].y, z2);
- glEnd();
- }
-
- /* Inside rim behind the tooth
- */
- glFrontFace (GL_CW);
- glBegin (wire_p ? GL_LINES : GL_QUAD_STRIP);
- for (j = start2; j < end2; j++)
- {
- glNormal3f (-points[j].x, -points[j].y, 0);
- glVertex3f ( points[j].x, points[j].y, z1);
- glVertex3f ( points[j].x, points[j].y, z2);
- polys++;
- }
- glEnd();
-
- /* Some more lines for the inside rim...
- */
- if (wire_p)
- {
- glBegin (GL_LINE_STRIP);
- for (j = start2; j < end2; j++)
- glVertex3f (points[j].x, points[j].y, z1);
- glEnd();
- glBegin (GL_LINE_STRIP);
- for (j = start2; j < end2; j++)
- glVertex3f (points[j].x, points[j].y, z2);
- glEnd();
- }
-
- /* All top and bottom facets. We can skip all of these in wire mode.
- */
- if (!wire_p || wire_all_p)
- for (z = z1; z <= z2; z += z2-z1)
- {
- /* Flat edge of the tooth
- */
- glFrontFace (z == z1 ? GL_CW : GL_CCW);
- glBegin (wire_p ? GL_LINES : GL_TRIANGLE_FAN);
- glNormal3f (0, 0, z);
- for (j = start1; j < end2; j++)
- {
- if (j == end1-1 || j == end1 || j == start2)
- continue; /* kludge... skip these... */
-
- if (wire_p || j == start1)
- glVertex3f (points[mid].x, points[mid].y, z);
- glVertex3f (points[j].x, points[j].y, z);
- polys++;
- }
- glVertex3f (points[start1].x, points[start1].y, z);
- glEnd();
-
- /* Flat edge between teeth
- */
- glFrontFace (z == z1 ? GL_CW : GL_CCW);
- glBegin (wire_p ? GL_LINES : GL_QUADS);
- glNormal3f (0, 0, z);
- glVertex3f (points[end1-1 ].x, points[end1-1 ].y, z);
- glVertex3f (points[start2 ].x, points[start2 ].y, z);
- glVertex3f (points[start2+1].x, points[start2+1].y, z);
- glVertex3f (points[end1-2 ].x, points[end1-2 ].y, z);
- polys++;
- glEnd();
- }
- }
-
- free (points);
- free (pnormals);
- return polys;
-}
-
-
-/* Render one gear, unrotated at 0,0.
- */
-static int
-draw_gear_1 (ModeInfo *mi, gear *g)
-{
- Bool wire_p = MI_IS_WIREFRAME(mi);
- int polys = 0;
-
- static GLfloat spec[4] = {1.0, 1.0, 1.0, 1.0};
- static GLfloat shiny = 128.0;
-
- glMaterialfv (GL_FRONT, GL_SPECULAR, spec);
- glMateriali (GL_FRONT, GL_SHININESS, shiny);
- glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, g->color);
- glColor3f (g->color[0], g->color[1], g->color[2]);
-
- if (debug_p && wire_p)
- polys += draw_gear_schematic (mi, g);
- else
- {
- glPushMatrix();
- glRotatef (g->wobble, 1, 0, 0);
- polys += draw_gear_teeth (mi, g);
- polys += draw_gear_interior (mi, g);
- polys += draw_gear_nubs (mi, g);
- glPopMatrix();
- }
- return polys;
-}
-
-