From dc597a2c65278119b7d11f83218b860c0c5da051 Mon Sep 17 00:00:00 2001 From: rodri Date: Tue, 4 Jun 2024 18:11:11 +0000 Subject: add a tangent parameter for normal mapping, and a world2model xform. --- graphics.h | 4 +++- render.c | 6 +----- scene.c | 24 +++++++++++++++++++++--- xform.c | 6 ++++++ 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) { -- cgit v1.2.3