From e29085580c9aa50f09dc6a696250edb90cebe3a8 Mon Sep 17 00:00:00 2001 From: ChaoLoveIceMDBoy Date: Mon, 1 Jan 2024 19:48:47 +0000 Subject: [PATCH] OpenGL: Fix linedef type 10 not culling FOFs (Closes #438) --- src/hardware/hw_main.c | 120 ++++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 56 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index fa3f27595..e92e9b476 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -2927,6 +2927,46 @@ static FBITFIELD HWR_RippleBlend(sector_t *sector, ffloor_t *rover, boolean ceil return /*R_IsRipplePlane(sector, rover, ceiling)*/ (rover->fofflags & FOF_RIPPLE) ? PF_Ripple : 0; } +// +// HWR_DoCulling +// Hardware version of R_DoCulling +// (see r_main.c) +static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float vz, float bottomh, float toph) +{ + float cullplane; + + if (!cullheight) + return false; + + cullplane = FIXED_TO_FLOAT(cullheight->frontsector->floorheight); + if (cullheight->args[1]) // Group culling + { + if (!viewcullheight) + return false; + + // Make sure this is part of the same group + if (viewcullheight->frontsector == cullheight->frontsector) + { + // OK, we can cull + if (vz > cullplane && toph < cullplane) // Cull if below plane + return true; + + if (bottomh > cullplane && vz <= cullplane) // Cull if above plane + return true; + } + } + else // Quick culling + { + if (vz > cullplane && toph < cullplane) // Cull if below plane + return true; + + if (bottomh > cullplane && vz <= cullplane) // Cull if above plane + return true; + } + + return false; +} + // -----------------+ // HWR_Subsector : Determine floor/ceiling planes. // : Add sprites of things in sector. @@ -3101,27 +3141,36 @@ static void HWR_Subsector(size_t num) for (rover = gl_frontsector->ffloors; rover; rover = rover->next) { - fixed_t cullHeight, centerHeight; - - // bottom plane - cullHeight = P_GetFFloorBottomZAt(rover, viewx, viewy); - centerHeight = P_GetFFloorBottomZAt(rover, gl_frontsector->soundorg.x, gl_frontsector->soundorg.y); + fixed_t bottomCullHeight, topCullHeight, centerHeight; if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_RENDERPLANES)) continue; if (sub->validcount == validcount) continue; + + // rendering heights for bottom and top planes + bottomCullHeight = P_GetFFloorBottomZAt(rover, viewx, viewy); + topCullHeight = P_GetFFloorTopZAt(rover, viewx, viewy); + + if (gl_frontsector->cullheight) + { + if (HWR_DoCulling(gl_frontsector->cullheight, viewsector->cullheight, gl_viewz, FIXED_TO_FLOAT(bottomCullHeight), FIXED_TO_FLOAT(topCullHeight))) + continue; + } + + // bottom plane + centerHeight = P_GetFFloorBottomZAt(rover, gl_frontsector->soundorg.x, gl_frontsector->soundorg.y); if (centerHeight <= locCeilingHeight && centerHeight >= locFloorHeight && - ((dup_viewz < cullHeight && (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES))) || - (dup_viewz > cullHeight && (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES)))) + ((dup_viewz < bottomCullHeight && (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES))) || + (dup_viewz > bottomCullHeight && (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES)))) { if (rover->fofflags & FOF_FOG) { UINT8 alpha; - light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); + light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < bottomCullHeight ? true : false); alpha = HWR_FogBlockAlpha(*gl_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap); HWR_AddTransparentFloor(0, @@ -3134,7 +3183,7 @@ static void HWR_Subsector(size_t num) } else if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend) // SoM: Flags are more efficient { - light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); + light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < bottomCullHeight ? true : false); HWR_AddTransparentFloor(&levelflats[*rover->bottompic], &extrasubsectors[num], @@ -3148,26 +3197,25 @@ static void HWR_Subsector(size_t num) else { HWR_GetLevelFlat(&levelflats[*rover->bottompic]); - light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); + light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < bottomCullHeight ? true : false); HWR_RenderPlane(sub, &extrasubsectors[num], false, *rover->bottomheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, &levelflats[*rover->bottompic], rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap); } } // top plane - cullHeight = P_GetFFloorTopZAt(rover, viewx, viewy); centerHeight = P_GetFFloorTopZAt(rover, gl_frontsector->soundorg.x, gl_frontsector->soundorg.y); if (centerHeight >= locFloorHeight && centerHeight <= locCeilingHeight && - ((dup_viewz > cullHeight && (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES))) || - (dup_viewz < cullHeight && (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES)))) + ((dup_viewz > topCullHeight && (rover->fofflags & FOF_BOTHPLANES || !(rover->fofflags & FOF_INVERTPLANES))) || + (dup_viewz < topCullHeight && (rover->fofflags & FOF_BOTHPLANES || rover->fofflags & FOF_INVERTPLANES)))) { if (rover->fofflags & FOF_FOG) { UINT8 alpha; - light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); + light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < topCullHeight ? true : false); alpha = HWR_FogBlockAlpha(*gl_frontsector->lightlist[light].lightlevel, rover->master->frontsector->extra_colormap); HWR_AddTransparentFloor(0, @@ -3180,7 +3228,7 @@ static void HWR_Subsector(size_t num) } else if ((rover->fofflags & FOF_TRANSLUCENT && !(rover->fofflags & FOF_SPLAT)) || rover->blend) { - light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); + light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < topCullHeight ? true : false); HWR_AddTransparentFloor(&levelflats[*rover->toppic], &extrasubsectors[num], @@ -3194,7 +3242,7 @@ static void HWR_Subsector(size_t num) else { HWR_GetLevelFlat(&levelflats[*rover->toppic]); - light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); + light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < topCullHeight ? true : false); HWR_RenderPlane(sub, &extrasubsectors[num], true, *rover->topheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, &levelflats[*rover->toppic], rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap); } @@ -3548,46 +3596,6 @@ static void HWR_LinkDrawHackFinish(void) linkdrawcount = 0; } -// -// HWR_DoCulling -// Hardware version of R_DoCulling -// (see r_main.c) -static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float vz, float bottomh, float toph) -{ - float cullplane; - - if (!cullheight) - return false; - - cullplane = FIXED_TO_FLOAT(cullheight->frontsector->floorheight); - if (cullheight->args[1]) // Group culling - { - if (!viewcullheight) - return false; - - // Make sure this is part of the same group - if (viewcullheight->frontsector == cullheight->frontsector) - { - // OK, we can cull - if (vz > cullplane && toph < cullplane) // Cull if below plane - return true; - - if (bottomh > cullplane && vz <= cullplane) // Cull if above plane - return true; - } - } - else // Quick culling - { - if (vz > cullplane && toph < cullplane) // Cull if below plane - return true; - - if (bottomh > cullplane && vz <= cullplane) // Cull if above plane - return true; - } - - return false; -} - static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) { patch_t *gpatch;