Plane optimization and cleanup

This commit is contained in:
Jaime Passos 2020-11-04 23:46:34 -03:00
parent 805818d48e
commit c07c80fd9e
5 changed files with 157 additions and 130 deletions

View File

@ -104,11 +104,11 @@ fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep;
UINT16 ds_flatwidth, ds_flatheight;
boolean ds_powersoftwo;
UINT8 *ds_source; // start of a 64*64 tile image
UINT8 *ds_source; // points to the start of a flat
UINT8 *ds_transmap; // one of the translucency tables
pslope_t *ds_slope; // Current slope being used
floatv3_t ds_su[MAXVIDHEIGHT], ds_sv[MAXVIDHEIGHT], ds_sz[MAXVIDHEIGHT]; // Vectors for... stuff?
// Vectors for Software's tilted slope drawers
floatv3_t *ds_su, *ds_sv, *ds_sz;
floatv3_t *ds_sup, *ds_svp, *ds_szp;
float focallengthf, zeroheight;

View File

@ -59,6 +59,7 @@ extern lighttable_t *ds_translation;
extern fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep;
extern UINT16 ds_flatwidth, ds_flatheight;
extern boolean ds_powersoftwo;
extern UINT8 *ds_source;
extern UINT8 *ds_transmap;
@ -66,8 +67,8 @@ typedef struct {
float x, y, z;
} floatv3_t;
extern pslope_t *ds_slope; // Current slope being used
extern floatv3_t ds_su[MAXVIDHEIGHT], ds_sv[MAXVIDHEIGHT], ds_sz[MAXVIDHEIGHT]; // Vectors for... stuff?
// Vectors for Software's tilted slope drawers
extern floatv3_t *ds_su, *ds_sv, *ds_sz;
extern floatv3_t *ds_sup, *ds_svp, *ds_szp;
extern float focallengthf, zeroheight;

View File

@ -958,6 +958,16 @@ void R_ExecuteSetViewSize(void)
dy = FixedMul(abs(dy), fovtan);
yslopetab[i] = FixedDiv(centerx*FRACUNIT, dy);
}
if (ds_su)
Z_Free(ds_su);
if (ds_sv)
Z_Free(ds_sv);
if (ds_sz)
Z_Free(ds_sz);
ds_su = ds_sv = ds_sz = NULL;
ds_sup = ds_svp = ds_szp = NULL;
}
memset(scalelight, 0xFF, sizeof(scalelight));

View File

