From efe9204f78b1e9dc03ec498bf018535f434d8c19 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 7 Feb 2018 17:46:01 +0000 Subject: [PATCH] Fixed sky-sky thok barriers showing HOM (turns out the floor and ceiling share the same plane, so I've modified the code to account for this) Additionally, place some optimisations in both software and OpenGL; in particular one has been added for when all of back and front sector (floor and ceiling) is sky: since everything is "open" anyway, we can simply the usual checks involved. --- src/hardware/hw_main.c | 91 ++++++++++++++++++++++++++++++++++-------- src/r_bsp.c | 48 +++++++++++++++------- src/r_segs.c | 43 +++++++++++--------- 3 files changed, 133 insertions(+), 49 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 44da2b9f2..597990a62 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -2433,6 +2433,12 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks { fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends + boolean bothceilingssky = false, bothfloorssky = false; + + if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) + bothceilingssky = true; + if (abacksector->floorpic == skyflatnum && afrontsector->floorpic == skyflatnum) + bothfloorssky = true; // GZDoom method of sloped line clipping @@ -2467,8 +2473,7 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks } // properly render skies (consider door "open" if both ceilings are sky) // same for floors - if ((abacksector->ceilingpic != skyflatnum || afrontsector->ceilingpic != skyflatnum) - && (abacksector->floorpic != skyflatnum || afrontsector->floorpic != skyflatnum)) + if (!bothceilingssky && !bothfloorssky) { // now check for closed sectors! if ((backc1 <= frontf1 && backc2 <= frontf2) @@ -2490,12 +2495,21 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks } } - if (backc1 != frontc1 || backc2 != frontc2 - || backf1 != frontf1 || backf2 != frontf2) + if (!bothceilingssky) { + if (backc1 != frontc1 || backc2 != frontc2) { checkforemptylines = false; return false; } + } + + if (!bothfloorssky) { + if (backf1 != frontf1 || backf2 != frontf2) + { + checkforemptylines = false; + return false; + } + } return false; } @@ -2798,6 +2812,7 @@ static void HWR_AddLine(seg_t * line) #ifndef NEWCLIP INT32 x1, x2; angle_t span, tspan; + boolean bothceilingssky = false, bothfloorssky = false; #endif // SoM: Backsector needs to be run through R_FakeFlat @@ -2923,7 +2938,30 @@ static void HWR_AddLine(seg_t * line) } else { + boolean bothceilingssky = false, bothfloorssky = false; + gr_backsector = R_FakeFlat(gr_backsector, &tempsec, NULL, NULL, true); + + if (gr_backsector->ceilingpic == skyflatnum && gr_frontsector->ceilingpic == skyflatnum) + bothceilingssky = true; + if (gr_backsector->floorpic == skyflatnum && gr_frontsector->floorpic == skyflatnum) + bothfloorssky = true; + + if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then + { + if ( +#ifdef POLYOBJECTS + !line->polyseg && +#endif + !line->sidedef->midtexture + && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) + || (gr_frontsector->tag == gr_backsector->tag))) + return; // line is empty, don't even bother + // treat like wide open window instead + HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D + return; + } + if (CheckClip(line, gr_frontsector, gr_backsector)) { gld_clipper_SafeAddClipRange(angle2, angle1); @@ -2946,6 +2984,25 @@ static void HWR_AddLine(seg_t * line) gr_backsector = R_FakeFlat(gr_backsector, &tempsec, NULL, NULL, true); + if (gr_backsector->ceilingpic == skyflatnum && gr_frontsector->ceilingpic == skyflatnum) + bothceilingssky = true; + if (gr_backsector->floorpic == skyflatnum && gr_frontsector->floorpic == skyflatnum) + bothfloorssky = true; + + if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then + { + if ( +#ifdef POLYOBJECTS + !line->polyseg && +#endif + !line->sidedef->midtexture + && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) + || (gr_frontsector->tag == gr_backsector->tag))) + return; // line is empty, don't even bother + + goto clippass; // treat like wide open window instead + } + #ifdef ESLOPE if (gr_frontsector->f_slope || gr_frontsector->c_slope || gr_backsector->f_slope || gr_backsector->c_slope) { @@ -2966,8 +3023,7 @@ static void HWR_AddLine(seg_t * line) #undef SLOPEPARAMS // if both ceilings are skies, consider it always "open" // same for floors - if ((gr_backsector->ceilingpic != skyflatnum || gr_frontsector->ceilingpic != skyflatnum) - && (gr_backsector->floorpic != skyflatnum || gr_frontsector->floorpic != skyflatnum)) + if (!bothceilingssky && !bothfloorssky) { // Closed door. if ((backc1 <= frontf1 && backc2 <= frontf2) @@ -2984,19 +3040,19 @@ static void HWR_AddLine(seg_t * line) } // Window. - if (backc1 != frontc1 || backc2 != frontc2 - || backf1 != frontf1 || backf2 != frontf2) - { - goto clippass; - } + if (!bothceilingssky) // ceilings are always the "same" when sky + if (backc1 != frontc1 || backc2 != frontc2) + goto clippass; + if (!bothfloorssky) // floors are always the "same" when sky + if (backf1 != frontf1 || backf2 != frontf2) + goto clippass; } else #endif { // if both ceilings are skies, consider it always "open" // same for floors - if ((gr_backsector->ceilingpic != skyflatnum || gr_frontsector->ceilingpic != skyflatnum) - && (gr_backsector->floorpic != skyflatnum || gr_frontsector->floorpic != skyflatnum)) + if (!bothceilingssky && !bothfloorssky) { // Closed door. if (gr_backsector->ceilingheight <= gr_frontsector->floorheight || @@ -3011,9 +3067,12 @@ static void HWR_AddLine(seg_t * line) } // Window. - if (gr_backsector->ceilingheight != gr_frontsector->ceilingheight || - gr_backsector->floorheight != gr_frontsector->floorheight) - goto clippass; + if (!bothceilingssky) // ceilings are always the "same" when sky + if (gr_backsector->ceilingheight != gr_frontsector->ceilingheight) + goto clippass; + if (!bothfloorssky) // floors are always the "same" when sky + if (gr_backsector->floorheight != gr_frontsector->floorheight) + goto clippass; } // Reject empty lines used for triggers and special events. diff --git a/src/r_bsp.c b/src/r_bsp.c index 5b0a4ca36..183def25a 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -401,6 +401,7 @@ static void R_AddLine(seg_t *line) INT32 x1, x2; angle_t angle1, angle2, span, tspan; static sector_t tempsec; // ceiling/water hack + boolean bothceilingssky = false, bothfloorssky = false; if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES)) return; @@ -487,6 +488,25 @@ static void R_AddLine(seg_t *line) doorclosed = 0; + if (backsector->ceilingpic == skyflatnum && frontsector->ceilingpic == skyflatnum) + bothceilingssky = true; + if (backsector->floorpic == skyflatnum && frontsector->floorpic == skyflatnum) + bothfloorssky = true; + + if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then + { + if ( +#ifdef POLYOBJECTS + !line->polyseg && +#endif + !line->sidedef->midtexture + && ((!frontsector->ffloors && !backsector->ffloors) + || (frontsector->tag == backsector->tag))) + return; // line is empty, don't even bother + + goto clippass; // treat like wide open window instead + } + // Closed door. #ifdef ESLOPE if (frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope) @@ -507,8 +527,7 @@ static void R_AddLine(seg_t *line) #undef SLOPEPARAMS // if both ceilings are skies, consider it always "open" // same for floors - if ((backsector->ceilingpic != skyflatnum || frontsector->ceilingpic != skyflatnum) - && (backsector->floorpic != skyflatnum || frontsector->floorpic != skyflatnum)) + if (!bothceilingssky && !bothfloorssky) { if ((backc1 <= frontf1 && backc2 <= frontf2) || (backf1 >= frontc1 && backf2 >= frontc2)) @@ -526,19 +545,19 @@ static void R_AddLine(seg_t *line) } // Window. - if (backc1 != frontc1 || backc2 != frontc2 - || backf1 != frontf1 || backf2 != frontf2) - { - goto clippass; - } + if (!bothceilingssky) // ceilings are always the "same" when sky + if (backc1 != frontc1 || backc2 != frontc2) + goto clippass; + if (!bothfloorssky) // floors are always the "same" when sky + if (backf1 != frontf1 || backf2 != frontf2) + goto clippass; } else #endif { // if both ceilings are skies, consider it always "open" // same for floors - if ((backsector->ceilingpic != skyflatnum || frontsector->ceilingpic != skyflatnum) - && (backsector->floorpic != skyflatnum || frontsector->floorpic != skyflatnum)) + if (!bothceilingssky && !bothfloorssky) { if (backsector->ceilingheight <= frontsector->floorheight || backsector->floorheight >= frontsector->ceilingheight) @@ -553,11 +572,12 @@ static void R_AddLine(seg_t *line) } // Window. - if (backsector->ceilingheight != frontsector->ceilingheight - || backsector->floorheight != frontsector->floorheight) - { - goto clippass; - } + if (!bothceilingssky) // ceilings are always the "same" when sky + if (backsector->ceilingheight != frontsector->ceilingheight) + goto clippass; + if (!bothfloorssky) // floors are always the "same" when sky + if (backsector->floorheight != frontsector->floorheight) + goto clippass; } // Reject empty lines used for triggers and special events. diff --git a/src/r_segs.c b/src/r_segs.c index ff3a956ad..5395f414a 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1321,6 +1321,18 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) #undef CLAMPMIN } +// R_ExpandPlaneY +// +// A simple function to modify a vsplane's top and bottom for a particular column +// Sort of like R_ExpandPlane in r_plane.c, except this is vertical expansion +static inline void R_ExpandPlaneY(visplane_t *pl, INT32 x, INT16 top, INT16 bottom) +{ + // Expand the plane, don't shrink it! + // note: top and bottom default to 0xFFFF and 0x0000 respectively, which is totally compatible with this + if (pl->top[x] > top) pl->top[x] = top; + if (pl->bottom[x] < bottom) pl->bottom[x] = bottom; +} + // // R_RenderSegLoop // Draws zero, one, or two textures (and possibly a masked @@ -1344,7 +1356,6 @@ UINT32 nombre = 100000; #endif //profile stuff --------------------------------------------------------- - static void R_RenderSegLoop (void) { angle_t angle; @@ -1374,13 +1385,19 @@ static void R_RenderSegLoop (void) if (markceiling) { +#if 0 + bottom = yl-1; + + if (bottom >= floorclip[rw_x]) + bottom = floorclip[rw_x]-1; + + if (top <= bottom) +#else bottom = yl > floorclip[rw_x] ? floorclip[rw_x] : yl; - if (top <= --bottom) - { - ceilingplane->top[rw_x] = (INT16)top; - ceilingplane->bottom[rw_x] = (INT16)bottom; - } + if (top <= --bottom && ceilingplane) +#endif + R_ExpandPlaneY(ceilingplane, rw_x, top, bottom); } @@ -1396,10 +1413,7 @@ static void R_RenderSegLoop (void) top = yh < ceilingclip[rw_x] ? ceilingclip[rw_x] : yh; if (++top <= bottom && floorplane) - { - floorplane->top[rw_x] = (INT16)top; - floorplane->bottom[rw_x] = (INT16)bottom; - } + R_ExpandPlaneY(floorplane, rw_x, top, bottom); } if (numffloors) @@ -1413,15 +1427,6 @@ static void R_RenderSegLoop (void) #ifdef POLYOBJECTS_PLANES if (ffloor[i].polyobj && (!curline->polyseg || ffloor[i].polyobj != curline->polyseg)) continue; -/* - // FIXME hack to fix planes disappearing when a seg goes behind the camera. This NEEDS to be changed to be done properly. -Red - if (curline->polyseg) { - if (ffloor[i].plane->minx > rw_x) - ffloor[i].plane->minx = rw_x; - else if (ffloor[i].plane->maxx < rw_x) - ffloor[i].plane->maxx = rw_x; - } -*/ #endif if (ffloor[i].height < viewz)