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)
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)