summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrodri <rgl@antares-labs.eu>2024-09-01 12:20:21 +0000
committerrodri <rgl@antares-labs.eu>2024-09-01 12:20:21 +0000
commit406aa46cad83725c4560737aa6f2d4a40277a108 (patch)
treed20ed19fd7c4a79f9aed8f89944d8b5d44f7ef8c
parenta28c8cb09e4e1e6357e3b594fad33071e3224efb (diff)
downloadlibgraphics-406aa46cad83725c4560737aa6f2d4a40277a108.tar.gz
libgraphics-406aa46cad83725c4560737aa6f2d4a40277a108.tar.bz2
libgraphics-406aa46cad83725c4560737aa6f2d4a40277a108.zip
unify shaders into a single interface.
-rw-r--r--camera.c6
-rw-r--r--graphics.h30
-rw-r--r--render.c112
-rw-r--r--vertex.c4
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;
}