From 406aa46cad83725c4560737aa6f2d4a40277a108 Mon Sep 17 00:00:00 2001 From: rodri Date: Sun, 1 Sep 2024 12:20:21 +0000 Subject: unify shaders into a single interface. --- camera.c | 6 ++-- graphics.h | 30 +++++++---------- render.c | 112 +++++++++++++++++++++++++++++++++++++++---------------------- vertex.c | 4 ++- 4 files changed, 90 insertions(+), 62 deletions(-) diff --git a/camera.c b/camera.c index 9734af1..0562769 100644 --- a/camera.c +++ b/camera.c @@ -13,7 +13,7 @@ * - https://learnopengl.com/Advanced-OpenGL/Cubemaps */ static Point3 -skyboxvs(VSparams *sp) +skyboxvs(Shaderparams *sp) { Point3 p; @@ -28,12 +28,12 @@ skyboxvs(VSparams *sp) } static Color -skyboxfs(FSparams *sp) +skyboxfs(Shaderparams *sp) { Vertexattr *va; Color c; - va = getvattr(&sp->v, "dir"); + va = getvattr(sp->v, "dir"); c = samplecubemap(sp->su->camera->scene->skybox, va->p, neartexsampler); return c; } diff --git a/graphics.h b/graphics.h index 106f467..a361491 100644 --- a/graphics.h +++ b/graphics.h @@ -53,9 +53,7 @@ typedef struct Primitive Primitive; typedef struct Model Model; typedef struct Entity Entity; typedef struct Scene Scene; -typedef struct VSparams VSparams; -typedef struct FSoutput FSoutput; -typedef struct FSparams FSparams; +typedef struct Shaderparams Shaderparams; typedef struct SUparams SUparams; typedef struct Shadertab Shadertab; typedef struct Renderer Renderer; @@ -198,21 +196,17 @@ struct Scene Entity *(*getent)(Scene*, char*); }; -/* shader params */ -struct VSparams +struct Shaderparams { SUparams *su; Vertex *v; - uint idx; -}; - -struct FSparams -{ - SUparams *su; - Point p; - Vertex v; /* only for the attributes (varyings) */ + Point p; /* fragment position (fshader-only) */ + uint idx; /* vertex index (vshader-only) */ - void (*toraster)(FSparams*, char*, void*); + Vertexattr *(*getuniform)(Shaderparams*, char*); + Vertexattr *(*getattr)(Shaderparams*, char*); + void (*setattr)(Shaderparams*, char*, int, void*); + void (*toraster)(Shaderparams*, char*, void*); }; /* shader unit params */ @@ -226,15 +220,15 @@ struct SUparams uvlong uni_time; - Point3 (*vshader)(VSparams*); - Color (*fshader)(FSparams*); + Point3 (*vshader)(Shaderparams*); + Color (*fshader)(Shaderparams*); }; struct Shadertab { char *name; - Point3 (*vshader)(VSparams*); /* vertex shader */ - Color (*fshader)(FSparams*); /* fragment shader */ + Point3 (*vshader)(Shaderparams*); /* vertex shader */ + Color (*fshader)(Shaderparams*); /* fragment shader */ }; struct Renderer diff --git a/render.c b/render.c index 1a78f08..9e06e67 100644 --- a/render.c +++ b/render.c @@ -10,6 +10,54 @@ Rectangle UR = {0,0,1,1}; +static ulong col2ul(Color); + +static Vertexattr * +sparams_getuniform(Shaderparams *sp, char *id) +{ + USED(sp, id); + return nil; +} + +static Vertexattr * +sparams_getattr(Shaderparams *sp, char *id) +{ + return getvattr(sp->v, id); +} + +static void +sparams_setattr(Shaderparams *sp, char *id, int type, void *val) +{ + addvattr(sp->v, id, type, val); +} + +static void +sparams_toraster(Shaderparams *sp, char *rname, void *v) +{ + Framebuf *fb; + Raster *r; + ulong c; + + /* keep the user away from the color buffer */ + if(rname == nil || v == nil) + return; + + fb = sp->su->fb; + r = fb->fetchraster(fb, rname); + if(r == nil) + return; + + switch(r->chan){ + case COLOR32: + c = col2ul(*(Color*)v); + rasterput(r, sp->p, &c); + break; + case FLOAT32: + rasterput(r, sp->p, v); + break; + } +} + static ulong col2ul(Color c) { @@ -49,33 +97,6 @@ pixel(Raster *fb, Point p, Color c, int blend) putpixel(fb, p, col2ul(linear2srgb(c))); } -static void -fsparams_toraster(FSparams *sp, char *rname, void *v) -{ - Framebuf *fb; - Raster *r; - ulong c; - - /* keep the user away from the color buffer */ - if(rname == nil || v == nil) - return; - - fb = sp->su->fb; - r = fb->fetchraster(fb, rname); - if(r == nil) - return; - - switch(r->chan){ - case COLOR32: - c = col2ul(*(Color*)v); - rasterput(r, sp->p, &c); - break; - case FLOAT32: - rasterput(r, sp->p, v); - break; - } -} - static int isvisible(Point3 p) { @@ -171,7 +192,8 @@ rasterize(Rastertask *task) SUparams *params; Raster *cr, *zr; Primitive prim; - FSparams fsp; + Shaderparams fsp; + Vertex v; Triangle2 t; Rectangle bbox; Point p, dp, Δp, p0, p1; @@ -183,9 +205,13 @@ rasterize(Rastertask *task) params = task->params; prim = task->p; + memset(&fsp, 0, sizeof fsp); fsp.su = params; - memset(&fsp.v, 0, sizeof fsp.v); - fsp.toraster = fsparams_toraster; + fsp.v = &v; + fsp.getuniform = sparams_getuniform; + fsp.getattr = sparams_getattr; + fsp.setattr = nil; + fsp.toraster = sparams_toraster; cr = params->fb->rasters; zr = cr->next; @@ -201,14 +227,14 @@ rasterize(Rastertask *task) putdepth(zr, p, z); } - fsp.v = dupvertex(&prim.v[0]); + *fsp.v = dupvertex(&prim.v[0]); fsp.p = p; c = params->fshader(&fsp); if(params->camera->enableAbuff) pushtoAbuf(params->fb, p, c, z); else pixel(cr, p, c, params->camera->enableblend); - delvattrs(&fsp.v); + delvattrs(fsp.v); break; case PLine: p0 = Pt(prim.v[0].p.x, prim.v[0].p.y); @@ -256,7 +282,7 @@ rasterize(Rastertask *task) /* perspective-correct attribute interpolation */ perc *= prim.v[0].p.w * pcz; - lerpvertex(&fsp.v, &prim.v[0], &prim.v[1], perc); + lerpvertex(fsp.v, &prim.v[0], &prim.v[1], perc); fsp.p = p; c = params->fshader(&fsp); @@ -264,7 +290,7 @@ rasterize(Rastertask *task) pushtoAbuf(params->fb, p, c, z); else pixel(cr, p, c, params->camera->enableblend); - delvattrs(&fsp.v); + delvattrs(fsp.v); discard: if(steep) SWAP(int, &p.x, &p.y); @@ -310,7 +336,7 @@ discard: bc = modulapt3(bc, Vec3(prim.v[0].p.w*pcz, prim.v[1].p.w*pcz, prim.v[2].p.w*pcz)); - berpvertex(&fsp.v, &prim.v[0], &prim.v[1], &prim.v[2], bc); + berpvertex(fsp.v, &prim.v[0], &prim.v[1], &prim.v[2], bc); fsp.p = p; c = params->fshader(&fsp); @@ -318,7 +344,7 @@ discard: pushtoAbuf(params->fb, p, c, z); else pixel(cr, p, c, params->camera->enableblend); - delvattrs(&fsp.v); + delvattrs(fsp.v); } break; default: sysfatal("alien primitive detected"); @@ -368,12 +394,12 @@ rasterizer(void *arg) } static void -tilerdurden(void *arg) +tiler(void *arg) { Tilerparam *tp; SUparams *params, *newparams; Rastertask *task; - VSparams vsp; + Shaderparams vsp; Primitive *ep, *cp, *p; /* primitives to raster */ Rectangle *wr, bbox; Channel **taskchans; @@ -387,7 +413,13 @@ tilerdurden(void *arg) nproc = tp->nproc; wr = emalloc(nproc*sizeof(Rectangle)); - threadsetname("tilerdurden %d", tp->id); + memset(&vsp, 0, sizeof vsp); + vsp.getuniform = sparams_getuniform; + vsp.getattr = sparams_getattr; + vsp.setattr = sparams_setattr; + vsp.toraster = nil; + + threadsetname("tiler %d", tp->id); while((params = recvp(tp->paramsc)) != nil){ t0 = nanosec(); @@ -595,7 +627,7 @@ entityproc(void *arg) tp->paramsc = paramsout[i]; tp->taskchans = taskchans; tp->nproc = nproc; - proccreate(tilerdurden, tp, mainstacksize); + proccreate(tiler, tp, mainstacksize); } for(i = 0; i < nproc; i++){ rp = emalloc(sizeof *rp); diff --git a/vertex.c b/vertex.c index 970bbbc..5701c23 100644 --- a/vertex.c +++ b/vertex.c @@ -13,6 +13,8 @@ _addvattr(Vertex *v, Vertexattr *va) { int i; + assert(va->id != nil); + for(i = 0; i < v->nattrs; i++) if(strcmp(v->attrs[i].id, va->id) == 0){ v->attrs[i] = *va; @@ -118,7 +120,7 @@ getvattr(Vertex *v, char *id) int i; for(i = 0; i < v->nattrs; i++) - if(strcmp(v->attrs[i].id, id) == 0) + if(id != nil && strcmp(v->attrs[i].id, id) == 0) return &v->attrs[i]; return nil; } -- cgit v1.2.3