Merge branch 'raised-sector-culling' into 'master'

Automatic level culling for raised floors / lowered ceilings

See merge request KartKrew/Kart!1145
This commit is contained in:
toaster 2023-04-06 14:42:56 +00:00
commit 217e116bcd
3 changed files with 44 additions and 15 deletions

View file

@ -43,6 +43,10 @@ drawseg_t *ds_p = NULL;
// indicates doors closed wrt automap bugfix: // indicates doors closed wrt automap bugfix:
INT32 doorclosed; INT32 doorclosed;
// A wall was drawn covering the whole screen, which means we
// can block off the BSP across that seg.
boolean g_walloffscreen;
boolean R_NoEncore(sector_t *sector, levelflat_t *flat, boolean ceiling) boolean R_NoEncore(sector_t *sector, levelflat_t *flat, boolean ceiling)
{ {
const boolean invertEncore = (sector->flags & MSF_INVERTENCORE); const boolean invertEncore = (sector->flags & MSF_INVERTENCORE);
@ -99,6 +103,7 @@ enum class ClipType
// e.g. single sided LineDefs (middle texture) // e.g. single sided LineDefs (middle texture)
// that entirely block the view. // that entirely block the view.
kSolid, kSolid,
kSolidDontRender,
// Clips the given range of columns, but does not include it in the clip list. // Clips the given range of columns, but does not include it in the clip list.
// Does handle windows, e.g. LineDefs with upper and lower texture. // Does handle windows, e.g. LineDefs with upper and lower texture.
@ -138,7 +143,10 @@ void R_ClipWallSegment(INT32 first, INT32 last)
if (last < start->first - 1) if (last < start->first - 1)
{ {
// Post is entirely visible (above start), so insert a new clippost. // Post is entirely visible (above start), so insert a new clippost.
R_StoreWallRange(first, last); if constexpr (Type != ClipType::kSolidDontRender)
{
R_StoreWallRange(first, last);
}
if constexpr (Type != ClipType::kPass) if constexpr (Type != ClipType::kPass)
{ {
@ -161,7 +169,10 @@ void R_ClipWallSegment(INT32 first, INT32 last)
} }
// There is a fragment above *start. // There is a fragment above *start.
R_StoreWallRange(first, start->first - 1); if constexpr (Type != ClipType::kSolidDontRender)
{
R_StoreWallRange(first, start->first - 1);
}
if constexpr (Type != ClipType::kPass) if constexpr (Type != ClipType::kPass)
{ {
@ -178,7 +189,11 @@ void R_ClipWallSegment(INT32 first, INT32 last)
while (last >= (next+1)->first - 1) while (last >= (next+1)->first - 1)
{ {
// There is a fragment between two posts. // There is a fragment between two posts.
R_StoreWallRange(start->last + 1, (start+1)->first - 1); if constexpr (Type != ClipType::kSolidDontRender)
{
R_StoreWallRange(next->last + 1, (next+1)->first - 1);
}
next++; next++;
if (last <= next->last) if (last <= next->last)
@ -196,7 +211,10 @@ void R_ClipWallSegment(INT32 first, INT32 last)
} }
// There is a fragment after *next. // There is a fragment after *next.
R_StoreWallRange(start->last + 1, last); if constexpr (Type != ClipType::kSolidDontRender)
{
R_StoreWallRange(next->last + 1, last);
}
if constexpr (Type != ClipType::kPass) if constexpr (Type != ClipType::kPass)
{ {
@ -629,10 +647,17 @@ static void R_AddLine(seg_t *line)
return; return;
clippass: clippass:
g_walloffscreen = false;
R_ClipWallSegment<ClipType::kPass>(x1, x2 - 1); R_ClipWallSegment<ClipType::kPass>(x1, x2 - 1);
if (g_walloffscreen)
{
R_ClipWallSegment<ClipType::kSolidDontRender>(x1, x2 -1);
}
return; return;
clipsolid: clipsolid:
g_walloffscreen = false;
R_ClipWallSegment<ClipType::kSolid>(x1, x2 - 1); R_ClipWallSegment<ClipType::kSolid>(x1, x2 - 1);
} }

View file

@ -39,6 +39,7 @@ extern drawseg_t *curdrawsegs;
extern drawseg_t *drawsegs; extern drawseg_t *drawsegs;
extern drawseg_t *ds_p; extern drawseg_t *ds_p;
extern INT32 doorclosed; extern INT32 doorclosed;
extern boolean g_walloffscreen;
// BSP? // BSP?
void R_ClearClipSegs(void); void R_ClearClipSegs(void);

View file

@ -2737,23 +2737,26 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (toptexture) if (toptexture)
{ {
pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2);
pixhighstep = -FixedMul (rw_scalestep,worldhigh);
if (backsector->c_slope) { pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale);
fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2); pixhighstep = (topfracend-pixhigh)/(range);
pixhighstep = (topfracend-pixhigh)/(range);
} // If the lowest part of a ceiling stretching down covers the entire screen
if (min(pixhigh, topfracend)>>HEIGHTBITS >= viewheight-1)
g_walloffscreen = true;
} }
if (bottomtexture) if (bottomtexture)
{ {
fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2);
pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale); pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale);
pixlowstep = -FixedMul (rw_scalestep,worldlow); pixlowstep = (bottomfracend-pixlow)/(range);
if (backsector->f_slope) {
fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); // If the highest part of a floor stretching up covers the entire screen
pixlowstep = (bottomfracend-pixlow)/(range); if ((max(pixlow, bottomfracend)+HEIGHTUNIT-1)>>HEIGHTBITS <= 0)
} g_walloffscreen = true;
} }
{ {