shithub: 3dee

Download patch

ref: f8954cf69e723da397c9ddd3cedf6a2a039668eb
parent: 02597db21d25fedde53513967cd979d38acbceec
author: rodri <rgl@antares-labs.eu>
date: Tue Aug 13 15:31:37 EDT 2024

vis: add options for the clr color, blending and z-buf and a-buf.

also stop setting alpha always to 1. it's not correct yet
but it allows for transparent objects to be blended properly.

--- a/dat.h
+++ b/dat.h
@@ -31,5 +31,6 @@
 	Sorient,
 	Spixcol,
 	Snorcol,
+	Sextra,
 	Se
 };
--- a/readme
+++ b/readme
@@ -29,6 +29,13 @@
 	The models supported by the program are OBJ files with material data (MTL
 	files).  You can find examples in the mdl/ folder.
 
+	NOTE:	Now two visibility determination technologies are available: the
+		Z-buffer and the A-buffer. To get the best results out of them the
+		following configurations are recommended:
+
+		- z-buffer: blend OFF | z-buf (depth testing) ON  | a-buf OFF
+		- a-buffer: blend ON  | z-buf (depth testing) OFF | a-buf ON
+
 	- move camera with ↑↓ ((for|back)ward), ←→ (horizontally), PgUp and PgDn (vertically).
 	- rotate camera with AD (yaw), WS (pitch), QE (roll).
 	- change cameras with F[1-4]. cameras 1 and 3 are orthographic, 2 and 4 perspective.
--- a/vis.c
+++ b/vis.c
@@ -92,6 +92,9 @@
 static int inception;
 static int showhud;
 static int shownormals;
+static int blendon;
+static int depthon;
+static int abuffon;
 Color (*tsampler)(Texture*,Point2);
 
 static int
@@ -160,7 +163,7 @@
 Color
 gouraudshader(FSparams *sp)
 {
-	Color tc, c;
+	Color tc;
 
 	if(sp->v.mtl != nil && sp->v.mtl->diffusemap != nil && sp->v.uv.w != 0)
 		tc = sampletexture(sp->v.mtl->diffusemap, sp->v.uv, tsampler);
@@ -169,10 +172,7 @@
 	else
 		tc = Pt3(1,1,1,1);
 
-	c = modulapt3(sp->v.c, tc);
-	c.a = 1;
-
-	return c;
+	return modulapt3(sp->v.c, tc);
 }
 
 Point3
@@ -271,7 +271,6 @@
 
 	c = addpt3(ambient, addpt3(diffuse, specular));
 	c = modulapt3(c, tc);
-	c.a = 1;
 
 	return c;
 }
@@ -320,7 +319,7 @@
 Color
 identshader(FSparams *sp)
 {
-	Color tc, c;
+	Color tc;
 
 	if(sp->v.mtl != nil && sp->v.mtl->diffusemap != nil && sp->v.uv.w != 0)
 		tc = sampletexture(sp->v.mtl->diffusemap, sp->v.uv, tsampler);
@@ -329,10 +328,7 @@
 	else
 		tc = Pt3(1,1,1,1);
 
-	c = modulapt3(sp->v.c, tc);
-	c.a = 1;
-
-	return c;
+	return modulapt3(sp->v.c, tc);
 }
 
 Point3
@@ -489,6 +485,10 @@
 		!maincam->stats.v? 0: 1e9/maincam->stats.v);
 	snprint(stats[Sframes], sizeof(stats[Sframes]), "frame %llud", maincam->stats.nframes);
 	snprint(stats[Sorient], sizeof(stats[Sorient]), "ℍ %V", (Point3)orient);
+	snprint(stats[Sextra], sizeof(stats[Sextra]), "blend %s z-buf %s a-buf %s",
+		maincam->enableblend? "on": "off",
+		maincam->enabledepth? "on": "off",
+		maincam->enableAbuff? "on": "off");
 	for(i = 0; i < Se; i++)
 		stringbg(screen, addpt(screen->r.min, Pt(10,10 + i*font->height)), display->black, ZP, font, stats[i], display->white, ZP);
 }
@@ -625,9 +625,15 @@
 		SP1,
 		SHOWNORMALS,
 		SP2,
+		SETCLRCOL,
+		SP3,
 		CULLFRONT,
 		CULLBACK,
 		CULLNO,
+		SP4,
+		TGLBLEND,
+		TGLDEPTH,
+		TGLABUFF,
 	};
 	static char *items[] = {
 	 [MOVELIGHT]	"move light",
@@ -637,9 +643,15 @@
 			"",
 	 [SHOWNORMALS]	"show normals",
 			"",
+	 [SETCLRCOL]	"set clear color",
+			"",
 	 [CULLFRONT]	"cull front faces",
 	 [CULLBACK]	"cull back faces",
 	 [CULLNO]	"no culling",
+			"",
+	 [TGLBLEND]	"toggle blending",
+	 [TGLDEPTH]	"toggle depth testing",
+	 [TGLABUFF]	"toggle the A-buffer",
 		nil,
 	};
 	static Menu menu = { .item = items };
@@ -668,6 +680,15 @@
 	case SHOWNORMALS:
 		shownormals ^= 1;
 		break;
