shithub: tinyrend

Download patch

ref: 69cc4051dc9ebb90a14c22b64ca7fea47215aa70
parent: 44cab0f62cdfaa2f208d07f52bd090d859a73c5a
author: rodri <rgl@antares-labs.eu>
date: Tue Nov 14 06:20:01 EST 2023

show the rendering as it happens, with the option of visualizing the z-buffer.

--- a/main.c
+++ b/main.c
@@ -9,6 +9,8 @@
 #include <geometry.h>
 #include "libobj/obj.h"
 
+#define HZ2MS(hz)	(1000/(hz))
+
 typedef Point Triangle[3];
 typedef struct Sparams Sparams;
 typedef struct SUparams SUparams;
@@ -31,7 +33,7 @@
 };
 
 
-Memimage *fb;
+Memimage *fb, *zfb, *curfb;
 double *zbuf;
 Memimage *red, *green, *blue;
 OBJ *model;
@@ -38,6 +40,7 @@
 Memimage *modeltex;
 Channel *drawc;
 int nprocs;
+int rendering;
 
 char winspec[32];
 
@@ -461,10 +464,8 @@
 
 				bbox = Rect(
 					min(min(st.p0.x, st.p1.x), st.p2.x), min(min(st.p0.y, st.p1.y), st.p2.y),
-					max(max(st.p0.x, st.p1.x), st.p2.x), max(max(st.p0.y, st.p1.y), st.p2.y)
+					max(max(st.p0.x, st.p1.x), st.p2.x)+1, max(max(st.p0.y, st.p1.y), st.p2.y)+1
 				);
-				bbox.max.x++;
-				bbox.max.y++;
 				if(!ptinrect(sp->p, bbox))
 					continue;
 
@@ -473,11 +474,17 @@
 					continue;
 
 				z = t.p0.z*bc.x + t.p1.z*bc.y + t.p2.z*bc.z;
-
 				if(z <= zbuf[sp->p.x+sp->p.y*Dx(fb->r)])
 					continue;
 				zbuf[sp->p.x+sp->p.y*Dx(fb->r)] = z;
 
+				cbuf[0] = 0xFF;
+				cbuf[1] = 0xFF*z;
+				cbuf[2] = 0xFF*z;
+				cbuf[3] = 0xFF*z;
+				memfillcolor(sp->frag, *(ulong*)cbuf);
+				pixel(zfb, sp->p, sp->frag);
+
 				n = normvec3(crossvec3(subpt3(t.p2, t.p0), subpt3(t.p1, t.p0)));
 				intensity = dotvec3(n, light);
 				/* back-face culling */
@@ -520,7 +527,7 @@
 {
 	lockdisplay(display);
 	draw(screen, screen->r, display->black, nil, ZP);
-	loadimage(screen, rectaddpt(fb->r, screen->r.min), byteaddr(fb, fb->r.min), bytesperline(fb->r, fb->depth)*Dy(fb->r));
+	loadimage(screen, rectaddpt(curfb->r, screen->r.min), byteaddr(curfb, curfb->r.min), bytesperline(curfb->r, curfb->depth)*Dy(curfb->r));
 	flushimage(display, 1);
 	unlockdisplay(display);
 }
@@ -536,11 +543,6 @@
 		t1 = nanosec();
 		fprint(2, "shader took %lludns\n", t1-t0);
 	}else{
-//		t0 = nanosec();
-//		shade(fb, circleshader);
-//		t1 = nanosec();
-//		fprint(2, "shader took %lludns\n", t1-t0);
-//
 //		bresenham(fb, Pt(40,40), Pt(300,300), red);
 //		bresenham(fb, Pt(80,80), Pt(100,200), red);
 //		bresenham(fb, Pt(80,80), Pt(200,100), red);
@@ -551,10 +553,6 @@
 //		triangle(fb, Pt(300,120), Pt(200,350), Pt(50, 210), red);
 //		filltriangle(fb, Pt(400,230), Pt(450,180), Pt(150, 320), blue);
 //		triangle(fb, Pt(400,230), Pt(450,180), Pt(150, 320), red);
-//
-//		t0 = nanosec();
-//		shade(fb, triangleshader);
-//		t1 = nanosec();
 
 		t0 = nanosec();
 		shade(fb, sfshader);
@@ -564,11 +562,61 @@
 }
 
 void
-rmb(Mousectl *, Keyboardctl *)
+renderer(void *)
 {
+	threadsetname("renderer");
+
+	render();
+	rendering = 0;
+	nbsendp(drawc, nil);
+	threadexits(nil);
 }
 
 void
+scrsync(void *)
+{
+	Ioproc *io;
+
+	threadsetname("scrsync");
+
+	io = ioproc();
+	while(rendering){
+		nbsendp(drawc, nil);
+		iosleep(io, 2000);
+	}
+	closeioproc(io);
+	threadexits(nil);
+}
+
+static char *
+genrmbmenuitem(int idx)
+{
+	enum {
+		TOGGLEZBUF,
+	};
+
+	if(idx == TOGGLEZBUF)
+		return curfb == zfb? "hide z-buffer": "show z-buffer";
+	return nil;
+}
+
+void
+rmb(Mousectl *mc, Keyboardctl *)
+{
+	enum {
+		TOGGLEZBUF,
+	};
+	static Menu menu = { .gen = genrmbmenuitem };
+
+	switch(menuhit(3, mc, &menu, _screen)){
+	case TOGGLEZBUF:
+		curfb = curfb == fb? zfb: fb;
+		break;
+	}
+	nbsendp(drawc, nil);
+}
+
+void
 lmb(Mousectl *, Keyboardctl *)
 {
 }
@@ -643,6 +691,8 @@
 	fb = eallocmemimage(rectsubpt(screen->r, screen->r.min), screen->chan);
 	zbuf = emalloc(Dx(fb->r)*Dy(fb->r)*sizeof(double));
 	memset(zbuf, ~0, Dx(fb->r)*Dy(fb->r)*sizeof(double));
+	zfb = eallocmemimage(fb->r, fb->chan);
+	curfb = fb;
 	red = rgb(DRed);
 	green = rgb(DGreen);
 	blue = rgb(DBlue);
@@ -652,12 +702,13 @@
 	if(texpath != nil && (modeltex = readtga(texpath)) == nil)
 		sysfatal("readtga: %r");
 
-	render();
-
 	drawc = chancreate(sizeof(void*), 1);
 	display->locking = 1;
 	unlockdisplay(display);
-	nbsend(drawc, nil);
+
+	rendering = 1;
+	proccreate(renderer, nil, mainstacksize);
+	threadcreate(scrsync, nil, mainstacksize);
 
 	for(;;){
 		enum { MOUSE, RESIZE, KEYBOARD, DRAW };