ref: 5a97a65584a9bdd97cd3399beff59c5ea5d9d4a9
parent: feecec6c4d7f3798c2298cd6c68b06d77eab719d
author: rodri <rgl@antares-labs.eu>
date: Wed Jan 31 17:34:30 EST 2024
improve coordinate transformations and fix projections. also got rid of Deco. there's no point in having that, just deal with image(6) files.
--- a/camera.c
+++ b/camera.c
@@ -66,15 +66,10 @@
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:
--- a/graphics.h
+++ b/graphics.h
@@ -129,9 +129,8 @@
/* 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 @@
double fmin(double, double);
double fmax(double, double);
Memimage *rgb(ulong);
-Memimage *readtga(char*);
-Memimage *readpng(char*);
/* shadeop */
double step(double, double);
--- 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 @@
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);
--- a/render.c
+++ b/render.c
@@ -80,6 +80,16 @@
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 @@
}
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 @@
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 @@
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 @@
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);
@@ -262,6 +274,13 @@
vsp.v = &t[2];
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){
--- a/util.c
+++ b/util.c
@@ -52,57 +52,3 @@
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);
-}