summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrodri <rgl@antares-labs.eu>2024-06-04 18:11:11 +0000
committerrodri <rgl@antares-labs.eu>2024-06-04 18:11:11 +0000
commitdc597a2c65278119b7d11f83218b860c0c5da051 (patch)
treea6baf268c4dc7f8ed15465e66268986e03415db7
parent5fa75a6d4b03c676112ca04cf5ff3f3ccd2f0fee (diff)
downloadlibgraphics-dc597a2c65278119b7d11f83218b860c0c5da051.tar.gz
libgraphics-dc597a2c65278119b7d11f83218b860c0c5da051.tar.bz2
libgraphics-dc597a2c65278119b7d11f83218b860c0c5da051.zip
add a tangent parameter for normal mapping, and a world2model xform.
-rw-r--r--graphics.h4
-rw-r--r--render.c6
-rw-r--r--scene.c24
-rw-r--r--xform.c6
4 files changed, 31 insertions, 9 deletions
diff --git a/graphics.h b/graphics.h
index 7eded0e..7998d01 100644
--- a/graphics.h
+++ b/graphics.h
@@ -87,6 +87,7 @@ struct Vertex
Color c; /* shading color */
Point2 uv; /* texture coordinate */
Material *mtl;
+ Point3 tangent;
/* TODO it'd be neat to use a dynamic hash table instead */
Vertexattr *attrs; /* attributes (aka varyings) */
@@ -116,6 +117,7 @@ struct Primitive
int type;
Vertex v[3];
Material *mtl;
+ Point3 tangent; /* used for normal mapping */
};
struct Model
@@ -123,7 +125,6 @@ struct Model
Primitive *prims;
ulong nprims;
Memimage *tex; /* texture map */
- Memimage *nor; /* normals map */
Material *materials;
ulong nmaterials;
};
@@ -290,6 +291,7 @@ Point3 ndc2vcs(Camera*, Point3);
Point3 viewport2vcs(Camera*, Point3);
Point3 vcs2world(Camera*, Point3);
Point3 viewport2world(Camera*, Point3);
+Point3 world2model(Entity*, Point3);
void perspective(Matrix3, double, double, double, double);
void orthographic(Matrix3, double, double, double, double, double, double);
diff --git a/render.c b/render.c
index 6879861..4a0862a 100644
--- a/render.c
+++ b/render.c
@@ -351,10 +351,6 @@ tilerdurden(void *arg)
p[np].v[0].p = clip2ndc(p[np].v[0].p);
p[np].v[1].p = clip2ndc(p[np].v[1].p);
- /* culling */
-// if(isfacingback(p[np]))
-// goto skiptri2;
-
p[np].v[0].p = ndc2viewport(params->fb, p[np].v[0].p);
p[np].v[1].p = ndc2viewport(params->fb, p[np].v[1].p);
@@ -375,7 +371,6 @@ tilerdurden(void *arg)
task->p.v[1] = dupvertex(&p[np].v[1]);
sendp(taskchans[i], task);
}
-//skiptri2:
delvattrs(&p[np].v[0]);
delvattrs(&p[np].v[1]);
}
@@ -386,6 +381,7 @@ tilerdurden(void *arg)
p[0].v[i].mtl = p->mtl;
p[0].v[i].attrs = nil;
p[0].v[i].nattrs = 0;
+ p[0].v[i].tangent = p->tangent;
vsp.v = &p[0].v[i];
vsp.idx = i;
diff --git a/scene.c b/scene.c
index c9c8d5c..7cec60d 100644
--- a/scene.c
+++ b/scene.c
@@ -277,6 +277,23 @@ loadobjmodel(Model *m, OBJ *obj)
p->v[idx].uv = Pt2(v->u, v->v, 1);
}
}
+ if(p->v[0].uv.w != 0){
+ Point3 e0, e1;
+ Point2 Δuv0, Δuv1;
+ double det;
+
+ e0 = subpt3(p->v[1].p, p->v[0].p);
+ e1 = subpt3(p->v[2].p, p->v[0].p);
+ Δuv0 = subpt2(p->v[1].uv, p->v[0].uv);
+ Δuv1 = subpt2(p->v[2].uv, p->v[0].uv);
+
+ det = Δuv0.x * Δuv1.y - Δuv1.x * Δuv0.y;
+ det = det == 0? 0: 1.0/det;
+ p->tangent.x = det*(Δuv1.y * e0.x - Δuv0.y * e1.x);
+ p->tangent.y = det*(Δuv1.y * e0.y - Δuv0.y * e1.y);
+ p->tangent.z = det*(Δuv1.y * e0.z - Δuv0.y * e1.z);
+ p->tangent = normvec3(p->tangent);
+ }
if(neednormal){
/* TODO build a list of per-vertex normals earlier */
n = normvec3(crossvec3(subpt3(p->v[1].p, p->v[0].p), subpt3(p->v[2].p, p->v[0].p)));
@@ -316,11 +333,12 @@ delmodel(Model *m)
return;
if(m->tex != nil)
freememimage(m->tex);
- if(m->nor != nil)
- freememimage(m->nor);
if(m->nmaterials > 0){
- while(m->nmaterials--)
+ while(m->nmaterials--){
+ freememimage(m->materials[m->nmaterials].diffusemap);
+ freememimage(m->materials[m->nmaterials].normalmap);
free(m->materials[m->nmaterials].name);
+ }
free(m->materials);
}
if(m->nprims > 0)
diff --git a/xform.c b/xform.c
index b6e4397..4351113 100644
--- a/xform.c
+++ b/xform.c
@@ -139,6 +139,12 @@ viewport2world(Camera *c, Point3 p)
return vcs2world(c, viewport2vcs(c, p));
}
+Point3
+world2model(Entity *e, Point3 p)
+{
+ return rframexform3(p, *e);
+}
+
void
perspective(Matrix3 m, double fovy, double a, double n, double f)
{