From c69735e24f7c5926ed63ff8c5292be282aa8b240 Mon Sep 17 00:00:00 2001 From: rodri Date: Fri, 14 Jun 2024 15:01:15 +0000 Subject: fix the barycoords routine to avoid reporting false degenerates. added a normals buffer for debugging. --- fb.c | 14 ++++++++++++++ graphics.h | 2 ++ render.c | 28 +++++++++++++++++++++++++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/fb.c b/fb.c index 5077b7d..e0fa2cd 100644 --- a/fb.c +++ b/fb.c @@ -30,6 +30,17 @@ framebufctl_memdraw(Framebufctl *ctl, Memimage *dst) qunlock(ctl); } +static void +framebufctl_drawnormals(Framebufctl *ctl, Image *dst) +{ + Framebuf *fb; + + qlock(ctl); + fb = ctl->getfb(ctl); + loadimage(dst, rectaddpt(fb->r, dst->r.min), (uchar*)fb->nb, Dx(fb->r)*Dy(fb->r)*4); + qunlock(ctl); +} + static void framebufctl_swap(Framebufctl *ctl) { @@ -45,6 +56,7 @@ framebufctl_reset(Framebufctl *ctl) /* address the back buffer—resetting the front buffer is VERBOTEN */ fb = ctl->getbb(ctl); + memset(fb->nb, 0, Dx(fb->r)*Dy(fb->r)*4); memsetd(fb->zb, Inf(-1), Dx(fb->r)*Dy(fb->r)); memset(fb->cb, 0, Dx(fb->r)*Dy(fb->r)*4); } @@ -71,6 +83,7 @@ mkfb(Rectangle r) fb->cb = emalloc(Dx(r)*Dy(r)*4); fb->zb = emalloc(Dx(r)*Dy(r)*sizeof(*fb->zb)); memsetd(fb->zb, Inf(-1), Dx(r)*Dy(r)); + fb->nb = emalloc(Dx(r)*Dy(r)*4); fb->r = r; return fb; } @@ -94,6 +107,7 @@ mkfbctl(Rectangle r) fc->fb[1] = mkfb(r); fc->draw = framebufctl_draw; fc->memdraw = framebufctl_memdraw; + fc->drawnormals = framebufctl_drawnormals; fc->swap = framebufctl_swap; fc->reset = framebufctl_reset; fc->getfb = framebufctl_getfb; diff --git a/graphics.h b/graphics.h index 17ce25e..7b46ed7 100644 --- a/graphics.h +++ b/graphics.h @@ -227,6 +227,7 @@ struct Framebuf { ulong *cb; /* color buffer */ double *zb; /* z/depth buffer */ + ulong *nb; /* normals buffer (DBG only) */ Rectangle r; }; @@ -238,6 +239,7 @@ struct Framebufctl void (*draw)(Framebufctl*, Image*); void (*memdraw)(Framebufctl*, Memimage*); + void (*drawnormals)(Framebufctl*, Image*); void (*swap)(Framebufctl*); void (*reset)(Framebufctl*); Framebuf *(*getfb)(Framebufctl*); diff --git a/render.c b/render.c index 62d52d2..2f38c32 100644 --- a/render.c +++ b/render.c @@ -46,6 +46,15 @@ pixel(Framebuf *fb, Point p, Color c) dst[Dx(fb->r)*p.y + p.x] = col2ul(c); } +static void +pixeln(Framebuf *fb, Point p, Color c) +{ + ulong *dst; + + dst = fb->nb; + dst[Dx(fb->r)*p.y + p.x] = col2ul(c); +} + static int isvisible(Point3 p) { @@ -67,6 +76,21 @@ isfacingback(Primitive p) return sa <= 0; } +static Point3 +_barycoords(Triangle2 t, Point2 p) +{ + Point2 p0p1 = subpt2(t.p1, t.p0); + Point2 p0p2 = subpt2(t.p2, t.p0); + Point2 pp0 = subpt2(t.p0, p); + + Point3 v = crossvec3(Vec3(p0p2.x, p0p1.x, pp0.x), Vec3(p0p2.y, p0p1.y, pp0.y)); + + /* handle degenerate triangles—i.e. the ones where every point lies on the same line */ + if(fabs(v.z) < 1e-5) + return Pt3(-1,-1,-1,1); + return Pt3(1 - (v.x + v.y)/v.z, v.y/v.z, v.x/v.z, 1); +} + static void rasterize(Rastertask *task) { @@ -178,7 +202,7 @@ discard: for(p.y = bbox.min.y; p.y < bbox.max.y; p.y++) for(p.x = bbox.min.x; p.x < bbox.max.x; p.x++){ - bc = barycoords(t, Pt2(p.x,p.y,1)); + bc = _barycoords(t, Pt2(p.x,p.y,1)); if(bc.x < 0 || bc.y < 0 || bc.z < 0) continue; @@ -198,6 +222,8 @@ discard: fsp.p = p; c = params->fshader(&fsp); pixel(params->fb, p, c); + fsp.v.n.w = 1; + pixeln(params->fb, p, fsp.v.n); delvattrs(&fsp.v); } break; -- cgit v1.2.3