ref: f8954cf69e723da397c9ddd3cedf6a2a039668eb
parent: 02597db21d25fedde53513967cd979d38acbceec
author: rodri <rgl@antares-labs.eu>
date: Tue Aug 13 15:31:37 EDT 2024
vis: add options for the clr color, blending and z-buf and a-buf. also stop setting alpha always to 1. it's not correct yet but it allows for transparent objects to be blended properly.
--- a/dat.h
+++ b/dat.h
@@ -31,5 +31,6 @@
Sorient,
Spixcol,
Snorcol,
+ Sextra,
Se
};
--- a/readme
+++ b/readme
@@ -29,6 +29,13 @@
The models supported by the program are OBJ files with material data (MTL
files). You can find examples in the mdl/ folder.
+ NOTE: Now two visibility determination technologies are available: the
+ Z-buffer and the A-buffer. To get the best results out of them the
+ following configurations are recommended:
+
+ - z-buffer: blend OFF | z-buf (depth testing) ON | a-buf OFF
+ - a-buffer: blend ON | z-buf (depth testing) OFF | a-buf ON
+
- move camera with ↑↓ ((for|back)ward), ←→ (horizontally), PgUp and PgDn (vertically).
- rotate camera with AD (yaw), WS (pitch), QE (roll).
- change cameras with F[1-4]. cameras 1 and 3 are orthographic, 2 and 4 perspective.
--- a/vis.c
+++ b/vis.c
@@ -92,6 +92,9 @@
static int inception;
static int showhud;
static int shownormals;
+static int blendon;
+static int depthon;
+static int abuffon;
Color (*tsampler)(Texture*,Point2);
static int
@@ -160,7 +163,7 @@
Color
gouraudshader(FSparams *sp)
{
- Color tc, c;
+ Color tc;
if(sp->v.mtl != nil && sp->v.mtl->diffusemap != nil && sp->v.uv.w != 0)
tc = sampletexture(sp->v.mtl->diffusemap, sp->v.uv, tsampler);
@@ -169,10 +172,7 @@
else
tc = Pt3(1,1,1,1);
- c = modulapt3(sp->v.c, tc);
- c.a = 1;
-
- return c;
+ return modulapt3(sp->v.c, tc);
}
Point3
@@ -271,7 +271,6 @@
c = addpt3(ambient, addpt3(diffuse, specular));
c = modulapt3(c, tc);
- c.a = 1;
return c;
}
@@ -320,7 +319,7 @@
Color
identshader(FSparams *sp)
{
- Color tc, c;
+ Color tc;
if(sp->v.mtl != nil && sp->v.mtl->diffusemap != nil && sp->v.uv.w != 0)
tc = sampletexture(sp->v.mtl->diffusemap, sp->v.uv, tsampler);
@@ -329,10 +328,7 @@
else
tc = Pt3(1,1,1,1);
- c = modulapt3(sp->v.c, tc);
- c.a = 1;
-
- return c;
+ return modulapt3(sp->v.c, tc);
}
Point3
@@ -489,6 +485,10 @@
!maincam->stats.v? 0: 1e9/maincam->stats.v);
snprint(stats[Sframes], sizeof(stats[Sframes]), "frame %llud", maincam->stats.nframes);
snprint(stats[Sorient], sizeof(stats[Sorient]), "ℍ %V", (Point3)orient);
+ snprint(stats[Sextra], sizeof(stats[Sextra]), "blend %s z-buf %s a-buf %s",
+ maincam->enableblend? "on": "off",
+ maincam->enabledepth? "on": "off",
+ maincam->enableAbuff? "on": "off");
for(i = 0; i < Se; i++)
stringbg(screen, addpt(screen->r.min, Pt(10,10 + i*font->height)), display->black, ZP, font, stats[i], display->white, ZP);
}
@@ -625,9 +625,15 @@
SP1,
SHOWNORMALS,
SP2,
+ SETCLRCOL,
+ SP3,
CULLFRONT,
CULLBACK,
CULLNO,
+ SP4,
+ TGLBLEND,
+ TGLDEPTH,
+ TGLABUFF,
};
static char *items[] = {
[MOVELIGHT] "move light",
@@ -637,9 +643,15 @@
"",
[SHOWNORMALS] "show normals",
"",
+ [SETCLRCOL] "set clear color",
+ "",
[CULLFRONT] "cull front faces",
[CULLBACK] "cull back faces",
[CULLNO] "no culling",
+ "",
+ [TGLBLEND] "toggle blending",
+ [TGLDEPTH] "toggle depth testing",
+ [TGLABUFF] "toggle the A-buffer",
nil,
};
static Menu menu = { .item = items };
@@ -668,6 +680,15 @@
case SHOWNORMALS:
shownormals ^= 1;
break;
+ case SETCLRCOL:
+ snprint(buf, sizeof buf, "0x%08lux", maincam->clearcolor);
+ if(enter("clear color", buf, sizeof buf, mctl, kctl, nil) <= 0)
+ break;
+ nf = tokenize(buf, f, 1);
+ if(nf != 1)
+ break;
+ maincam->clearcolor = strtoul(buf, nil, 0);
+ break;
case CULLFRONT:
maincam->cullmode = CullFront;
break;
@@ -677,6 +698,15 @@
case CULLNO:
maincam->cullmode = CullNone;
break;
+ case TGLBLEND:
+ maincam->enableblend ^= 1;
+ break;
+ case TGLDEPTH:
+ maincam->enabledepth ^= 1;
+ break;
+ case TGLABUFF:
+ maincam->enableAbuff ^= 1;
+ break;
}
unlockdisplay(display);
nbsend(drawc, nil);
@@ -829,6 +859,51 @@
okdown = kdown;
}
+static void
+mkblendtestscene(void)
+{
+ static Color cols[] = {{1,0,0,0.5}, {0,1,0,0.5}, {0,0,1,0.5}};
+ Entity *ent;
+ Model *mdl;
+ Primitive t[2];
+ Point3 p, v1, v2;
+ int i, j, k;
+
+ memset(t, 0, sizeof t);
+ t[0].type = t[1].type = PTriangle;
+
+ /* build the first face/quad, facing the positive z axis */
+ p = Vec3(-0.5,-0.5,0);
+ v1 = Vec3(1,0,0);
+ v2 = Vec3(0,1,0);
+ t[0].v[0].p = addpt3(center, p);
+ t[0].v[1].p = addpt3(center, addpt3(p, v1));
+ t[0].v[2].p = addpt3(center, addpt3(p, addpt3(v1, v2)));
+ t[0].v[0].n = t[0].v[1].n = t[0].v[2].n = Vec3(0,0,1);
+ t[1].v[0] = t[0].v[0];
+ t[1].v[1] = t[0].v[2];
+ t[1].v[2].p = addpt3(center, addpt3(p, v2));
+ t[1].v[2].n = Vec3(0,0,1);
+
+ for(i = 0; i < nelem(cols); i++){
+ for(j = 0; j < 2; j++)
+ for(k = 0; k < 3; k++){
+ if(i != 0){
+ t[j].v[k].p = qrotate(t[j].v[k].p, Vec3(0,1,0), PI/nelem(cols));
+ t[j].v[k].n = qrotate(t[j].v[k].n, Vec3(0,1,0), PI/nelem(cols));
+ }
+ t[j].v[k].c = cols[i];
+ }
+
+ mdl = newmodel();
+ mdl->prims = erealloc(mdl->prims, (mdl->nprims += 2)*sizeof(*mdl->prims));
+ mdl->prims[mdl->nprims-2] = t[0];
+ mdl->prims[mdl->nprims-1] = t[1];
+ ent = newentity(nil, mdl);
+ scene->addent(scene, ent);
+ }
+}
+
void
resize(void)
{
@@ -874,6 +949,7 @@
Entity *subject;
char *texpath, *mdlpath, *s;
int i, fd, fbw, fbh, scale;
+ int blendtest = 0;
GEOMfmtinstall();
texpath = nil;
@@ -898,7 +974,7 @@
default: usage();
}ARGEND;
if(argc < 1)
- usage();
+ blendtest++;
confproc();
@@ -906,6 +982,9 @@
sysfatal("couldn't find gouraud shader");
scene = newscene(nil);
+ if(blendtest)
+ mkblendtestscene();
+ else
while(argc--){
mdlpath = argv[argc];
model = readobjmodel(mdlpath);
@@ -936,6 +1015,7 @@
sysfatal("initmouse: %r");
screenb = eallocimage(display, rectsubpt(screen->r, screen->r.min), XRGB32, 0, 0x888888FF);
+fprint(2, "screen %R\n", screenb->r);
for(i = 0; i < nelem(cams); i++){
if(fbw == 0 || fbh == 0)
cams[i] = Cam(screenb->r, rctl,
@@ -953,7 +1033,7 @@
cams[i]->view->setscalefilter(cams[i]->view, UFScale3x);
cams[i]->view->p.x = (Dx(screenb->r) - cams[i]->view->getwidth(cams[i]->view))/2;
cams[i]->view->p.y = (Dy(screenb->r) - cams[i]->view->getheight(cams[i]->view))/2;
-fprint(2, "off %v scalex %g scaley %g\n", cams[i]->view->p, cams[i]->view->bx.x, cams[i]->view->by.y);
+fprint(2, "cam%d off %v scalex %g scaley %g\n", i+1, cams[i]->view->p, cams[i]->view->bx.x, cams[i]->view->by.y);
}
maincam = cams[3];
light.p = Pt3(0,100,100,1);