Painter's Rendering System


Basic System



Image *img = NULL;
View *view = NULL;
Light *lights = NULL;
OBJECT *o, *objs = NULL;
Matrix4 mclip, mdpy;
GouraudData *g;
RContext *rc;
List *z = NULL;


int main(int argc, char **argv)
{
  Poly *l, *p, *c = poly_alloc(3);
  Item *i;

  read_scene();
  init_render();

  for (o = objs; o != NULL; o = o->next) {
    for (l = prim_uv_decomp(o->shp); l != NULL; l = l->next) {
      p = poly_transform(prim_polys(o->shp, l), mclip);
      if (!is_backfacing(p, v3_unit(v3_scale(-1, poly_centr(p)))))
        hclip(view->front/view->back, p, z_store, pl_free);
    }
  }
  z = z_sort(z);

  for (i = z->head; i != NULL; i = i->next) { 
    gouraud_shade(c, P(i), N(i), view->center, rc, lights, M(i));
    scan_obj(poly_homoxform(S(i),mdpy), gouraud_paint, gouraud_set(g,c,img));
  }
  img_write(img, "stdout", 0);
  exit(0);
}


void init_render(void)
{
  if (view == NULL)
    view = initview();
  mclip = m4_m4prod(view->C, view->V);
  mdpy = m4_m4prod(view->S, view->P);

  if (img == NULL)
    img = img_init(view->sc_max.x, view->sc_max.y, 0);
  if (lights == NULL)
    LIST_INSERT(lights, light_ambient(.5), Light);
  rc = NEWSTRUCT(RContext);
  g = NEWSTRUCT(GouraudData);
  z = new_list();
}


void z_store(Poly *l)
{
  Zdatum *d = NEWSTRUCT(Zdatum);
  d->zmax = MIN(l->v[0].z, MIN(l->v[1].z, l->v[2].z));
  d->l = l;
  d->o = o;
  append_item(z, new_item(d));
}


Poly *prim_polys(Prim *s, Poly *p)
{
  int i;
  Poly *l = plist_alloc(3, p->n);
  for (i = 0; i < p->n; i++) {
    PL(l)->v[i] = SL(l)->v[i] = prim_point(s, p->v[i].x, p->v[i].y);
    NL(l)->v[i] = prim_normal(s, p->v[i].x, p->v[i].y);
  }
  return l;
}


void pl_free(Poly *l)
{
  free(NL(l)); free(PL(l)); free(SL(l));
}

Macros
#define S(I) (((Zdatum *)(I->d))->l)
#define P(I) (((Zdatum *)(I->d))->l->next)
#define N(I) (((Zdatum *)(I->d))->l->next->next)

#define M(I) (((Zdatum *)(I->d))->o->mat)

#define SL(L) (l)
#define PL(L) (l->next)
#define NL(L) (l->next->next)


Input-Output

Input
scene{
        camera = view {
                from = {0, 0, -2}, at = {0, 0.5, 0}, roll = 0, fov = 90
                },
        light = dist_light {direction = {0, 1, 1} },
        object = primobj{ 
                material = plastic { ka = .2, kd = 0.8, ks = 0.0 },
                shape = sphere { center = {0, 0, 0}}},
};

Output
Image file (stdout)


Extension Options


Copyright © 1997 Luiz Velho