Listing 8 (solrdr. c)

#include "solid.h"

void render_facet(struct solid_obj *obj_ptr,
   struct facet *facet_ptr)
/*  renders (shades) and displays a facet */
{
   struct vertex *vertex_ptr;
   int x_first, y_first; /* screen coords for 1st
      vertex of facet */
   int vertex_ref_index;
   float screen_x, screen_y; /* screen coords */
   float x_normal, y_normal, z_normal; /* surface
      normal vector */
   float x_total, y_total, x_ave, y_ave;
      /* coords to compute seed point for fill */
   float light_vect_x, light_vect_y, light_vect_z;
      /* unit vector from light source to first
      vertex of facet */
   struct vector normal; /* unit vector normal to
      facet */
   float unit; /* mult. factor to get unit vector */
   float illum_x, illum_y, illum_z; /* illumination */
   int illum;
   char fill_pat[12][8] = {
      {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
         /*   0% */
      {0x0, 0x20, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0},
         /*   3% */
      {0x20, 0x0, 0x2, 0x0, 0x80, 0x0, 0x8, 0x0},
         /*   6% */
      {0x20, 0x2, 0x80, 0x8, 0x20, 0x2, 0x80, 0x8},
         /*  12% */
      {0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
         0x11}, /*  25% */
      {0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa,
         0x11}, /*  37% */
      {0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55,
         0xaa}, /*  50% */
      {0x55, 0xbb, 0x55, 0xec, 0x55, 0xbb, 0x55,
         0xec}, /*  62% */
      {0xbb, 0xec, 0xbb, 0xec, 0xbb, 0xec, 0xbb,
         0xec}, /*  75% */
      {0xdf, 0xfd, 0x7f, 0xf7, 0xdf, 0xfd, 0x7f,
         0xf7}, /*  87% */
      {0xff, 0xdf, 0xff, 0xff, 0xff, 0xed, 0xff,
         0xff}, /*  93% */
      {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
         0xff}}; /* 100% */
   unsigned line_pat[12] : {0x0000, 0x0000, 0x0100,
      0x1010, 0x4444, 0x8a8a, 0xaaaa, 0xdada, 0xdddd,
      0xdfdf, 0xefef, 0xffff};

   setcolor(WHITE); /* draw white border */
   setlinestyle(SOLID_LINE, NULL, NORM_WIDTH);
   draw_polygon(obj_ptr, facet_ptr);

   /* seed point for fill */
   x_total = y_total = 0.0;
   for (vertex_ref_index = 0; vertex_ref_index <
      facet_ptr->vertex_count; ++vertex_ref_index) {
      vertex_ptr = obj_ptr->vertex_first +
         facet_ptr->vertex_index[vertex_ref_index];
      x_total += proj_d * vertex_ptr->coord[0] /
         proj_z;
      y_total += proj_d * vertex_ptr->coord[1] /
         proj_z;
   }
   x_ave = x_total / facet_ptr->vertex_count;
   y_ave = y_total / facet_ptr->vertex_count;

   /* unit vector from 1st vertex to light source */
   light_vect_x = light_x;
   light_vect_y = light_y;
   light_vect_z = light_z;
   unit = 1.0 / sqrt(light_vect_x * light_vect_x +
      light_vect_y * light_vect_y + light_vect_z *
      light_vect_z);
   light_vect_x *= unit;
   light_vect_y *= unit;
   light_vect_z *= unit;

   /* unit vector normal to facet */
   normal = normal_vector(obj_ptr, facet_ptr);
   unit = 1.0 / sqrt(normal.x * normal.x + normal.y *
      normal.y + normal.z * normal.z);
   normal.x *= unit;
   normal.y *= unit;
   normal.z *= unit;

   /* illumination and shading */
   illum_x = light_vect_x * normal.x;
   illum_y = light_vect_y * normal.y;
   illum_z = light_vect_z * normal.z;
   illum = 1 + (int)((((illum_x < 0.0) ? 0.0 :
      illum_x) + ((illum_y < 0.0) ? 0.0 : illum_y) +
      ((illum_z < 0.0) ? 0.0 : illum_z)) * 11.0 -
      0.5);
   setfillpattern(&fill_pat[illum][0],
      obj_ptr->color); /* fill polygon */
   floodfill((int)(((x_ave - screen_x_min) /
      (screen_x_max - screen_x_min)) * maxx),
      (int)(((y_ave - screen_y_min) /
      (screen_y_max - screen_y_min)) * maxy), WHITE);
   setcolor(color_bkgd); /* redraw border in
      background color */
   draw_polygon(obj_ptr, facet_ptr);
   setcolor(obj_ptr->color); /* overlay border with
      pattern */
   setlinestyle(USERBIT_LINE, line_pat[illum],
      NORM_WIDTH);
   draw_polygon(obj_ptr, facet_ptr);
   return;
}
/* End of File */