shithub: libgraphics

Download patch

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(&params->fb->zbuflk);
 			if(depth <= params->fb->zbuf[p.x + p.y*Dx(params->fb->r)]){
 				unlock(&params->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);
-}