shithub: libgraphics

Download patch

ref: b1335875b19a4db2ae028f8d790784cddcffe8b5
parent: 213c3a4e99c3085ee89fda550897213abbc888ad
author: rodri <rgl@antares-labs.eu>
date: Thu Jun 13 15:06:37 EDT 2024

replace the Memimage color buffer with a ulong* one. some fixes.

--- a/fb.c
+++ b/fb.c
@@ -15,7 +15,7 @@
 
 	qlock(ctl);
 	fb = ctl->getfb(ctl);
-	loadimage(dst, rectaddpt(fb->r, dst->r.min), byteaddr(fb->cb, fb->r.min), bytesperline(fb->r, fb->cb->depth)*Dy(fb->r));
+	loadimage(dst, rectaddpt(fb->r, dst->r.min), (uchar*)fb->cb, Dx(fb->r)*Dy(fb->r)*4);
 	qunlock(ctl);
 }
 
@@ -26,7 +26,7 @@
 
 	qlock(ctl);
 	fb = ctl->getfb(ctl);
-	memimagedraw(dst, dst->r, fb->cb, ZP, nil, ZP, SoverD);
+	loadmemimage(dst, dst->r, (uchar*)fb->cb, Dx(fb->r)*Dy(fb->r)*4);
 	qunlock(ctl);
 }
 
@@ -46,7 +46,7 @@
 	/* address the back buffer—resetting the front buffer is VERBOTEN */
 	fb = ctl->getbb(ctl);
 	memsetd(fb->zb, Inf(-1), Dx(fb->r)*Dy(fb->r));
-	memfillcolor(fb->cb, DTransparent);
+	memset(fb->cb, 0, Dx(fb->r)*Dy(fb->r)*4);
 }
 
 static Framebuf *
@@ -68,7 +68,7 @@
 
 	fb = emalloc(sizeof *fb);
 	memset(fb, 0, sizeof *fb);
-	fb->cb = eallocmemimage(r, RGBA32);
+	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->r = r;
@@ -79,7 +79,7 @@
 rmfb(Framebuf *fb)
 {
 	free(fb->zb);
-	freememimage(fb->cb);
+	free(fb->cb);
 	free(fb);
 }
 
--- a/graphics.h
+++ b/graphics.h
@@ -178,7 +178,6 @@
 struct SUparams
 {
 	Framebuf *fb;
-	Memimage *frag;
 	Renderjob *job;
 	Camera *camera;
 	Entity *entity;
@@ -226,7 +225,7 @@
 
 struct Framebuf
 {
-	Memimage *cb;	/* color buffer */
+	ulong *cb;	/* color buffer */
 	double *zb;	/* z/depth buffer */
 	Rectangle r;
 };
--- a/render.c
+++ b/render.c
@@ -22,13 +22,28 @@
 	return cbuf[3]<<24 | cbuf[2]<<16 | cbuf[1]<<8 | cbuf[0];
 }
 
+static Color
+ul2col(ulong l)
+{
+	Color c;
+
+	c.a = (l     & 0xff)/255.0;
+	c.b = (l>>8  & 0xff)/255.0;
+	c.g = (l>>16 & 0xff)/255.0;
+	c.r = (l>>24 & 0xff)/255.0;
+	return c;
+}
+
 static void
-pixel(Memimage *dst, Point p, Memimage *src)
+pixel(Framebuf *fb, Point p, Color c)
 {
-	if(dst == nil || src == nil)
-		return;
+	Color dc;
+	ulong *dst;
 
-	memimagedraw(dst, rectaddpt(UR, p), src, ZP, nil, ZP, SoverD);
+	dst = fb->cb;
+	dc = ul2col(dst[Dx(fb->r)*p.y + p.x]);
+	c = lerp3(dc, c, c.a);	/* SoverD */
+	dst[Dx(fb->r)*p.y + p.x] = col2ul(c);
 }
 
 static int
@@ -63,7 +78,7 @@
 	Point p, dp, Δp, p0, p1;
 	Point3 bc;
 	Color c;
-	double z, depth, dplen, perc;
+	double z, dplen, perc;
 	int steep = 0, Δe, e, Δy;
 
 	params = task->params;
@@ -76,17 +91,15 @@
 	case PPoint:
 		p = Pt(prim.v[0].p.x, prim.v[0].p.y);
 
-		depth = fclamp(prim.v[0].p.z, 0, 1);
-		if(depth <= params->fb->zb[p.x + p.y*Dx(params->fb->r)])
+		z = fclamp(prim.v[0].p.z, 0, 1);
+		if(z <= params->fb->zb[p.x + p.y*Dx(params->fb->r)])
 			break;