@ -117,29 +117,41 @@ void R_InitPlanes(void)
//
// Water ripple effect!!
// Needs the height of the plane, and the vertical position of the span.
// Sets ripple_xfrac and ripple_yfrac, added to ds_xfrac and ds_yfrac, if the span is not tilted.
// Sets planeripple.xfrac and planeripple.yfrac, added to ds_xfrac and ds_yfrac, if the span is not tilted.
//
#ifndef NOWATER
INT32 ds_bgofs;
INT32 ds_waterofs;
static INT32 wtofs=0;
static boolean itswater;
static fixed_t ripple_xfrac;
static fixed_t ripple_yfrac;
struct
{
INT32 offset;
fixed_t xfrac, yfrac;
boolean active;
} planeripple;
static void R_PlaneRipple(visplane_t *plane, INT32 y, fixed_t plheight)
static void R_CalculatePlaneRipple(visplane_t *plane, INT32 y, fixed_t plheight, boolean calcfrac)
{
fixed_t distance = FixedMul(plheight, yslope[y]);
const INT32 yay = (wtofs + (distance>>9) ) & 8191;
const INT32 yay = (planeripple.offset + (distance>>9)) & 8191;
// ripples da water texture
angle_t angle = (plane->viewangle + plane->plangle)>>ANGLETOFINESHIFT;
ds_bgofs = FixedDiv(FINESINE(yay), (1<<12) + (distance>>11))>>FRACBITS;
angle = (angle + 2048) & 8191; // 90 degrees
ripple_xfrac = FixedMul(FINECOSINE(angle), (ds_bgofs<<FRACBITS));
ripple_yfrac = FixedMul(FINESINE(angle), (ds_bgofs<<FRACBITS));
if (calcfrac)
{
angle_t angle = (plane->viewangle + plane->plangle)>>ANGLETOFINESHIFT;
angle = (angle + 2048) & 8191; // 90 degrees
planeripple.xfrac = FixedMul(FINECOSINE(angle), (ds_bgofs<<FRACBITS));
planeripple.yfrac = FixedMul(FINESINE(angle), (ds_bgofs<<FRACBITS));
}
}
static void R_UpdatePlaneRipple(void)
{
ds_waterofs = (leveltime & 1)*16384;
planeripple.offset = (leveltime * 140);
}
#endif
@ -159,7 +171,7 @@ static void R_PlaneRipple(visplane_t *plane, INT32 y, fixed_t plheight)
void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
{
angle_t angle, planecos, planesin;
fixed_t distance, span;
fixed_t distance = 0, span;
size_t pindex;
#ifdef RANGECHECK
@ -167,41 +179,51 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
I_Error("R_MapPlane: %d, %d at %d", x1, x2, y);
#endif
// from r_splats's R_RenderFloorSplat
if (x1 >= vid.width) x1 = vid.width - 1;
if (x1 >= vid.width)
x1 = vid.width - 1;
angle = (currentplane->viewangle + currentplane->plangle)>>ANGLETOFINESHIFT;
planecos = FINECOSINE(angle);
planesin = FINESINE(angle);
if (planeheight != cachedheight[y])
if (!currentplane->slope)
{
cachedheight[y] = planeheight;
distance = cacheddistance[y] = FixedMul(planeheight, yslope[y]);
ds_xstep = cachedxstep[y] = FixedMul(distance, basexscale);
ds_ystep = cachedystep[y] = FixedMul(distance, baseyscale);
angle = (currentplane->viewangle + currentplane->plangle)>>ANGLETOFINESHIFT;
planecos = FINECOSINE(angle);
planesin = FINESINE(angle);
if ((span = abs(centery-y)))
if (planeheight != cachedheight[y])
{
ds_xstep = cachedxstep[y] = FixedMul(planesin, planeheight) / span;
ds_ystep = cachedystep[y] = FixedMul(planecos, planeheight) / span;
}
}
else
{
distance = cacheddistance[y];
ds_xstep = cachedxstep[y];
ds_ystep = cachedystep[y];
}
cachedheight[y] = planeheight;
cacheddistance[y] = distance = FixedMul(planeheight, yslope[y]);
span = abs(centery - y);
ds_xfrac = xoffs + FixedMul(planecos, distance) + (x1 - centerx) * ds_xstep;
ds_yfrac = yoffs - FixedMul(planesin, distance) + (x1 - centerx) * ds_ystep;
if (span) // don't divide by zero
{
ds_xstep = FixedMul(planesin, planeheight) / span;
ds_ystep = FixedMul(planecos, planeheight) / span;
}
else
{
ds_xstep = FixedMul(distance, basexscale);
ds_ystep = FixedMul(distance, baseyscale);
}
cachedxstep[y] = ds_xstep;
cachedystep[y] = ds_ystep;
}
else
{
distance = cacheddistance[y];
ds_xstep = cachedxstep[y];
ds_ystep = cachedystep[y];
}
ds_xfrac = xoffs + FixedMul(planecos, distance) + (x1 - centerx) * ds_xstep;
ds_yfrac = yoffs - FixedMul(planesin, distance) + (x1 - centerx) * ds_ystep;
}
#ifndef NOWATER
if (itswater)
if (planeripple.active)
{
// Needed for ds_bgofs
R_PlaneRipple(currentplane, y, planeheight);
R_CalculatePlaneRipple(currentplane, y, planeheight, (!currentplane->slope));
if (currentplane->slope)
{
@ -211,25 +233,26 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
}
else
{
ds_xfrac += ripple_xfrac;
ds_yfrac += ripple_yfrac;
ds_xfrac += planeripple.xfrac;
ds_yfrac += planeripple.yfrac;
}
if (y+ds_bgofs>=viewheight)
if ((y + ds_bgofs) >= viewheight)
ds_bgofs = viewheight-y-1;
if (y+ds_bgofs<0)
if ((y + ds_bgofs) < 0)
ds_bgofs = -y;
}
#endif
pindex = distance >> LIGHTZSHIFT;
if (pindex >= MAXLIGHTZ)
pindex = MAXLIGHTZ - 1;
if (currentplane->slope)
ds_colormap = colormaps;
else
{
pindex = distance >> LIGHTZSHIFT;
if (pindex >= MAXLIGHTZ)
pindex = MAXLIGHTZ - 1;
ds_colormap = planezlight[pindex];
}
if (currentplane->extra_colormap)
ds_colormap = currentplane->extra_colormap->colormap + (ds_colormap - colormaps);
@ -596,9 +619,9 @@ void R_DrawPlanes(void)
R_DrawSinglePlane(pl);
}
}
#ifndef NOWATER
ds_waterofs = (leveltime & 1)*16384;
wtofs = leveltime * 140;
R_UpdatePlaneRipple();
#endif
}
@ -738,12 +761,20 @@ d->z = (v1.x * v2.y) - (v1.y * v2.x)
#undef SFMULT
}
static void R_SlopePlaneVectors(visplane_t *pl, INT32 i, float fudge)
static void R_SetSlopePlaneVectors(visplane_t *pl, INT32 y, fixed_t xoff, fixed_t yoff, float fudge)
{
ds_sup = &ds_su[i];
ds_svp = &ds_sv[i];
ds_szp = &ds_sz[i];
R_CalculateSlopeVectors(pl->slope, pl->viewx, pl->viewy, pl->viewz, FRACUNIT, FRACUNIT, xoffs, yoffs, pl->viewangle, pl->plangle, fudge);
if (ds_su == NULL)
ds_su = Z_Malloc(sizeof(*ds_su) * vid.height, PU_STATIC, NULL);
if (ds_sv == NULL)
ds_sv = Z_Malloc(sizeof(*ds_sv) * vid.height, PU_STATIC, NULL);
if (ds_sz == NULL)
ds_sz = Z_Malloc(sizeof(*ds_sz) * vid.height, PU_STATIC, NULL);
ds_sup = &ds_su[y];
ds_svp = &ds_sv[y];
ds_szp = &ds_sz[y];
R_CalculateSlopeVectors(pl->slope, pl->viewx, pl->viewy, pl->viewz, FRACUNIT, FRACUNIT, xoff, yoff, pl->viewangle, pl->plangle, fudge);
}
void R_DrawSinglePlane(visplane_t *pl)
@ -768,7 +799,7 @@ void R_DrawSinglePlane(visplane_t *pl)
}
#ifndef NOWATER
itswater = false;
planeripple.active = false;
#endif
spanfunc = spanfuncs[BASEDRAWFUNC];
@ -851,12 +882,13 @@ void R_DrawSinglePlane(visplane_t *pl)
}
else light = (pl->lightlevel >> LIGHTSEGSHIFT);
#ifndef NOWATER
#ifndef NOWATER
if (pl->ffloor->flags & FF_RIPPLE)
{
INT32 top, bottom;
itswater = true;
planeripple.active = true;
if (spanfunctype == SPANDRAWFUNC_TRANS)
{
spanfunctype = SPANDRAWFUNC_WATER;
@ -876,7 +908,7 @@ void R_DrawSinglePlane(visplane_t *pl)
vid.width, vid.width);
}
}
#endif
#endif
}
else
light = (pl->lightlevel >> LIGHTSEGSHIFT);
@ -979,50 +1011,45 @@ void R_DrawSinglePlane(visplane_t *pl)
xoffs -= (pl->slope->o.x + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1);
yoffs += (pl->slope->o.y + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1);
}
xoffs = (fixed_t)(xoffs*fudgecanyon);
yoffs = (fixed_t)(yoffs/fudgecanyon);
}
ds_sup = &ds_su[0];
ds_svp = &ds_sv[0];
ds_szp = &ds_sz[0];
#ifndef NOWATER
if (itswater)
if (planeripple.active)
{
INT32 i;
fixed_t plheight = abs(P_GetSlopeZAt(pl->slope, pl->viewx, pl->viewy) - pl->viewz);
fixed_t rxoffs = xoffs;
fixed_t ryoffs = yoffs;
R_PlaneBounds(pl);
for (i = pl->high; i < pl->low; i++)
for (x = pl->high; x < pl->low; x++)
{
R_PlaneRipple(pl, i, plheight);
xoffs = rxoffs + ripple_xfrac;
yoffs = ryoffs + ripple_yfrac;
R_SlopePlaneVectors(pl, i, fudgecanyon);
R_CalculatePlaneRipple(pl, x, plheight, true);
R_SetSlopePlaneVectors(pl, x, (xoffs + planeripple.xfrac), (yoffs + planeripple.yfrac), fudgecanyon);
}
xoffs = rxoffs;
yoffs = ryoffs;
}
else
#endif
R_SlopePlaneVectors(pl, 0, fudgecanyon);
R_SetSlopePlaneVectors(pl, 0, xoffs, yoffs, fudgecanyon);
switch (spanfunctype)
{
#ifndef NOWATER
if (itswater && (spanfunctype == SPANDRAWFUNC_WATER))
spanfunctype = SPANDRAWFUNC_TILTEDWATER;
else
case SPANDRAWFUNC_WATER:
spanfunctype = SPANDRAWFUNC_TILTEDWATER;
break;
#endif
if (spanfunctype == SPANDRAWFUNC_TRANS)
spanfunctype = SPANDRAWFUNC_TILTEDTRANS;
else if (spanfunctype == SPANDRAWFUNC_SPLAT)
spanfunctype = SPANDRAWFUNC_TILTEDSPLAT;
else
spanfunctype = SPANDRAWFUNC_TILTED;
case SPANDRAWFUNC_TRANS:
spanfunctype = SPANDRAWFUNC_TILTEDTRANS;
break;
case SPANDRAWFUNC_SPLAT:
spanfunctype = SPANDRAWFUNC_TILTEDSPLAT;
break;
default:
spanfunctype = SPANDRAWFUNC_TILTED;
break;
}
planezlight = scalelight[light];
}

