From 7b8a564f69688515319ccd425f2b88ffe8b7b120 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 5 Apr 2023 00:13:18 -0700 Subject: [PATCH] Cull BSP behind a raised floor or lowered ceiling that covers the entire screen This can effectively award the performance of a thok barrier automatically, for walls that completely fill the screen vertically. (Not pegged midtextures.) --- src/r_bsp.cpp | 33 +++++++++++++++++++++++++++++---- src/r_bsp.h | 1 + src/r_segs.c | 25 ++++++++++++++----------- 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 84987a32d..ddafbb014 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -43,6 +43,10 @@ drawseg_t *ds_p = NULL; // indicates doors closed wrt automap bugfix: 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) { const boolean invertEncore = (sector->flags & MSF_INVERTENCORE); @@ -99,6 +103,7 @@ enum class ClipType // e.g. single sided LineDefs (middle texture) // that entirely block the view. kSolid, + kSolidDontRender, // 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. @@ -138,7 +143,10 @@ void R_ClipWallSegment(INT32 first, INT32 last) if (last < start->first - 1) { // 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) { @@ -161,7 +169,10 @@ void R_ClipWallSegment(INT32 first, INT32 last) } // 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) { @@ -178,7 +189,11 @@ void R_ClipWallSegment(INT32 first, INT32 last) while (last >= (next+1)->first - 1) { // 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++; if (last <= next->last) @@ -196,7 +211,10 @@ void R_ClipWallSegment(INT32 first, INT32 last) } // 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) { @@ -629,10 +647,17 @@ static void R_AddLine(seg_t *line) return; clippass: + g_walloffscreen = false; R_ClipWallSegment(x1, x2 - 1); + + if (g_walloffscreen) + { + R_ClipWallSegment(x1, x2 -1); + } return; clipsolid: + g_walloffscreen = false; R_ClipWallSegment(x1, x2 - 1); } diff --git a/src/r_bsp.h b/src/r_bsp.h index 66d1ff9cc..d01fa97f0 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -39,6 +39,7 @@ extern drawseg_t *curdrawsegs; extern drawseg_t *drawsegs; extern drawseg_t *ds_p; extern INT32 doorclosed; +extern boolean g_walloffscreen; // BSP? void R_ClearClipSegs(void); diff --git a/src/r_segs.c b/src/r_segs.c index 2b6f471d6..74800fb21 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -2737,23 +2737,26 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (toptexture) { - pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); - pixhighstep = -FixedMul (rw_scalestep,worldhigh); + fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2); - if (backsector->c_slope) { - fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2); - pixhighstep = (topfracend-pixhigh)/(range); - } + pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); + 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) { + fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); + pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale); - pixlowstep = -FixedMul (rw_scalestep,worldlow); - if (backsector->f_slope) { - fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); - pixlowstep = (bottomfracend-pixlow)/(range); - } + pixlowstep = (bottomfracend-pixlow)/(range); + + // If the highest part of a floor stretching up covers the entire screen + if ((max(pixlow, bottomfracend)+HEIGHTUNIT-1)>>HEIGHTBITS <= 0) + g_walloffscreen = true; } {