From 5a97a65584a9bdd97cd3399beff59c5ea5d9d4a9 Mon Sep 17 00:00:00 2001 From: rodri Date: Wed, 31 Jan 2024 22:34:30 +0000 Subject: improve coordinate transformations and fix projections. also got rid of Deco. there's no point in having that, just deal with image(6) files. --- camera.c | 5 ----- graphics.h | 7 ++----- internal.h | 10 +--------- render.c | 59 +++++++++++++++++++++++++++++++++++++++-------------------- util.c | 54 ------------------------------------------------------ 5 files changed, 42 insertions(+), 93 deletions(-) diff --git a/camera.c b/camera.c index d54f0dd..699b59c 100644 --- a/camera.c +++ b/camera.c @@ -66,15 +66,10 @@ reloadcamera(Camera *c) verifycfg(c); switch(c->projtype){ case ORTHOGRAPHIC: - /* r = Dx(c->vp->fbctl->fb[0]->r)/2; t = Dy(c->vp->fbctl->fb[0]->r)/2; l = -r; b = -t; - */ - l = t = 0; - r = Dx(c->vp->fbctl->fb[0]->r); - b = Dy(c->vp->fbctl->fb[0]->r); orthographic(c->proj, l, r, b, t, c->clip.n, c->clip.f); break; case PERSPECTIVE: diff --git a/graphics.h b/graphics.h index 55c378c..7eb284d 100644 --- a/graphics.h +++ b/graphics.h @@ -129,9 +129,8 @@ void rmviewport(Viewport*); /* render */ Point3 world2vcs(Camera*, Point3); -Point3 vcs2ndc(Camera*, Point3); -Point3 world2ndc(Camera*, Point3); -Point3 ndc2viewport(Camera*, Point3); +Point3 vcs2clip(Camera*, Point3); +Point3 world2clip(Camera*, Point3); void perspective(Matrix3, double, double, double, double); void orthographic(Matrix3, double, double, double, double, double, double); @@ -139,8 +138,6 @@ void orthographic(Matrix3, double, double, double, double, double, double); double fmin(double, double); double fmax(double, double); Memimage *rgb(ulong); -Memimage *readtga(char*); -Memimage *readpng(char*); /* shadeop */ double step(double, double); diff --git a/internal.h b/internal.h index a6b7a96..6abb115 100644 --- a/internal.h +++ b/internal.h @@ -1,11 +1,3 @@ -typedef struct Deco Deco; -struct Deco -{ - int pfd[2]; - int infd; - char *prog; -}; - /* alloc */ void *emalloc(ulong); void *erealloc(void*, ulong); @@ -18,7 +10,7 @@ Framebufctl *mkfbctl(Rectangle); void rmfbctl(Framebufctl*); /* render */ -void shade(Framebuf *fb, OBJ *model, Memimage *modeltex, Shader *s, ulong nprocs); +void shade(Framebuf*, OBJ*, Memimage*, Shader*, ulong); /* util */ int min(int, int); diff --git a/render.c b/render.c index b28c3ff..541cb6e 100644 --- a/render.c +++ b/render.c @@ -80,6 +80,16 @@ triangulate(OBJElem **newe, OBJElem *e) return 2; } +static int +isclipping(Point3 p) +{ + if(p.x < -p.w || p.x > p.w || + p.y < -p.w || p.y > p.w || + p.z < -p.w || p.z > p.w) + return 1; + return 0; +} + Point3 world2vcs(Camera *c, Point3 p) { @@ -87,29 +97,32 @@ world2vcs(Camera *c, Point3 p) } Point3 -vcs2ndc(Camera *c, Point3 p) +vcs2clip(Camera *c, Point3 p) { return xform3(p, c->proj); } Point3 -world2ndc(Camera *c, Point3 p) +world2clip(Camera *c, Point3 p) { - return vcs2ndc(c, world2vcs(c, p)); + return vcs2clip(c, world2vcs(c, p)); } -Point3 -ndc2viewport(Camera *c, Point3 p) +static Point3 +clip2ndc(Point3 p) { - Matrix3 view; + return divpt3(p, p.w); +} - identity3(view); - view[0][3] = c->vp->fbctl->fb[0]->r.max.x/2.0; - view[1][3] = c->vp->fbctl->fb[0]->r.max.y/2.0; - view[2][3] = 1.0/2.0; - view[0][0] = Dx(c->vp->fbctl->fb[0]->r)/2.0; - view[1][1] = -Dy(c->vp->fbctl->fb[0]->r)/2.0; - view[2][2] = 1.0/2.0; +static Point3 +ndc2viewport(Framebuf *fb, Point3 p) +{ + Matrix3 view = { + Dx(fb->r)/2.0, 0, 0, Dx(fb->r)/2.0, + 0, -Dy(fb->r)/2.0, 0, Dy(fb->r)/2.0, + 0, 0, 1.0/2.0, 1.0/2.0, + 0, 0, 0, 1, + }; return xform3(p, view); } @@ -123,7 +136,7 @@ perspective(Matrix3 m, double fov, double a, double n, double f) identity3(m); m[0][0] = cotan/a; m[1][1] = cotan; - m[2][2] = (f+n)/(f-n); + m[2][2] = (f+n)/(f-n); m[2][3] = -2*f*n/(f-n); m[3][2] = -1; } @@ -148,12 +161,12 @@ rasterize(SUparams *params, Triangle t, Memimage *frag) Rectangle bbox; Point p, tp; Point3 bc; - double z, w, depth; + double z, depth; uchar cbuf[4]; - t₂.p0 = Pt2(t[0].p.x/t[0].p.w, t[0].p.y/t[0].p.w, 1); - t₂.p1 = Pt2(t[1].p.x/t[1].p.w, t[1].p.y/t[1].p.w, 1); - t₂.p2 = Pt2(t[2].p.x/t[2].p.w, t[2].p.y/t[2].p.w, 1); + t₂.p0 = Pt2(t[0].p.x, t[0].p.y, 1); + t₂.p1 = Pt2(t[1].p.x, t[1].p.y, 1); + t₂.p2 = Pt2(t[2].p.x, t[2].p.y, 1); /* find the triangle's bbox and clip it against the fb */ bbox = Rect( min(min(t₂.p0.x, t₂.p1.x), t₂.p2.x), min(min(t₂.p0.y, t₂.p1.y), t₂.p2.y), @@ -175,8 +188,7 @@ rasterize(SUparams *params, Triangle t, Memimage *frag) continue; z = t[0].p.z*bc.x + t[1].p.z*bc.y + t[2].p.z*bc.z; - w = t[0].p.w*bc.x + t[1].p.w*bc.y + t[2].p.w*bc.z; - depth = fclamp(z/w, 0, 1); + depth = fclamp(z, 0, 1); lock(¶ms->fb->zbuflk); if(depth <= params->fb->zbuf[p.x + p.y*Dx(params->fb->r)]){ unlock(¶ms->fb->zbuflk); @@ -263,6 +275,13 @@ shaderunit(void *arg) vsp.idx = 2; t[2].p = params->vshader(&vsp); +// if(isclipping(t[0].p) || isclipping(t[1].p) || isclipping(t[2].p)) +// continue; /* TODO clip the primitive */ + + t[0].p = ndc2viewport(params->fb, clip2ndc(t[0].p)); + t[1].p = ndc2viewport(params->fb, clip2ndc(t[1].p)); + t[2].p = ndc2viewport(params->fb, clip2ndc(t[2].p)); + idxtab = &(*ep)->indextab[OBJVTexture]; if(params->modeltex != nil && idxtab->nindex == 3){ t[0].uv = Pt2(tverts[idxtab->indices[0]].u, tverts[idxtab->indices[0]].v, 1); diff --git a/util.c b/util.c index 1ff251f..2a4c7d6 100644 --- a/util.c +++ b/util.c @@ -52,57 +52,3 @@ rgb(ulong c) memfillcolor(i, c); return i; } - -static void -decproc(void *arg) -{ - char buf[32]; - Deco *d; - - d = arg; - - close(d->pfd[0]); - dup(d->infd, 0); - close(d->infd); - dup(d->pfd[1], 1); - close(d->pfd[1]); - - snprint(buf, sizeof buf, "/bin/%s", d->prog); - - execl(buf, d->prog, "-9t", nil); - threadexitsall("execl: %r"); -} - -static Memimage * -genreadimage(char *prog, char *path) -{ - Memimage *i; - Deco d; - - d.prog = prog; - - if(pipe(d.pfd) < 0) - sysfatal("pipe: %r"); - d.infd = open(path, OREAD); - if(d.infd < 0) - sysfatal("open: %r"); - procrfork(decproc, &d, mainstacksize, RFFDG|RFNAMEG|RFNOTEG); - close(d.pfd[1]); - i = readmemimage(d.pfd[0]); - close(d.pfd[0]); - close(d.infd); - - return i; -} - -Memimage * -readtga(char *path) -{ - return genreadimage("tga", path); -} - -Memimage * -readpng(char *path) -{ - return genreadimage("png", path); -} -- cgit v1.2.3