-		params->fb->zb[p.x + p.y*Dx(params->fb->r)] = depth;
+		params->fb->zb[p.x + p.y*Dx(params->fb->r)] = z;
 
 		fsp.v = dupvertex(&prim.v[0]);
 		fsp.p = p;
 		c = params->fshader(&fsp);
-		memfillcolor(params->frag, col2ul(c));
-
-		pixel(params->fb->cb, p, params->frag);
+		pixel(params->fb, p, c);
 		delvattrs(&fsp.v);
 		break;
 	case PLine:
@@ -122,11 +135,10 @@
 			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);
 			/* TODO get rid of the bounds check and make sure the clipping doesn't overflow */
-			if(!ptinrect(p, params->fb->r) || depth <= params->fb->zb[p.x + p.y*Dx(params->fb->r)])
+			if(!ptinrect(p, params->fb->r) || z <= 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;
+			params->fb->zb[p.x + p.y*Dx(params->fb->r)] = z;
 
 			/* interpolate z⁻¹ and get actual z */
 			z = flerp(prim.v[0].p.w, prim.v[1].p.w, perc);
@@ -138,9 +150,7 @@
 
 			fsp.p = p;
 			c = params->fshader(&fsp);
-			memfillcolor(params->frag, col2ul(c));
-
-			pixel(params->fb->cb, p, params->frag);
+			pixel(params->fb, p, c);
 			delvattrs(&fsp.v);
 discard:
 			if(steep) swapi(&p.x, &p.y);
@@ -173,10 +183,9 @@
 					continue;
 
 				z = fberp(prim.v[0].p.z, prim.v[1].p.z, prim.v[2].p.z, bc);
-				depth = fclamp(z, 0, 1);
-				if(depth <= params->fb->zb[p.x + p.y*Dx(params->fb->r)])
+				if(z <= params->fb->zb[p.x + p.y*Dx(params->fb->r)])
 					continue;
-				params->fb->zb[p.x + p.y*Dx(params->fb->r)] = depth;
+				params->fb->zb[p.x + p.y*Dx(params->fb->r)] = z;
 
 				/* interpolate z⁻¹ and get actual z */
 				z = fberp(prim.v[0].p.w, prim.v[1].p.w, prim.v[2].p.w, bc);
@@ -183,17 +192,12 @@
 				z = 1.0/(z < 1e-5? 1e-5: z);
 
 				/* perspective-correct attribute interpolation  */
-				bc.x *= prim.v[0].p.w;
-				bc.y *= prim.v[1].p.w;
-				bc.z *= prim.v[2].p.w;
-				bc = mulpt3(bc, z);
+				bc = modulapt3(bc, Vec3(prim.v[0].p.w*z,prim.v[1].p.w*z,prim.v[2].p.w*z));
 				berpvertex(&fsp.v, &prim.v[0], &prim.v[1], &prim.v[2], bc);
 
 				fsp.p = p;
 				c = params->fshader(&fsp);
-				memfillcolor(params->frag, col2ul(c));
-
-				pixel(params->fb->cb, p, params->frag);
+				pixel(params->fb, p, c);
 				delvattrs(&fsp.v);
 			}
 		break;
@@ -206,12 +210,10 @@
 	Rasterparam *rp;
 	Rastertask *task;
 	SUparams *params;
-	Memimage *frag;
 	uvlong t0;
 	int i;
 
 	rp = arg;
-	frag = rgb(DBlack);
 
 	threadsetname("rasterizer %d", rp->id);
 
@@ -232,7 +234,6 @@
 		if(params->job->times.Rn.t0 == 0)
 			params->job->times.Rn.t0 = t0;
 
-		params->frag = frag;
 		rasterize(task);
 
 		for(i = 0; i < task->p.type+1; i++)
--- a/vertex.c
+++ b/vertex.c
@@ -79,6 +79,7 @@
 	Vertexattr va;
 	int i;
 
+	v->p = berp3(v0->p, v1->p, v2->p, bc);
 	v->n = berp3(v0->n, v1->n, v2->n, bc);
 	v->c = berp3(v0->c, v1->c, v2->c, bc);
 	v->uv = berp2(v0->uv, v1->uv, v2->uv, bc);
--- a/xform.c
+++ b/xform.c
@@ -64,7 +64,7 @@
 Point3
 clip2ndc(Point3 p)
 {
-	p.w = p.w == 0? 1: 1.0/p.w;
+	p.w = p.w == 0? 0: 1.0/p.w;
 	p.x *= p.w;
 	p.y *= p.w;
 	p.z *= p.w;