shithub: libobj

Download patch

ref: 6be6c7a12a4dc890ca67750aa8924f430b2922ea
parent: b31457e40a5178320d1aefa588d2d9fc2c5bdfc0
author: rodri <[email protected]>
date: Tue May 28 12:43:38 EDT 2024

add support for normal map loading.

--- a/obj.c
+++ b/obj.c
@@ -172,6 +172,28 @@
 	return genreadimage("jpg", path);
 }
 
+static Memimage *
+readimagefile(char *path)
+{
+	Memimage *i;
+	char *ext;
+
+	i = nil;
+	ext = strrchr(path, '.');
+	if(ext++ != nil){
+		if(strcmp(ext, "tga") == 0)
+			i = readtga(path);
+		else if(strcmp(ext, "png") == 0)
+			i = readpng(path);
+		else if(strcmp(ext, "jpg") == 0)
+			i = readjpg(path);
+		else
+			werrstr("file format not supported");
+	}else
+		werrstr("unknown format");
+	return i;
+}
+
 static void
 addvertva(OBJVertexArray *va, OBJVertex v)
 {
@@ -298,6 +320,8 @@
 static void
 freemt(OBJMaterial *m)
 {
+	freememimage(m->norm);
+	freememimage(m->map_Kd);
 	free(m->name);
 	free(m);
 }
@@ -353,7 +377,7 @@
 	OBJMaterlist *ml;
 	OBJMaterial *m;
 	Biobuf *bin;
-	char *line, *f[10], *p, *ext, buf[128];
+	char *line, *f[10], *p, buf[128];
 	int nf;
 
 	if((p = strrchr(curline.file, '/')) != nil)
@@ -455,25 +479,23 @@
 				mterror("no material found");
 				goto error;
 			}
-			ext = strrchr(f[1], '.');
-			if(ext++ != nil){
-				snprint(buf, sizeof buf, "%.*s/%s", (int)(p-curline.file), curline.file, f[1]);
-				if(strcmp(ext, "tga") == 0)
-					m->map_Kd = readtga(buf);
-				else if(strcmp(ext, "png") == 0)
-					m->map_Kd = readpng(buf);
-				else if(strcmp(ext, "jpg") == 0)
-					m->map_Kd = readjpg(buf);
-				else{
-					mterror("file format not supported");
-					goto error;
-				}
-				if(m->map_Kd == nil){
-					mterror("read%s: %r", ext);
-					goto error;
-				}
+			snprint(buf, sizeof buf, "%.*s/%s", (int)(p-curline.file), curline.file, f[1]);
+			if((m->map_Kd = readimagefile(buf)) == nil){
+				mterror("readimagefile: %r");
+				goto error;
 			}
 		}
+		if(nf == 2 && strcmp(f[0], "norm") == 0){
+			if(m == nil){
+				mterror("no material found");
+				goto error;
+			}
+			snprint(buf, sizeof buf, "%.*s/%s", (int)(p-curline.file), curline.file, f[1]);
+			if((m->norm = readimagefile(buf)) == nil){
+				mterror("readimagefile: %r");
+				goto error;
+			}
+		}
 		if(nf == 2 && strcmp(f[0], "illum") == 0){
 			if(m == nil){
 				mterror("no material found");
@@ -501,7 +523,6 @@
 	for(i = 0; i < nelem(ml->mattab); i++)
 		for(m = ml->mattab[i]; m != nil; m = nm){
 			nm = m->next;
-			freememimage(m->map_Kd);
 			freemt(m);
 		}
 	free(ml->filename);
--- a/obj.h
+++ b/obj.h
@@ -75,6 +75,7 @@
 	double d;		/* dissolution factor */
 	int illum;		/* illumination model */
 	Memimage *map_Kd;	/* color texture file */
+	Memimage *norm;		/* normal texture file */
 	OBJMaterial *next;
 };