shithub: tinyrend

Download patch

ref: 88b8681339b85e27e3d1d98c867ac3aa0557f780
parent: 32360e2b88f88f643be632941580c90d3e466076
author: rodri <rgl@antares-labs.eu>
date: Sun Jan 14 17:14:04 EST 2024

triangulate quads. replace matrix rotation with quaternions.

generalize texture image decoding.
change lighting.

--- a/fns.h
+++ b/fns.h
@@ -27,4 +27,5 @@
 void swap(int*, int*);
 void memsetd(double*, double, usize);
 Memimage *readtga(char*);
+Memimage *readpng(char*);
 Memimage *rgb(ulong);
--- a/main.c
+++ b/main.c
@@ -22,7 +22,7 @@
 int shownormals;	/* XXX DBG */
 
 char winspec[32];
-Point3 light = {0,-1,1,1};	/* global directional light */
+Point3 light = {0,1,1,1};	/* global directional light */
 Point3 camera = {0,0,3,1};
 Point3 center = {0,0,0,1};
 Point3 up = {0,1,0,0};
@@ -174,12 +174,7 @@
 Point3
 vertshader(VSparams *sp)
 {
-	Matrix3 yrot = {
-		cos(θ+fmod(ω*sp->su->uni_time/1e9, 2*PI)), 0, -sin(θ+fmod(ω*sp->su->uni_time/1e9, 2*PI)), 0,
-		0, 1, 0, 0,
-		sin(θ+fmod(ω*sp->su->uni_time/1e9, 2*PI)), 0, cos(θ+fmod(ω*sp->su->uni_time/1e9, 2*PI)), 0,
-		0, 0, 0, 1,
-	}, S = {
+	Matrix3 S = {
 		scale, 0, 0, 0,
 		0, scale, 0, 0,
 		0, 0, scale, 0,
@@ -188,14 +183,15 @@
 
 	identity3(M);
 	identity3(V);
-	mulm3(yrot, S);
 	mulm3(M, rota);
-	mulm3(M, yrot);
+	mulm3(M, S);
 	mulm3(V, view);
 	mulm3(V, M);
 
-	*sp->n = xform3(*sp->n, M);
+	*sp->n = qrotate(*sp->n, Vec3(0,1,0), θ+fmod(ω*sp->su->uni_time/1e9, 2*PI));
 	sp->su->var_intensity[sp->idx] = fmax(0, dotvec3(*sp->n, light));
+	*sp->n = xform3(*sp->n, M);
+	*sp->p = qrotate(*sp->p, Vec3(0,1,0), θ+fmod(ω*sp->su->uni_time/1e9, 2*PI));
 	*sp->p = xform3(*sp->p, V);
 	return *sp->p;
 }
@@ -407,10 +403,66 @@
 				for(e = o->child; e != nil; e = e->next){
 					idxtab = &e->indextab[OBJVGeometric];
 					/* discard non-triangles */
-					if(e->type != OBJEFace || idxtab->nindex != 3)
+					if(e->type != OBJEFace || (idxtab->nindex != 3 && idxtab->nindex != 4))
 						continue;
-					elems = erealloc(elems, ++nelems*sizeof(*elems));
-					elems[nelems-1] = e;
+					if(idxtab->nindex == 4){	/* triangulate */
+						OBJElem *auxe;
+						OBJIndexArray *auxia;
+
+						auxe = emalloc(sizeof *auxe);
+						auxe->type = OBJEFace;
+						auxia = &auxe->indextab[OBJVGeometric];
+						auxia->nindex = 3;
+						auxia->indices = emalloc(auxia->nindex*sizeof(*auxia->indices));
+						auxia->indices[0] = idxtab->indices[0];
+						auxia->indices[1] = idxtab->indices[1];
+						auxia->indices[2] = idxtab->indices[2];
+						idxtab = &e->indextab[OBJVTexture];
+						auxia = &auxe->indextab[OBJVTexture];
+						auxia->nindex = 3;
+						auxia->indices = emalloc(auxia->nindex*sizeof(*auxia->indices));
+						auxia->indices[0] = idxtab->indices[0];
+						auxia->indices[1] = idxtab->indices[1];
+						auxia->indices[2] = idxtab->indices[2];
+						idxtab = &e->indextab[OBJVNormal];
+						auxia = &auxe->indextab[OBJVNormal];
+						auxia->nindex = 3;
+						auxia->indices = emalloc(auxia->nindex*sizeof(*auxia->indices));
+						auxia->indices[0] = idxtab->indices[0];
+						auxia->indices[1] = idxtab->indices[1];
+						auxia->indices[2] = idxtab->indices[2];
+						elems = erealloc(elems, ++nelems*sizeof(*elems));
+						elems[nelems-1] = auxe;
+
+						idxtab = &e->indextab[OBJVGeometric];
+						auxe = emalloc(sizeof *auxe);
+						auxe->type = OBJEFace;
+						auxia = &auxe->indextab[OBJVGeometric];
+						auxia->nindex = 3;
+						auxia->indices = emalloc(auxia->nindex*sizeof(*auxia->indices));
+						auxia->indices[0] = idxtab->indices[0];
+						auxia->indices[1] = idxtab->indices[2];
+						auxia->indices[2] = idxtab->indices[3];
+						idxtab = &e->indextab[OBJVTexture];
+						auxia = &auxe->indextab[OBJVTexture];
+						auxia->nindex = 3;
+						auxia->indices = emalloc(auxia->nindex*sizeof(*auxia->indices));
+						auxia->indices[0] = idxtab->indices[0];
+						auxia->indices[1] = idxtab->indices[2];
+						auxia->indices[2] = idxtab->indices[3];
+						idxtab = &e->indextab[OBJVNormal];
+						auxia = &auxe->indextab[OBJVNormal];
+						auxia->nindex = 3;
+						auxia->indices = emalloc(auxia->nindex*sizeof(*auxia->indices));
+						auxia->indices[0] = idxtab->indices[0];
+						auxia->indices[1] = idxtab->indices[2];
+						auxia->indices[2] = idxtab->indices[3];
+						elems = erealloc(elems, ++nelems*sizeof(*elems));
+						elems[nelems-1] = auxe;
+					}else{
+						elems = erealloc(elems, ++nelems*sizeof(*elems));
+						elems[nelems-1] = e;
+					}
 				}
 		if(nelems < nprocs){
 			nworkers = nelems;
@@ -760,7 +812,7 @@
 	Keyboardctl *kc;
 	Rune r;
 	Shader *s;
-	char *mdlpath, *texpath;
+	char *mdlpath, *texpath, *p;
 	char *sname;
 	int fbw, fbh;
 
@@ -810,8 +862,17 @@
 
 	if((model = objparse(mdlpath)) == nil)
 		sysfatal("objparse: %r");
-	if(texpath != nil && (modeltex = readtga(texpath)) == nil)
-		sysfatal("readtga: %r");
+	if(texpath != nil){
+		if((p = strrchr(texpath, '\\')) == nil)
+			p = texpath;
+		p = strchr(p, '.');
+		if(p == nil)
+			sysfatal("unknown image file");
+		if(strcmp(++p, "tga") == 0 && (modeltex = readtga(texpath)) == nil)
+			sysfatal("readtga: %r");
+		else if(strcmp(p, "png") == 0 && (modeltex = readpng(texpath)) == nil)
+			sysfatal("readpng: %r");
+	}
 
 	{
 		int i, nv[OBJNVERT], nf;
--- a/util.c
+++ b/util.c
@@ -53,43 +53,66 @@
 		*dp = v;
 }
 
+typedef struct Deco Deco;
+struct Deco
+{
+	int pfd[2];
+	int infd;
+	char *prog;
+};
+
 static void
 decproc(void *arg)
 {
-	int fd, *pfd;
+	char buf[32];
+	Deco *d;
 
-	pfd = arg;
-	fd = pfd[2];
+	d = arg;
 
-	close(pfd[0]);
-	dup(fd, 0);
-	close(fd);
-	dup(pfd[1], 1);
-	close(pfd[1]);
+	close(d->pfd[0]);
+	dup(d->infd, 0);
+	close(d->infd);
+	dup(d->pfd[1], 1);
+	close(d->pfd[1]);
 
-	execl("/bin/tga", "tga", "-9t", nil);
+	snprint(buf, sizeof buf, "/bin/%s", d->prog);
+
+	execl(buf, d->prog, "-9t", nil);
 	threadexitsall("execl: %r");
 }
 
-Memimage *
-readtga(char *path)
+static Memimage *
+genreadimage(char *prog, char *path)
 {
 	Memimage *i;
-	int fd, pfd[3];
+	Deco d;
 
-	if(pipe(pfd) < 0)
+	d.prog = prog;
+
+	if(pipe(d.pfd) < 0)
 		sysfatal("pipe: %r");
-	fd = open(path, OREAD);
-	if(fd < 0)
+	d.infd = open(path, OREAD);
+	if(d.infd < 0)
 		sysfatal("open: %r");
-	pfd[2] = fd;
-	procrfork(decproc, pfd, mainstacksize, RFFDG|RFNAMEG|RFNOTEG);
-	close(pfd[1]);
-	i = readmemimage(pfd[0]);
-	close(pfd[0]);
-	close(fd);
+	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);
 }
 
 Memimage *