shithub: libgraphics

Download patch

ref: 406aa46cad83725c4560737aa6f2d4a40277a108
parent: a28c8cb09e4e1e6357e3b594fad33071e3224efb
author: rodri <rgl@antares-labs.eu>
date: Sun Sep 1 08:20:21 EDT 2024

unify shaders into a single interface.

--- 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 @@
 }
 
 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;
 }
--- a/graphics.h
+++ b/graphics.h
@@ -53,9 +53,7 @@
 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 @@
 	Entity *(*getent)(Scene*, char*);
 };
 
-/* shader params */
-struct VSparams
+struct Shaderparams
 {
 	SUparams *su;
 	Vertex *v;
-	uint idx;
-};
+	Point p;	/* fragment position (fshader-only) */
+	uint idx;	/* vertex index (vshader-only) */
 
-struct FSparams
-{
-	SUparams *su;
-	Point p;
-	Vertex v;		/* only for the attributes (varyings) */
-
-	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 @@
 
 	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
--- 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 @@
 	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 @@
 	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 @@
 
 	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,7 +227,7 @@
 			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)
@@ -208,7 +234,7 @@
 			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 @@
 
 			/* 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 @@
 				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 @@
 				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 @@
 					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 @@
 }
 
 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,8 +413,14 @@
 	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();
 		if(params->job->times.Tn.t0 == 0)
@@ -595,7 +627,7 @@
 		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);
--- a/vertex.c
+++ b/vertex.c
@@ -13,6 +13,8 @@
 {
 	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 @@
 	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;
 }