+	case SETCLRCOL:
+		snprint(buf, sizeof buf, "0x%08lux", maincam->clearcolor);
+		if(enter("clear color", buf, sizeof buf, mctl, kctl, nil) <= 0)
+			break;
+		nf = tokenize(buf, f, 1);
+		if(nf != 1)
+			break;
+		maincam->clearcolor = strtoul(buf, nil, 0);
+		break;
 	case CULLFRONT:
 		maincam->cullmode = CullFront;
 		break;
@@ -677,6 +698,15 @@
 	case CULLNO:
 		maincam->cullmode = CullNone;
 		break;
+	case TGLBLEND:
+		maincam->enableblend ^= 1;
+		break;
+	case TGLDEPTH:
+		maincam->enabledepth ^= 1;
+		break;
+	case TGLABUFF:
+		maincam->enableAbuff ^= 1;
+		break;
 	}
 	unlockdisplay(display);
 	nbsend(drawc, nil);
@@ -829,6 +859,51 @@
 	okdown = kdown;
 }
 
+static void
+mkblendtestscene(void)
+{
+	static Color cols[] = {{1,0,0,0.5}, {0,1,0,0.5}, {0,0,1,0.5}};
+	Entity *ent;
+	Model *mdl;
+	Primitive t[2];
+	Point3 p, v1, v2;
+	int i, j, k;
+
+	memset(t, 0, sizeof t);
+	t[0].type = t[1].type = PTriangle;
+
+	/* build the first face/quad, facing the positive z axis */
+	p = Vec3(-0.5,-0.5,0);
+	v1 = Vec3(1,0,0);
+	v2 = Vec3(0,1,0);
+	t[0].v[0].p = addpt3(center, p);
+	t[0].v[1].p = addpt3(center, addpt3(p, v1));
+	t[0].v[2].p = addpt3(center, addpt3(p, addpt3(v1, v2)));
+	t[0].v[0].n = t[0].v[1].n = t[0].v[2].n = Vec3(0,0,1);
+	t[1].v[0] = t[0].v[0];
+	t[1].v[1] = t[0].v[2];
+	t[1].v[2].p = addpt3(center, addpt3(p, v2));
+	t[1].v[2].n = Vec3(0,0,1);
+
+	for(i = 0; i < nelem(cols); i++){
+		for(j = 0; j < 2; j++)
+			for(k = 0; k < 3; k++){
+				if(i != 0){
+					t[j].v[k].p = qrotate(t[j].v[k].p, Vec3(0,1,0), PI/nelem(cols));
+					t[j].v[k].n = qrotate(t[j].v[k].n, Vec3(0,1,0), PI/nelem(cols));
+				}
+				t[j].v[k].c = cols[i];
+			}
+
+		mdl = newmodel();
+		mdl->prims = erealloc(mdl->prims, (mdl->nprims += 2)*sizeof(*mdl->prims));
+		mdl->prims[mdl->nprims-2] = t[0];
+		mdl->prims[mdl->nprims-1] = t[1];
+		ent = newentity(nil, mdl);
+		scene->addent(scene, ent);
+	}
+}
+
 void
 resize(void)
 {
@@ -874,6 +949,7 @@
 	Entity *subject;
 	char *texpath, *mdlpath, *s;
 	int i, fd, fbw, fbh, scale;
+	int blendtest = 0;
 
 	GEOMfmtinstall();
 	texpath = nil;
@@ -898,7 +974,7 @@
 	default: usage();
 	}ARGEND;
 	if(argc < 1)
-		usage();
+		blendtest++;
 
 	confproc();
 
@@ -906,6 +982,9 @@
 		sysfatal("couldn't find gouraud shader");
 
 	scene = newscene(nil);
+	if(blendtest)
+		mkblendtestscene();
+	else
 	while(argc--){
 		mdlpath = argv[argc];
 		model = readobjmodel(mdlpath);
@@ -936,6 +1015,7 @@
 		sysfatal("initmouse: %r");
 
 	screenb = eallocimage(display, rectsubpt(screen->r, screen->r.min), XRGB32, 0, 0x888888FF);
+fprint(2, "screen %R\n", screenb->r);
 	for(i = 0; i < nelem(cams); i++){
 		if(fbw == 0 || fbh == 0)
 			cams[i] = Cam(screenb->r, rctl,
@@ -953,7 +1033,7 @@
 			cams[i]->view->setscalefilter(cams[i]->view, UFScale3x);
 		cams[i]->view->p.x = (Dx(screenb->r) - cams[i]->view->getwidth(cams[i]->view))/2;
 		cams[i]->view->p.y = (Dy(screenb->r) - cams[i]->view->getheight(cams[i]->view))/2;
-fprint(2, "off %v scalex %g scaley %g\n", cams[i]->view->p, cams[i]->view->bx.x, cams[i]->view->by.y);
+fprint(2, "cam%d off %v scalex %g scaley %g\n", i+1, cams[i]->view->p, cams[i]->view->bx.x, cams[i]->view->by.y);
 	}
 	maincam = cams[3];
 	light.p = Pt3(0,100,100,1);