View File

@ -344,13 +344,9 @@ void R_RenderFloorSplat(floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis
INT32 miny = viewheight + 1, maxy = 0;
INT32 y, x1, ry1, x2, y2, i;
fixed_t offsetx = 0, offsety = 0;
fixed_t planeheight = 0;
fixed_t step;
fixed_t planeheight;
fixed_t xstep, ystep;
angle_t angle, planecos, planesin;
fixed_t distance, span;
int spanfunctype = SPANDRAWFUNC_SPRITE;
prepare_rastertab();
@ -431,14 +427,17 @@ void R_RenderFloorSplat(floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis
}
else
{
planeheight = abs(pSplat->z - viewz);
if (pSplat->angle)
{
// Add the view offset, rotated by the plane angle.
fixed_t a = -pSplat->verts[0].x + viewx;
fixed_t b = -pSplat->verts[0].y + viewy;
angle = (pSplat->angle >> ANGLETOFINESHIFT);
angle_t angle = (pSplat->angle >> ANGLETOFINESHIFT);
offsetx = FixedMul(a, FINECOSINE(angle)) - FixedMul(b,FINESINE(angle));
offsety = -FixedMul(a, FINESINE(angle)) - FixedMul(b,FINECOSINE(angle));
memset(cachedheight, 0, sizeof(cachedheight));
}
else
{
@ -477,21 +476,6 @@ void R_RenderFloorSplat(floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis
else
spanfunc = spanfuncs_npo2[spanfunctype];
if (pSplat->angle && !pSplat->tilted)
{
memset(cachedheight, 0, sizeof(cachedheight));
angle = (viewangle + pSplat->angle - ANGLE_90) >> ANGLETOFINESHIFT;
basexscale = FixedDiv(FINECOSINE(angle), centerxfrac);
baseyscale = -FixedDiv(FINESINE(angle), centerxfrac);
}
else
{
angle = (viewangle - ANGLE_90) >> ANGLETOFINESHIFT;
basexscale = FixedDiv(FINECOSINE(angle), centerxfrac);
baseyscale = -FixedDiv(FINESINE(angle), centerxfrac);
}
planeheight = abs(pSplat->z - viewz);
if (maxy >= vid.height)
maxy = vid.height-1;
@ -543,25 +527,38 @@ void R_RenderFloorSplat(floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis
break;
}
if (x2 < x1)
continue;
if (!pSplat->tilted)
{
angle = (viewangle + pSplat->angle)>>ANGLETOFINESHIFT;
planecos = FINECOSINE(angle);
planesin = FINESINE(angle);
fixed_t xstep, ystep;
fixed_t distance, span;
angle_t angle = (viewangle + pSplat->angle)>>ANGLETOFINESHIFT;
angle_t planecos = FINECOSINE(angle);
angle_t planesin = FINESINE(angle);
if (planeheight != cachedheight[y])
{
cachedheight[y] = planeheight;
distance = cacheddistance[y] = FixedMul(planeheight, yslope[y]);
xstep = cachedxstep[y] = FixedMul(distance, basexscale);
ystep = cachedystep[y] = FixedMul(distance, baseyscale);
span = abs(centery - y);
// don't divide by zero
if ((span = abs(centery-y)))
if (span) // don't divide by zero
{
xstep = cachedxstep[y] = FixedMul(planesin, planeheight) / span;
ystep = cachedystep[y] = FixedMul(planecos, planeheight) / span;
xstep = FixedMul(planesin, planeheight) / span;
ystep = FixedMul(planecos, planeheight) / span;
}
else
{
// ah
xstep = FRACUNIT;
ystep = FRACUNIT;
}
cachedxstep[y] = xstep;
cachedystep[y] = ystep;
}
else
{
@ -577,25 +574,17 @@ void R_RenderFloorSplat(floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis
ds_yfrac = FixedDiv(offsety - FixedMul(planesin, distance) + (x1 - centerx) * ystep, pSplat->yscale);
}
if (x2 >= x1)
{
ds_y = y;
ds_x1 = x1;
ds_x2 = x2;
spanfunc();
}
ds_y = y;
ds_x1 = x1;
ds_x2 = x2;
spanfunc();
rastertab[y].minx = INT32_MAX;
rastertab[y].maxx = INT32_MIN;
}
if (pSplat->angle && !pSplat->tilted)
{
memset(cachedheight, 0, sizeof(cachedheight));
angle = (viewangle - ANGLE_90) >> ANGLETOFINESHIFT;
basexscale = FixedDiv(FINECOSINE(angle), centerxfrac);
baseyscale = -FixedDiv(FINESINE(angle), centerxfrac);
}
}
static void prepare_rastertab(void)