From e2e203e6fa64a9e57c8d4ba4cea4deec89d8f0c1 Mon Sep 17 00:00:00 2001 From: rodri Date: Tue, 21 May 2024 16:59:33 +0000 Subject: fix line rasterization. --- clip.c | 35 +++++++++++++++++++++++++---------- render.c | 11 +++++------ xform.c | 3 +-- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/clip.c b/clip.c index 18019fc..bcfcabf 100644 --- a/clip.c +++ b/clip.c @@ -53,6 +53,21 @@ cleanpoly(Polygon *p) p->n = 0; } +static void +fprintpoly(int fd, Polygon *p) +{ + int i; + + for(i = 0; i < p->n; i++) + fprint(fd, "%d/%lud p %V\n", i, p->n, p->v[i].p); +} + +static int +eqpt3(Point3 a, Point3 b) +{ + return vec3len(subpt3(a, b)) < 1e-6; +} + /* * references: * - James F. Blinn, Martin E. Newell, “Clipping Using Homogeneous Coordinates”, @@ -76,9 +91,9 @@ clipprimitive(Primitive *p) double d0, d1, perc; Polygon Vin, Vout; Vertex *v0, *v1, v; /* edge verts and new vertex (line-plane intersection) */ - int i, j, nt; + int i, j, np; - nt = 0; + np = 0; memset(&Vin, 0, sizeof Vin); memset(&Vout, 0, sizeof Vout); for(i = 0; i < p[0].type+1; i++) @@ -119,30 +134,30 @@ allin: cleanpoly(&Vout); else switch(p[0].type){ case PLine: - /* TODO fix line clipping (they disappear instead, why?) */ p[0].v[0] = dupvertex(&Vout.v[0]); - p[0].v[1] = dupvertex(&Vout.v[1]); + p[0].v[1] = eqpt3(Vout.v[0].p, Vout.v[1].p)? dupvertex(&Vout.v[2]): dupvertex(&Vout.v[1]); cleanpoly(&Vout); + np = 1; break; case PTriangle: /* triangulate */ - for(i = 0; i < Vout.n-2; i++, nt++){ + for(i = 0; i < Vout.n-2; i++, np++){ /* * when performing fan triangulation, indices 0 and 2 * are referenced on every triangle, so duplicate them * to avoid complications during rasterization. */ - memmove(&p[nt], &p[0], sizeof *p); - p[nt].v[0] = i < Vout.n-2-1? dupvertex(&Vout.v[0]): Vout.v[0]; - p[nt].v[1] = Vout.v[i+1]; - p[nt].v[2] = i < Vout.n-2-1? dupvertex(&Vout.v[i+2]): Vout.v[i+2]; + memmove(&p[np], &p[0], sizeof *p); + p[np].v[0] = i < Vout.n-2-1? dupvertex(&Vout.v[0]): Vout.v[0]; + p[np].v[1] = Vout.v[i+1]; + p[np].v[2] = i < Vout.n-2-1? dupvertex(&Vout.v[i+2]): Vout.v[i+2]; } break; } free(Vout.v); free(Vin.v); - return nt; + return np; } static int diff --git a/render.c b/render.c index f0fffd7..400c268 100644 --- a/render.c +++ b/render.c @@ -119,11 +119,12 @@ rasterize(Rastertask *task) dplen = hypot(dp.x, dp.y); perc = dplen == 0? 0: hypot(Δp.x, Δp.y)/dplen; - /* TODO it seems depth testing messes with the output. find out why */ + if(steep) swapi(&p.x, &p.y); + z = flerp(prim.v[0].p.z, prim.v[1].p.z, perc); depth = fclamp(z, 0, 1); - if(depth <= params->fb->zb[p.x + p.y*Dx(params->fb->r)]) - continue; + if(!ptinrect(p, params->fb->r) || depth <= params->fb->zb[p.x + p.y*Dx(params->fb->r)]) + goto discard; params->fb->zb[p.x + p.y*Dx(params->fb->r)] = depth; /* interpolate z⁻¹ and get actual z */ @@ -134,15 +135,13 @@ rasterize(Rastertask *task) perc *= prim.v[0].p.w * z; lerpvertex(&fsp.v, &prim.v[0], &prim.v[1], perc); - if(steep) swapi(&p.x, &p.y); - fsp.p = p; c = params->fshader(&fsp); memfillcolor(params->frag, col2ul(c)); pixel(params->fb->cb, p, params->frag); delvattrs(&fsp.v); - +discard: if(steep) swapi(&p.x, &p.y); e += Δe; diff --git a/xform.c b/xform.c index aba2089..b6e4397 100644 --- a/xform.c +++ b/xform.c @@ -145,13 +145,12 @@ perspective(Matrix3 m, double fovy, double a, double n, double f) double cotan; cotan = 1/tan(fovy/2); - identity3(m); + memset(m, 0, 4*4*sizeof(double)); m[0][0] = cotan/a; m[1][1] = cotan; m[2][2] = (f+n)/(f-n); m[2][3] = 2*f*n/(f-n); m[3][2] = -1; - m[3][3] = 0; } void -- cgit v1.2.3