ref: 0e95c99e5645c8754782168c8e78243482746372
parent: b85143c529f1ca238611290e73fae27320479b0b
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sat Dec 16 08:42:05 EST 2023
32-bit zbuffer and more precise zspans drawing This significantly reduces z-fighting (especiall apparent on ad_tears) and makes torch behind a wall on ad_azad invisible from afar.
--- a/d_local.h
+++ b/d_local.h
@@ -33,7 +33,7 @@
int u, v, count;
} sspan_t;
-typedef u16int uzint;
+typedef s32int uzint;
extern cvar_t d_subdiv16;
--- a/d_part.c
+++ b/d_part.c
@@ -37,7 +37,7 @@
pz = d_pzbuffer + d_zwidth*v + u;
pdest = d_viewbuffer + d_scantable[v] + u;
- izi = zi * 0x8000;
+ izi = zi * 0x8000 * 0x10000;
zi = 1024.0 * d_pix_scale / Length(local);
pix = clamp(zi, d_pix_min, d_pix_max) * r_part_scale.value;
--- a/d_polyse.c
+++ b/d_polyse.c
@@ -117,7 +117,7 @@
// valid triangle coordinates for filling can include the bottom and
// right clip edges, due to the fill rule; these shouldn't be drawn
if (fv->u < r_refdef.vrectright && fv->v < r_refdef.vrectbottom){
- z = fv->zi >> 16;
+ z = fv->zi;
zbuf = zspantable[fv->v] + fv->u;
if(z >= *zbuf){
pixel_t p = addlight(skintable[fv->t >> 16][fv->s >> 16], fv->l[0], fv->l[1], fv->l[2]);
@@ -305,7 +305,7 @@
if ((lp2->v == lp1->v) && (lp2->u < lp1->u))
goto nodraw;
- z = new.zi >> 16;
+ z = new.zi;
zbuf = zspantable[new.v] + new.u;
if (z >= *zbuf){
pixel_t p = addlight(skintable[new.t >> 16][new.s >> 16], l[0], l[1], l[2]);
@@ -549,7 +549,7 @@
do
{
- if ((lzi >> 16) >= *lpz){
+ if (lzi >= *lpz){
pixel_t p = addlight(*lptex, llight[0], llight[1], llight[2]);
if(r_drawflags & DRAW_BLEND){
*lpdest = blendalpha(
@@ -560,7 +560,7 @@
}else{
*lpdest = p;
// gel mapping *lpdest = gelmap[*lpdest];
- *lpz = lzi >> 16;
+ *lpz = lzi;
}
}
lpdest++;
--- a/d_scan.c
+++ b/d_scan.c
@@ -63,7 +63,7 @@
do{
sturb = ((r_turb_s + r_turb_turb[(r_turb_t>>16)&(CYCLE-1)])>>16)&63;
tturb = ((r_turb_t + r_turb_turb[(r_turb_s>>16)&(CYCLE-1)])>>16)&63;
- if(*r_turb_z <= (izi >> 16) || (r_drawflags & DRAW_BLEND) == 0)
+ if(*r_turb_z <= izi || (r_drawflags & DRAW_BLEND) == 0)
*r_turb_pdest = blendalpha(*(r_turb_pbase + (tturb<<6) + sturb), *r_turb_pdest, alpha);
r_turb_s += r_turb_sstep;
r_turb_t += r_turb_tstep;
@@ -140,7 +140,7 @@
// can't step off polygon), clamp, calculate s and t steps across
// span by division, biasing steps low so we don't run off the
// texture
- spancountminus1 = (float)(r_turb_spancount - 1);
+ spancountminus1 = r_turb_spancount - 1;
sdivz += d_sdivzstepu * spancountminus1;
tdivz += d_tdivzstepu * spancountminus1;
zi += d_zistepu * spancountminus1;
@@ -242,7 +242,7 @@
// can't step off polygon), clamp, calculate s and t steps across
// span by division, biasing steps low so we don't run off the
// texture
- spancountminus1 = (float)(spancount - 1);
+ spancountminus1 = spancount - 1;
sdivz += d_sdivzstepu * spancountminus1;
tdivz += d_tdivzstepu * spancountminus1;
zi += d_zistepu * spancountminus1;
@@ -284,50 +284,44 @@
void
D_DrawZSpans(espan_t *pspan)
{
- int count, doublecount, izistep, izi;
- uzint *pdest;
- unsigned ltemp;
- double zi;
- float du, dv;
+ int count, spancount, izi, izistep;
+ uzint *pz;
+ double zi, du, dv, spancountminus1;
+ double zistepu;
if((r_drawflags & DRAW_BLEND) != 0)
return;
- // FIXME: check for clamping/range problems
- // we count on FP exceptions being turned off to avoid range problems
+ zistepu = d_zistepu * 16;
izistep = (int)(d_zistepu * 0x8000 * 0x10000);
do{
- pdest = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
+ pz = d_pzbuffer + d_zwidth*pspan->v + pspan->u;
+
count = pspan->count;
- // calculate the initial 1/z
- du = (float)pspan->u;
- dv = (float)pspan->v;
+ // calculate the initial s/z, t/z, 1/z, s, and t and clamp
+ du = pspan->u;
+ dv = pspan->v;
zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
- // we count on FP exceptions being turned off to avoid range problems
- izi = (int)(zi * 0x8000 * 0x10000);
- if((uintptr)pdest & 0x02){
- *pdest++ = (short)(izi >> 16);
- izi += izistep;
- count--;
- }
+ do{
+ spancount = min(count, 16);
+ count -= spancount;
- if((doublecount = count >> 1) > 0){
- do{
- ltemp = izi >> 16;
- izi += izistep;
- ltemp |= izi & 0xFFFF0000;
- izi += izistep;
- *(int *)pdest = ltemp;
- pdest += 2;
- }while (--doublecount > 0);
- }
+ if(count){
+ zi += zistepu;
+ }else{
+ spancountminus1 = spancount - 1;
+ zi += d_zistepu * spancountminus1;
+ }
- if(count & 1)
- *pdest = (short)(izi >> 16);
-
+ izi = (int)(zi * 0x8000 * 0x10000);
+ while(spancount-- > 0){
+ *pz++ = izi;
+ izi += izistep;
+ }
+ }while(count > 0);
}while((pspan = pspan->pnext) != nil);
}
--- a/d_sprite.c
+++ b/d_sprite.c
@@ -137,11 +137,11 @@
btemp = *(pbase + (s >> 16) + (t >> 16) * cachewidth);
if (opaque(btemp))
{
- if (*pz <= (izi >> 16)){ /* FIXME: segfault: assumed 32bit ptr? */
+ if (*pz <= izi){
if(r_drawflags & DRAW_BLEND){
*pdest = blendalpha(btemp, *pdest, alpha);
}else{
- *pz = izi >> 16;
+ *pz = izi;
*pdest = btemp;
}
}
--- a/span_alpha.c
+++ b/span_alpha.c
@@ -8,7 +8,7 @@
if(alpha != 255){
do{
pix = pbase[(s >> 16) + (t >> 16) * cachewidth];
- if(opaque(pix) && *pz <= (izi >> 16))
+ if(opaque(pix) && *pz <= izi)
*pdest = blendalpha(pix, *pdest, alpha);
pdest++;
pz++;
@@ -19,9 +19,9 @@
}else{
do{
pix = pbase[(s >> 16) + (t >> 16) * cachewidth];
- if(opaque(pix) && *pz <= (izi >> 16)){
+ if(opaque(pix) && *pz <= izi){
*pdest = pix;
- *pz = izi >> 16;
+ *pz = izi;
}
pdest++;
pz++;