diff --git a/src/swrenderer/line/r_farclip_line.cpp b/src/swrenderer/line/r_farclip_line.cpp index f000744c25..5b55e654f4 100644 --- a/src/swrenderer/line/r_farclip_line.cpp +++ b/src/swrenderer/line/r_farclip_line.cpp @@ -65,13 +65,14 @@ namespace swrenderer Thread = thread; } - void FarClipLine::Render(seg_t *line, subsector_t *subsector, VisiblePlane *linefloorplane, VisiblePlane *lineceilingplane) + void FarClipLine::Render(seg_t *line, subsector_t *subsector, VisiblePlane *linefloorplane, VisiblePlane *lineceilingplane, Fake3DOpaque opaque3dfloor) { mSubsector = subsector; mFrontSector = mSubsector->sector; mLineSegment = line; mFloorPlane = linefloorplane; mCeilingPlane = lineceilingplane; + m3DFloor = opaque3dfloor; DVector2 pt1 = line->v1->fPos() - Thread->Viewport->viewpoint.Pos; DVector2 pt2 = line->v2->fPos() - Thread->Viewport->viewpoint.Pos; @@ -153,7 +154,7 @@ namespace swrenderer for (int x = x1; x < x2; ++x) { - short top = (clip3d->fakeFloor && clip3d->fake3D & FAKE3D_FAKECEILING) ? clip3d->fakeFloor->ceilingclip[x] : ceilingclip[x]; + short top = (clip3d->fakeFloor && m3DFloor.type == Fake3DOpaque::FakeCeiling) ? clip3d->fakeFloor->ceilingclip[x] : ceilingclip[x]; short bottom = MIN(walltop.ScreenY[x], floorclip[x]); if (top < bottom) { @@ -177,7 +178,7 @@ namespace swrenderer for (int x = x1; x < x2; ++x) { short top = MAX(wallbottom.ScreenY[x], ceilingclip[x]); - short bottom = (clip3d->fakeFloor && clip3d->fake3D & FAKE3D_FAKEFLOOR) ? clip3d->fakeFloor->floorclip[x] : floorclip[x]; + short bottom = (clip3d->fakeFloor && m3DFloor.type == Fake3DOpaque::FakeFloor) ? clip3d->fakeFloor->floorclip[x] : floorclip[x]; if (top < bottom) { assert(bottom <= viewheight); diff --git a/src/swrenderer/line/r_farclip_line.h b/src/swrenderer/line/r_farclip_line.h index c450a63836..05cba472d2 100644 --- a/src/swrenderer/line/r_farclip_line.h +++ b/src/swrenderer/line/r_farclip_line.h @@ -28,7 +28,7 @@ namespace swrenderer { public: FarClipLine(RenderThread *thread); - void Render(seg_t *line, subsector_t *subsector, VisiblePlane *linefloorplane, VisiblePlane *lineceilingplane); + void Render(seg_t *line, subsector_t *subsector, VisiblePlane *linefloorplane, VisiblePlane *lineceilingplane, Fake3DOpaque opaque3dfloor); RenderThread *Thread = nullptr; @@ -44,6 +44,7 @@ namespace swrenderer seg_t *mLineSegment; VisiblePlane *mFloorPlane; VisiblePlane *mCeilingPlane; + Fake3DOpaque m3DFloor; double mFrontCeilingZ1; double mFrontCeilingZ2; diff --git a/src/swrenderer/line/r_line.cpp b/src/swrenderer/line/r_line.cpp index 1f68727b11..b2c1fee72d 100644 --- a/src/swrenderer/line/r_line.cpp +++ b/src/swrenderer/line/r_line.cpp @@ -71,7 +71,7 @@ namespace swrenderer Thread = thread; } - void SWRenderLine::Render(seg_t *line, subsector_t *subsector, sector_t *sector, sector_t *fakebacksector, VisiblePlane *linefloorplane, VisiblePlane *lineceilingplane, bool infog, FDynamicColormap *colormap) + void SWRenderLine::Render(seg_t *line, subsector_t *subsector, sector_t *sector, sector_t *fakebacksector, VisiblePlane *linefloorplane, VisiblePlane *lineceilingplane, bool infog, FDynamicColormap *colormap, Fake3DOpaque opaque3dfloor) { mSubsector = subsector; mFrontSector = sector; @@ -81,6 +81,7 @@ namespace swrenderer foggy = infog; basecolormap = colormap; mLineSegment = line; + m3DFloor = opaque3dfloor; DVector2 pt1 = line->v1->fPos() - Thread->Viewport->viewpoint.Pos; DVector2 pt2 = line->v2->fPos() - Thread->Viewport->viewpoint.Pos; @@ -133,7 +134,7 @@ namespace swrenderer Clip3DFloors *clip3d = Thread->Clip3D.get(); - if (!(clip3d->fake3D & FAKE3D_FAKEBACK)) + if (m3DFloor.type != Fake3DOpaque::FakeBack) { mBackSector = line->backsector; } @@ -141,7 +142,7 @@ namespace swrenderer if (mBackSector) { // kg3D - its fake, no transfer_heights - if (!(clip3d->fake3D & FAKE3D_FAKEBACK)) + if (m3DFloor.type != Fake3DOpaque::FakeBack) { // killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water mBackSector = Thread->OpaquePass->FakeFlat(mBackSector, &tempsec, nullptr, nullptr, mLineSegment, WallC.sx1, WallC.sx2, mFrontCeilingZ1, mFrontCeilingZ2); } @@ -151,15 +152,15 @@ namespace swrenderer mBackCeilingZ2 = mBackSector->ceilingplane.ZatPoint(line->v2); mBackFloorZ2 = mBackSector->floorplane.ZatPoint(line->v2); - if (clip3d->fake3D & FAKE3D_FAKEBACK) + if (m3DFloor.type == Fake3DOpaque::FakeBack) { if (mFrontFloorZ1 >= mBackFloorZ1 && mFrontFloorZ2 >= mBackFloorZ2) { - clip3d->fake3D |= FAKE3D_CLIPBOTFRONT; + m3DFloor.clipBotFront = true; } if (mFrontCeilingZ1 <= mBackCeilingZ1 && mFrontCeilingZ2 <= mBackCeilingZ2) { - clip3d->fake3D |= FAKE3D_CLIPTOPFRONT; + m3DFloor.clipTopFront = true; } } } @@ -325,7 +326,7 @@ namespace swrenderer // 3D floors code abuses the line render code to update plane clipping // lists but doesn't actually draw anything. - bool onlyUpdatePlaneClip = (clip3d->fake3D & FAKE3D_FAKEMASK) ? true : false; + bool onlyUpdatePlaneClip = (m3DFloor.type != Fake3DOpaque::Normal); if (!onlyUpdatePlaneClip) Thread->DrawSegments->Push(draw_segment); @@ -516,9 +517,9 @@ namespace swrenderer MarkFloorPlane(start, stop); Mark3DFloors(start, stop); - if (clip3d->fake3D & FAKE3D_FAKEMASK) + if (m3DFloor.type != Fake3DOpaque::Normal) { - return (clip3d->fake3D & FAKE3D_FAKEMASK) == 0; + return false; } MarkOpaquePassClip(start, stop); @@ -557,7 +558,7 @@ namespace swrenderer Thread->Portal->AddLinePortal(mLineSegment->linedef, draw_segment->x1, draw_segment->x2, draw_segment->sprtopclip, draw_segment->sprbottomclip); } - return (clip3d->fake3D & FAKE3D_FAKEMASK) == 0; + return m3DFloor.type == Fake3DOpaque::Normal; } bool SWRenderLine::ShouldMarkFloor() const @@ -1015,7 +1016,7 @@ namespace swrenderer for (int x = x1; x < x2; ++x) { - short top = (clip3d->fakeFloor && clip3d->fake3D & FAKE3D_FAKECEILING) ? clip3d->fakeFloor->ceilingclip[x] : ceilingclip[x]; + short top = (clip3d->fakeFloor && m3DFloor.type == Fake3DOpaque::FakeCeiling) ? clip3d->fakeFloor->ceilingclip[x] : ceilingclip[x]; short bottom = MIN(walltop.ScreenY[x], floorclip[x]); if (top < bottom) { @@ -1039,7 +1040,7 @@ namespace swrenderer for (int x = x1; x < x2; ++x) { short top = MAX(wallbottom.ScreenY[x], ceilingclip[x]); - short bottom = (clip3d->fakeFloor && clip3d->fake3D & FAKE3D_FAKEFLOOR) ? clip3d->fakeFloor->floorclip[x] : floorclip[x]; + short bottom = (clip3d->fakeFloor && m3DFloor.type == Fake3DOpaque::FakeFloor) ? clip3d->fakeFloor->floorclip[x] : floorclip[x]; if (top < bottom) { assert(bottom <= viewheight); @@ -1055,12 +1056,12 @@ namespace swrenderer Clip3DFloors *clip3d = Thread->Clip3D.get(); // kg3D - fake planes clipping - if (clip3d->fake3D & FAKE3D_FAKEBACK) + if (m3DFloor.type == Fake3DOpaque::FakeBack) { auto ceilingclip = Thread->OpaquePass->ceilingclip; auto floorclip = Thread->OpaquePass->floorclip; - if (clip3d->fake3D & FAKE3D_CLIPBOTFRONT) + if (m3DFloor.clipBotFront) { memcpy(clip3d->fakeFloor->floorclip + x1, wallbottom.ScreenY + x1, (x2 - x1) * sizeof(short)); } @@ -1072,7 +1073,7 @@ namespace swrenderer } memcpy(clip3d->fakeFloor->floorclip + x1, walllower.ScreenY + x1, (x2 - x1) * sizeof(short)); } - if (clip3d->fake3D & FAKE3D_CLIPTOPFRONT) + if (m3DFloor.clipTopFront) { memcpy(clip3d->fakeFloor->ceilingclip + x1, walltop.ScreenY + x1, (x2 - x1) * sizeof(short)); } diff --git a/src/swrenderer/line/r_line.h b/src/swrenderer/line/r_line.h index 1462410e58..a76f4dc7c4 100644 --- a/src/swrenderer/line/r_line.h +++ b/src/swrenderer/line/r_line.h @@ -25,6 +25,7 @@ #include "vectors.h" #include "r_wallsetup.h" #include "swrenderer/segments/r_clipsegment.h" +#include "swrenderer/scene/r_3dfloors.h" struct seg_t; struct subsector_t; @@ -71,7 +72,7 @@ namespace swrenderer { public: SWRenderLine(RenderThread *thread); - void Render(seg_t *line, subsector_t *subsector, sector_t *sector, sector_t *fakebacksector, VisiblePlane *floorplane, VisiblePlane *ceilingplane, bool foggy, FDynamicColormap *basecolormap); + void Render(seg_t *line, subsector_t *subsector, sector_t *sector, sector_t *fakebacksector, VisiblePlane *floorplane, VisiblePlane *ceilingplane, bool foggy, FDynamicColormap *basecolormap, Fake3DOpaque fake3DOpaque); RenderThread *Thread = nullptr; @@ -109,6 +110,7 @@ namespace swrenderer VisiblePlane *mFloorPlane; VisiblePlane *mCeilingPlane; seg_t *mLineSegment; + Fake3DOpaque m3DFloor; double mBackCeilingZ1; double mBackCeilingZ2; diff --git a/src/swrenderer/line/r_renderdrawsegment.cpp b/src/swrenderer/line/r_renderdrawsegment.cpp index e00b08f5f3..df6c8f7a1b 100644 --- a/src/swrenderer/line/r_renderdrawsegment.cpp +++ b/src/swrenderer/line/r_renderdrawsegment.cpp @@ -63,11 +63,12 @@ namespace swrenderer Thread = thread; } - void RenderDrawSegment::Render(DrawSegment *ds, int x1, int x2) + void RenderDrawSegment::Render(DrawSegment *ds, int x1, int x2, Fake3DTranslucent clip3DFloor) { auto viewport = Thread->Viewport.get(); curline = ds->curline; + m3DFloor = clip3DFloor; float alpha = (float)MIN(curline->linedef->alpha, 1.); bool additive = (curline->linedef->flags & ML_ADDTRANS) != 0; @@ -102,9 +103,9 @@ namespace swrenderer Clip3DFloors *clip3d = Thread->Clip3D.get(); - if (!(clip3d->fake3D & FAKE3D_CLIPTOP)) + if (!(m3DFloor.clipTop)) { - clip3d->sclipTop = sec->ceilingplane.ZatPoint(Thread->Viewport->viewpoint.Pos); + m3DFloor.sclipTop = sec->ceilingplane.ZatPoint(Thread->Viewport->viewpoint.Pos); } CameraLight *cameraLight = CameraLight::Instance(); @@ -112,7 +113,7 @@ namespace swrenderer { for (int i = frontsector->e->XFloor.lightlist.Size() - 1; i >= 0; i--) { - if (clip3d->sclipTop <= frontsector->e->XFloor.lightlist[i].plane.Zat0()) + if (m3DFloor.sclipTop <= frontsector->e->XFloor.lightlist[i].plane.Zat0()) { lightlist_t *lit = &frontsector->e->XFloor.lightlist[i]; basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); @@ -252,11 +253,11 @@ namespace swrenderer return false; } - if ((clip3d->fake3D & FAKE3D_CLIPBOTTOM) && textop < clip3d->sclipBottom - Thread->Viewport->viewpoint.Pos.Z) + if (m3DFloor.clipBottom && textop < m3DFloor.sclipBottom - Thread->Viewport->viewpoint.Pos.Z) { return true; } - if ((clip3d->fake3D & FAKE3D_CLIPTOP) && textop - texheight > clip3d->sclipTop - Thread->Viewport->viewpoint.Pos.Z) + if (m3DFloor.clipTop && textop - texheight > m3DFloor.sclipTop - Thread->Viewport->viewpoint.Pos.Z) { return true; } @@ -266,17 +267,17 @@ namespace swrenderer WallC.sx1 = ds->sx1; WallC.sx2 = ds->sx2; - if (clip3d->fake3D & FAKE3D_CLIPTOP) + if (m3DFloor.clipTop) { - wallupper.Project(Thread->Viewport.get(), textop < clip3d->sclipTop - Thread->Viewport->viewpoint.Pos.Z ? textop : clip3d->sclipTop - Thread->Viewport->viewpoint.Pos.Z, &WallC); + wallupper.Project(Thread->Viewport.get(), textop < m3DFloor.sclipTop - Thread->Viewport->viewpoint.Pos.Z ? textop : m3DFloor.sclipTop - Thread->Viewport->viewpoint.Pos.Z, &WallC); } else { wallupper.Project(Thread->Viewport.get(), textop, &WallC); } - if (clip3d->fake3D & FAKE3D_CLIPBOTTOM) + if (m3DFloor.clipBottom) { - walllower.Project(Thread->Viewport.get(), textop - texheight > clip3d->sclipBottom - Thread->Viewport->viewpoint.Pos.Z ? textop - texheight : clip3d->sclipBottom - Thread->Viewport->viewpoint.Pos.Z, &WallC); + walllower.Project(Thread->Viewport.get(), textop - texheight > m3DFloor.sclipBottom - Thread->Viewport->viewpoint.Pos.Z ? textop - texheight : m3DFloor.sclipBottom - Thread->Viewport->viewpoint.Pos.Z, &WallC); } else { @@ -366,9 +367,9 @@ namespace swrenderer } } - if (clip3d->fake3D & FAKE3D_CLIPTOP) + if (m3DFloor.clipTop) { - wallupper.Project(Thread->Viewport.get(), clip3d->sclipTop - Thread->Viewport->viewpoint.Pos.Z, &WallC); + wallupper.Project(Thread->Viewport.get(), m3DFloor.sclipTop - Thread->Viewport->viewpoint.Pos.Z, &WallC); for (int i = x1; i < x2; i++) { if (wallupper.ScreenY[i] < mceilingclip[i]) @@ -376,9 +377,9 @@ namespace swrenderer } mceilingclip = wallupper.ScreenY; } - if (clip3d->fake3D & FAKE3D_CLIPBOTTOM) + if (m3DFloor.clipBottom) { - walllower.Project(Thread->Viewport.get(), clip3d->sclipBottom - Thread->Viewport->viewpoint.Pos.Z, &WallC); + walllower.Project(Thread->Viewport.get(), m3DFloor.sclipBottom - Thread->Viewport->viewpoint.Pos.Z, &WallC); for (int i = x1; i < x2; i++) { if (walllower.ScreenY[i] > mfloorclip[i]) @@ -484,8 +485,8 @@ namespace swrenderer WallT = ds->tmapvals; Clip3DFloors *clip3d = Thread->Clip3D.get(); - wallupper.Project(Thread->Viewport.get(), clip3d->sclipTop - Thread->Viewport->viewpoint.Pos.Z, &WallC); - walllower.Project(Thread->Viewport.get(), clip3d->sclipBottom - Thread->Viewport->viewpoint.Pos.Z, &WallC); + wallupper.Project(Thread->Viewport.get(), m3DFloor.sclipTop - Thread->Viewport->viewpoint.Pos.Z, &WallC); + walllower.Project(Thread->Viewport.get(), m3DFloor.sclipBottom - Thread->Viewport->viewpoint.Pos.Z, &WallC); for (i = x1; i < x2; i++) { @@ -542,14 +543,14 @@ namespace swrenderer Clip3DFloors *clip3d = Thread->Clip3D.get(); // maybe fix clipheights - if (!(clip3d->fake3D & FAKE3D_CLIPBOTTOM)) clip3d->sclipBottom = floorHeight; - if (!(clip3d->fake3D & FAKE3D_CLIPTOP)) clip3d->sclipTop = ceilingHeight; + if (!m3DFloor.clipBottom) m3DFloor.sclipBottom = floorHeight; + if (!m3DFloor.clipTop) m3DFloor.sclipTop = ceilingHeight; // maybe not visible - if (clip3d->sclipBottom >= frontsector->CenterCeiling()) return; - if (clip3d->sclipTop <= frontsector->CenterFloor()) return; + if (m3DFloor.sclipBottom >= frontsector->CenterCeiling()) return; + if (m3DFloor.sclipTop <= frontsector->CenterFloor()) return; - if (clip3d->fake3D & FAKE3D_DOWN2UP) + if (m3DFloor.down2Up) { // bottom to viewz last = 0; for (i = backsector->e->XFloor.ffloors.Size() - 1; i >= 0; i--) @@ -560,7 +561,7 @@ namespace swrenderer // visible? passed = 0; if (!(rover->flags & FF_RENDERSIDES) || rover->top.plane->isSlope() || rover->bottom.plane->isSlope() || - rover->top.plane->Zat0() <= clip3d->sclipBottom || + rover->top.plane->Zat0() <= m3DFloor.sclipBottom || rover->bottom.plane->Zat0() >= ceilingHeight || rover->top.plane->Zat0() <= floorHeight) { @@ -575,7 +576,7 @@ namespace swrenderer } rw_pic = nullptr; - if (rover->bottom.plane->Zat0() >= clip3d->sclipTop || passed) + if (rover->bottom.plane->Zat0() >= m3DFloor.sclipTop || passed) { if (last) { @@ -597,8 +598,8 @@ namespace swrenderer if (fover->top.plane->isSlope() || fover->bottom.plane->isSlope()) continue; // visible? - if (fover->top.plane->Zat0() <= clip3d->sclipBottom) continue; // no - if (fover->bottom.plane->Zat0() >= clip3d->sclipTop) + if (fover->top.plane->Zat0() <= m3DFloor.sclipBottom) continue; // no + if (fover->bottom.plane->Zat0() >= m3DFloor.sclipTop) { // no, last possible fover = nullptr; break; @@ -650,8 +651,8 @@ namespace swrenderer if (fover->top.plane->isSlope() || fover->bottom.plane->isSlope()) continue; // visible? - if (fover->top.plane->Zat0() <= clip3d->sclipBottom) continue; // no - if (fover->bottom.plane->Zat0() >= clip3d->sclipTop) + if (fover->top.plane->Zat0() <= m3DFloor.sclipBottom) continue; // no + if (fover->bottom.plane->Zat0() >= m3DFloor.sclipTop) { // visible, last possible fover = nullptr; break; @@ -702,7 +703,7 @@ namespace swrenderer { for (j = backsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--) { - if (clip3d->sclipTop <= backsector->e->XFloor.lightlist[j].plane.Zat0()) + if (m3DFloor.sclipTop <= backsector->e->XFloor.lightlist[j].plane.Zat0()) { lightlist_t *lit = &backsector->e->XFloor.lightlist[j]; basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); @@ -716,7 +717,7 @@ namespace swrenderer { for (j = frontsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--) { - if (clip3d->sclipTop <= frontsector->e->XFloor.lightlist[j].plane.Zat0()) + if (m3DFloor.sclipTop <= frontsector->e->XFloor.lightlist[j].plane.Zat0()) { lightlist_t *lit = &frontsector->e->XFloor.lightlist[j]; basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); @@ -748,7 +749,7 @@ namespace swrenderer passed = 0; if (!(rover->flags & FF_RENDERSIDES) || rover->top.plane->isSlope() || rover->bottom.plane->isSlope() || - rover->bottom.plane->Zat0() >= clip3d->sclipTop || + rover->bottom.plane->Zat0() >= m3DFloor.sclipTop || rover->top.plane->Zat0() <= floorHeight || rover->bottom.plane->Zat0() >= ceilingHeight) { @@ -762,7 +763,7 @@ namespace swrenderer } } rw_pic = nullptr; - if (rover->top.plane->Zat0() <= clip3d->sclipBottom || passed) + if (rover->top.plane->Zat0() <= m3DFloor.sclipBottom || passed) { // maybe wall from inside rendering? fover = nullptr; for (j = 0; j < (int)frontsector->e->XFloor.ffloors.Size(); j++) @@ -779,8 +780,8 @@ namespace swrenderer if (fover->top.plane->isSlope() || fover->bottom.plane->isSlope()) continue; // visible? - if (fover->bottom.plane->Zat0() >= clip3d->sclipTop) continue; // no - if (fover->top.plane->Zat0() <= clip3d->sclipBottom) + if (fover->bottom.plane->Zat0() >= m3DFloor.sclipTop) continue; // no + if (fover->top.plane->Zat0() <= m3DFloor.sclipBottom) { // no, last possible fover = nullptr; break; @@ -831,8 +832,8 @@ namespace swrenderer if (fover->top.plane->isSlope() || fover->bottom.plane->isSlope()) continue; // visible? - if (fover->bottom.plane->Zat0() >= clip3d->sclipTop) continue; // no - if (fover->top.plane->Zat0() <= clip3d->sclipBottom) + if (fover->bottom.plane->Zat0() >= m3DFloor.sclipTop) continue; // no + if (fover->top.plane->Zat0() <= m3DFloor.sclipBottom) { // visible, last possible fover = nullptr; break; @@ -881,7 +882,7 @@ namespace swrenderer { for (j = backsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--) { - if (clip3d->sclipTop <= backsector->e->XFloor.lightlist[j].plane.Zat0()) + if (m3DFloor.sclipTop <= backsector->e->XFloor.lightlist[j].plane.Zat0()) { lightlist_t *lit = &backsector->e->XFloor.lightlist[j]; basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); @@ -895,7 +896,7 @@ namespace swrenderer { for (j = frontsector->e->XFloor.lightlist.Size() - 1; j >= 0; j--) { - if (clip3d->sclipTop <= frontsector->e->XFloor.lightlist[j].plane.Zat0()) + if (m3DFloor.sclipTop <= frontsector->e->XFloor.lightlist[j].plane.Zat0()) { lightlist_t *lit = &frontsector->e->XFloor.lightlist[j]; basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); @@ -952,13 +953,13 @@ namespace swrenderer bot = MIN(frontfz1, frontfz2); Clip3DFloors *clip3d = Thread->Clip3D.get(); - if (clip3d->fake3D & FAKE3D_CLIPTOP) + if (m3DFloor.clipTop) { - top = MIN(top, clip3d->sclipTop); + top = MIN(top, m3DFloor.sclipTop); } - if (clip3d->fake3D & FAKE3D_CLIPBOTTOM) + if (m3DFloor.clipBottom) { - bot = MAX(bot, clip3d->sclipBottom); + bot = MAX(bot, m3DFloor.sclipBottom); } } } diff --git a/src/swrenderer/line/r_renderdrawsegment.h b/src/swrenderer/line/r_renderdrawsegment.h index 05a4b68c07..f54ff6b1a9 100644 --- a/src/swrenderer/line/r_renderdrawsegment.h +++ b/src/swrenderer/line/r_renderdrawsegment.h @@ -32,7 +32,7 @@ namespace swrenderer { public: RenderDrawSegment(RenderThread *thread); - void Render(DrawSegment *ds, int x1, int x2); + void Render(DrawSegment *ds, int x1, int x2, Fake3DTranslucent clip3DFloor); RenderThread *Thread = nullptr; @@ -47,6 +47,7 @@ namespace swrenderer sector_t *backsector = nullptr; seg_t *curline = nullptr; + Fake3DTranslucent m3DFloor; FWallCoords WallC; FWallTmapVals WallT; diff --git a/src/swrenderer/plane/r_visibleplanelist.cpp b/src/swrenderer/plane/r_visibleplanelist.cpp index 7a4f5a57c9..561930cc27 100644 --- a/src/swrenderer/plane/r_visibleplanelist.cpp +++ b/src/swrenderer/plane/r_visibleplanelist.cpp @@ -99,7 +99,7 @@ namespace swrenderer } } - VisiblePlane *VisiblePlaneList::FindPlane(const secplane_t &height, FTextureID picnum, int lightlevel, double Alpha, bool additive, const FTransform &xxform, int sky, FSectorPortal *portal, FDynamicColormap *basecolormap) + VisiblePlane *VisiblePlaneList::FindPlane(const secplane_t &height, FTextureID picnum, int lightlevel, double Alpha, bool additive, const FTransform &xxform, int sky, FSectorPortal *portal, FDynamicColormap *basecolormap, Fake3DOpaque::Type fakeFloorType, fixed_t fakeAlpha) { secplane_t plane; VisiblePlane *check; @@ -140,8 +140,7 @@ namespace swrenderer // kg3D - hack, store alpha in sky // i know there is ->alpha, but this also allows to identify fake plane // and ->alpha is for stacked sectors - Clip3DFloors *clip3d = Thread->Clip3D.get(); - if (clip3d->fake3D & (FAKE3D_FAKEFLOOR | FAKE3D_FAKECEILING)) sky = 0x80000000 | clip3d->fakeAlpha; + if (fakeFloorType == Fake3DOpaque::FakeFloor || fakeFloorType == Fake3DOpaque::FakeCeiling) sky = 0x80000000 | fakeAlpha; else sky = 0; // not skyflatnum so it can't be a sky portal = nullptr; alpha = OPAQUE; diff --git a/src/swrenderer/plane/r_visibleplanelist.h b/src/swrenderer/plane/r_visibleplanelist.h index c44c860eb7..a49479e6c6 100644 --- a/src/swrenderer/plane/r_visibleplanelist.h +++ b/src/swrenderer/plane/r_visibleplanelist.h @@ -40,7 +40,7 @@ namespace swrenderer void Clear(); void ClearKeepFakePlanes(); - VisiblePlane *FindPlane(const secplane_t &height, FTextureID picnum, int lightlevel, double Alpha, bool additive, const FTransform &xxform, int sky, FSectorPortal *portal, FDynamicColormap *basecolormap); + VisiblePlane *FindPlane(const secplane_t &height, FTextureID picnum, int lightlevel, double Alpha, bool additive, const FTransform &xxform, int sky, FSectorPortal *portal, FDynamicColormap *basecolormap, Fake3DOpaque::Type fakeFloorType, fixed_t fakeAlpha); VisiblePlane *GetRange(VisiblePlane *pl, int start, int stop); bool HasPortalPlanes() const; diff --git a/src/swrenderer/scene/r_3dfloors.cpp b/src/swrenderer/scene/r_3dfloors.cpp index 111cbf5041..d468c9611e 100644 --- a/src/swrenderer/scene/r_3dfloors.cpp +++ b/src/swrenderer/scene/r_3dfloors.cpp @@ -67,7 +67,6 @@ namespace swrenderer FakeFloors.clear(); fakeActive = false; - fake3D = 0; while (CurrentSkybox) { DeleteHeights(); diff --git a/src/swrenderer/scene/r_3dfloors.h b/src/swrenderer/scene/r_3dfloors.h index e1f52d1669..0237ca95eb 100644 --- a/src/swrenderer/scene/r_3dfloors.h +++ b/src/swrenderer/scene/r_3dfloors.h @@ -33,23 +33,33 @@ namespace swrenderer ClipStack *next; }; - enum Fake3DOpaque + // BSP stage + struct Fake3DOpaque { - // BSP stage: - FAKE3D_FAKEFLOOR = 1, // fake floor, mark seg as FAKE - FAKE3D_FAKECEILING = 2, // fake ceiling, mark seg as FAKE - FAKE3D_FAKEBACK = 4, // RenderLine with fake backsector, mark seg as FAKE - FAKE3D_FAKEMASK = 7, - FAKE3D_CLIPBOTFRONT = 8, // use front sector clipping info (bottom) - FAKE3D_CLIPTOPFRONT = 16, // use front sector clipping info (top) + enum Type + { + Normal, // Not a 3D floor + FakeFloor, // fake floor, mark seg as FAKE + FakeCeiling, // fake ceiling, mark seg as FAKE + FakeBack // RenderLine with fake backsector, mark seg as FAKE + }; + Type type = Normal; + + bool clipBotFront = false; // use front sector clipping info (bottom) + bool clipTopFront = false; // use front sector clipping info (top) + + Fake3DOpaque() { } + Fake3DOpaque(Type type) : type(type) { } }; - enum Fake3DTranslucent + // Drawing stage + struct Fake3DTranslucent { - // sorting stage: - FAKE3D_CLIPBOTTOM = 1, // clip bottom - FAKE3D_CLIPTOP = 2, // clip top - FAKE3D_DOWN2UP = 8, // rendering from down to up (floors) + bool clipBottom = false; + bool clipTop = false; + bool down2Up = false; // rendering from down to up (floors) + double sclipBottom = 0; + double sclipTop = 0; }; class FakeFloorClip @@ -81,13 +91,8 @@ namespace swrenderer RenderThread *Thread = nullptr; - int fake3D = 0; - FakeFloorClip *fakeFloor = nullptr; - fixed_t fakeAlpha = 0; bool fakeActive = false; - double sclipBottom = 0; - double sclipTop = 0; HeightLevel *height_top = nullptr; HeightLevel *height_cur = nullptr; int CurrentSkybox = 0; diff --git a/src/swrenderer/scene/r_opaque_pass.cpp b/src/swrenderer/scene/r_opaque_pass.cpp index f18cdc2ec3..4b0c6f1faa 100644 --- a/src/swrenderer/scene/r_opaque_pass.cpp +++ b/src/swrenderer/scene/r_opaque_pass.cpp @@ -450,7 +450,7 @@ namespace swrenderer } // kg3D - add fake segs, never rendered - void RenderOpaquePass::FakeDrawLoop(subsector_t *sub, VisiblePlane *floorplane, VisiblePlane *ceilingplane, bool foggy, FDynamicColormap *basecolormap) + void RenderOpaquePass::FakeDrawLoop(subsector_t *sub, VisiblePlane *floorplane, VisiblePlane *ceilingplane, bool foggy, FDynamicColormap *basecolormap, Fake3DOpaque opaque3dfloor) { int count; seg_t* line; @@ -462,7 +462,7 @@ namespace swrenderer { if ((line->sidedef) && !(line->sidedef->Flags & WALLF_POLYOBJ)) { - renderline.Render(line, InSubsector, frontsector, nullptr, floorplane, ceilingplane, foggy, basecolormap); + renderline.Render(line, InSubsector, frontsector, nullptr, floorplane, ceilingplane, foggy, basecolormap, opaque3dfloor); } line++; } @@ -565,7 +565,9 @@ namespace swrenderer frontsector->planes[sector_t::ceiling].xform, frontsector->sky, portal, - basecolormap + basecolormap, + Fake3DOpaque::Normal, + 0 ) : nullptr; if (ceilingplane) @@ -606,7 +608,9 @@ namespace swrenderer frontsector->planes[sector_t::floor].xform, frontsector->sky, portal, - basecolormap + basecolormap, + Fake3DOpaque::Normal, + 0 ) : nullptr; if (floorplane) @@ -634,7 +638,7 @@ namespace swrenderer if (!(clip3d->fakeFloor->fakeFloor->flags & FF_RENDERPLANES)) continue; if (clip3d->fakeFloor->fakeFloor->alpha == 0) continue; if (clip3d->fakeFloor->fakeFloor->flags & FF_THISINSIDE && clip3d->fakeFloor->fakeFloor->flags & FF_INVERTSECTOR) continue; - clip3d->fakeAlpha = MIN(Scale(clip3d->fakeFloor->fakeFloor->alpha, OPAQUE, 255), OPAQUE); + fixed_t fakeAlpha = MIN(Scale(clip3d->fakeFloor->fakeFloor->alpha, OPAQUE, 255), OPAQUE); if (clip3d->fakeFloor->validcount != validcount) { clip3d->fakeFloor->validcount = validcount; @@ -644,7 +648,6 @@ namespace swrenderer if (fakeHeight < Thread->Viewport->viewpoint.Pos.Z && fakeHeight > frontsector->floorplane.ZatPoint(frontsector->centerspot)) { - clip3d->fake3D = FAKE3D_FAKEFLOOR; tempsec = *clip3d->fakeFloor->fakeFloor->model; tempsec.floorplane = *clip3d->fakeFloor->fakeFloor->top.plane; tempsec.ceilingplane = *clip3d->fakeFloor->fakeFloor->bottom.plane; @@ -672,13 +675,14 @@ namespace swrenderer frontsector->planes[position].xform, frontsector->sky, nullptr, - basecolormap); + basecolormap, + Fake3DOpaque::FakeFloor, + fakeAlpha); if (floorplane) floorplane->AddLights(Thread, frontsector->lighthead); - FakeDrawLoop(sub, floorplane, ceilingplane, foggy, basecolormap); - clip3d->fake3D = 0; + FakeDrawLoop(sub, floorplane, ceilingplane, foggy, basecolormap, Fake3DOpaque::FakeFloor); frontsector = sub->sector; } } @@ -696,7 +700,7 @@ namespace swrenderer if (!(clip3d->fakeFloor->fakeFloor->flags & FF_RENDERPLANES)) continue; if (clip3d->fakeFloor->fakeFloor->alpha == 0) continue; if (!(clip3d->fakeFloor->fakeFloor->flags & FF_THISINSIDE) && (clip3d->fakeFloor->fakeFloor->flags & (FF_SWIMMABLE | FF_INVERTSECTOR)) == (FF_SWIMMABLE | FF_INVERTSECTOR)) continue; - clip3d->fakeAlpha = MIN(Scale(clip3d->fakeFloor->fakeFloor->alpha, OPAQUE, 255), OPAQUE); + fixed_t fakeAlpha = MIN(Scale(clip3d->fakeFloor->fakeFloor->alpha, OPAQUE, 255), OPAQUE); if (clip3d->fakeFloor->validcount != validcount) { @@ -707,7 +711,6 @@ namespace swrenderer if (fakeHeight > Thread->Viewport->viewpoint.Pos.Z && fakeHeight < frontsector->ceilingplane.ZatPoint(frontsector->centerspot)) { - clip3d->fake3D = FAKE3D_FAKECEILING; tempsec = *clip3d->fakeFloor->fakeFloor->model; tempsec.floorplane = *clip3d->fakeFloor->fakeFloor->top.plane; tempsec.ceilingplane = *clip3d->fakeFloor->fakeFloor->bottom.plane; @@ -738,13 +741,14 @@ namespace swrenderer frontsector->planes[position].xform, frontsector->sky, nullptr, - basecolormap); + basecolormap, + Fake3DOpaque::FakeCeiling, + fakeAlpha); if (ceilingplane) ceilingplane->AddLights(Thread, frontsector->lighthead); - FakeDrawLoop(sub, floorplane, ceilingplane, foggy, basecolormap); - clip3d->fake3D = 0; + FakeDrawLoop(sub, floorplane, ceilingplane, foggy, basecolormap, Fake3DOpaque::FakeCeiling); frontsector = sub->sector; } } @@ -787,7 +791,7 @@ namespace swrenderer if (dist1 > line_distance_cull && dist2 > line_distance_cull) { FarClipLine farclip(Thread); - farclip.Render(line, InSubsector, floorplane, ceilingplane); + farclip.Render(line, InSubsector, floorplane, ceilingplane, Fake3DOpaque::Normal); } else if (!outersubsector || line->sidedef == nullptr || !(line->sidedef->Flags & WALLF_POLYOBJ)) { @@ -805,7 +809,7 @@ namespace swrenderer if (!(clip3d->fakeFloor->fakeFloor->flags & FF_EXISTS)) continue; if (!(clip3d->fakeFloor->fakeFloor->flags & FF_RENDERPLANES)) continue; if (!clip3d->fakeFloor->fakeFloor->model) continue; - clip3d->fake3D = FAKE3D_FAKEBACK; + Fake3DOpaque opaque3dfloor = Fake3DOpaque::FakeBack; tempsec = *clip3d->fakeFloor->fakeFloor->model; tempsec.floorplane = *clip3d->fakeFloor->fakeFloor->top.plane; tempsec.ceilingplane = *clip3d->fakeFloor->fakeFloor->bottom.plane; @@ -814,14 +818,13 @@ namespace swrenderer clip3d->fakeFloor->validcount = validcount; clip3d->NewClip(); } - renderline.Render(line, InSubsector, frontsector, &tempsec, floorplane, ceilingplane, foggy, basecolormap); // fake + renderline.Render(line, InSubsector, frontsector, &tempsec, floorplane, ceilingplane, foggy, basecolormap, opaque3dfloor); // fake } clip3d->fakeFloor = nullptr; - clip3d->fake3D = 0; floorplane = backupfp; ceilingplane = backupcp; } - renderline.Render(line, InSubsector, frontsector, nullptr, floorplane, ceilingplane, foggy, basecolormap); // now real + renderline.Render(line, InSubsector, frontsector, nullptr, floorplane, ceilingplane, foggy, basecolormap, Fake3DOpaque::Normal); // now real } line++; } diff --git a/src/swrenderer/scene/r_opaque_pass.h b/src/swrenderer/scene/r_opaque_pass.h index c71dd3985f..e17a6109a1 100644 --- a/src/swrenderer/scene/r_opaque_pass.h +++ b/src/swrenderer/scene/r_opaque_pass.h @@ -82,7 +82,7 @@ namespace swrenderer bool CheckBBox(float *bspcoord); void AddPolyobjs(subsector_t *sub); - void FakeDrawLoop(subsector_t *sub, VisiblePlane *floorplane, VisiblePlane *ceilingplane, bool foggy, FDynamicColormap *basecolormap); + void FakeDrawLoop(subsector_t *sub, VisiblePlane *floorplane, VisiblePlane *ceilingplane, bool foggy, FDynamicColormap *basecolormap, Fake3DOpaque opaque3dfloor); void AddSprites(sector_t *sec, int lightlevel, WaterFakeSide fakeside, bool foggy, FDynamicColormap *basecolormap); diff --git a/src/swrenderer/scene/r_translucent_pass.cpp b/src/swrenderer/scene/r_translucent_pass.cpp index 76677a6a0a..d56fde2fd6 100644 --- a/src/swrenderer/scene/r_translucent_pass.cpp +++ b/src/swrenderer/scene/r_translucent_pass.cpp @@ -131,7 +131,7 @@ namespace swrenderer return false; } - void RenderTranslucentPass::DrawMaskedSingle(bool renew) + void RenderTranslucentPass::DrawMaskedSingle(bool renew, Fake3DTranslucent clip3DFloor) { RenderPortal *renderportal = Thread->Portal.get(); DrawSegmentList *drawseglist = Thread->DrawSegments.get(); @@ -143,7 +143,7 @@ namespace swrenderer if (sprite->IsCurrentPortalUniq(renderportal->CurrentPortalUniq)) { - sprite->Render(Thread); + sprite->Render(Thread, clip3DFloor); } } @@ -159,7 +159,7 @@ namespace swrenderer if (ds->maskedtexturecol || ds->bFogBoundary) { RenderDrawSegment renderer(Thread); - renderer.Render(ds, ds->x1, ds->x2); + renderer.Render(ds, ds->x1, ds->x2, clip3DFloor); if (renew && ds->bFogBoundary) // don't draw fogboundary again ds->bFogBoundary = false; @@ -184,48 +184,58 @@ namespace swrenderer Clip3DFloors *clip3d = Thread->Clip3D.get(); if (clip3d->height_top == nullptr) { // kg3D - no visible 3D floors, normal rendering - DrawMaskedSingle(false); + Fake3DTranslucent clip3DFloor; + DrawMaskedSingle(false, clip3DFloor); } else { // kg3D - correct sorting // ceilings for (HeightLevel *hl = clip3d->height_cur; hl != nullptr && hl->height >= Thread->Viewport->viewpoint.Pos.Z; hl = hl->prev) { + Fake3DTranslucent clip3DFloor; if (hl->next) { - clip3d->fake3D = FAKE3D_CLIPBOTTOM | FAKE3D_CLIPTOP; - clip3d->sclipTop = hl->next->height; + clip3DFloor.clipBottom = true; + clip3DFloor.clipTop = true; + clip3DFloor.sclipTop = hl->next->height; } else { - clip3d->fake3D = FAKE3D_CLIPBOTTOM; + clip3DFloor.clipBottom = true; } - clip3d->sclipBottom = hl->height; - DrawMaskedSingle(true); + clip3DFloor.sclipBottom = hl->height; + DrawMaskedSingle(true, clip3DFloor); Thread->PlaneList->RenderHeight(hl->height); } // floors - clip3d->fake3D = FAKE3D_DOWN2UP | FAKE3D_CLIPTOP; - clip3d->sclipTop = clip3d->height_top->height; - DrawMaskedSingle(true); + { + Fake3DTranslucent clip3DFloor; + clip3DFloor.clipTop = true; + clip3DFloor.down2Up = true; + clip3DFloor.sclipTop = clip3d->height_top->height; + DrawMaskedSingle(true, clip3DFloor); + } + for (HeightLevel *hl = clip3d->height_top; hl != nullptr && hl->height < Thread->Viewport->viewpoint.Pos.Z; hl = hl->next) { Thread->PlaneList->RenderHeight(hl->height); + Fake3DTranslucent clip3DFloor; if (hl->next) { - clip3d->fake3D = FAKE3D_DOWN2UP | FAKE3D_CLIPTOP | FAKE3D_CLIPBOTTOM; - clip3d->sclipTop = hl->next->height; + clip3DFloor.clipBottom = true; + clip3DFloor.clipTop = true; + clip3DFloor.down2Up = true; + clip3DFloor.sclipTop = hl->next->height; } else { - clip3d->fake3D = FAKE3D_DOWN2UP | FAKE3D_CLIPBOTTOM; + clip3DFloor.clipBottom = true; } - clip3d->sclipBottom = hl->height; - DrawMaskedSingle(true); + clip3DFloor.sclipBottom = hl->height; + DrawMaskedSingle(true, clip3DFloor); } clip3d->DeleteHeights(); - clip3d->fake3D = 0; } if (Thread->MainThread) diff --git a/src/swrenderer/scene/r_translucent_pass.h b/src/swrenderer/scene/r_translucent_pass.h index 47da285b54..5c28749a72 100644 --- a/src/swrenderer/scene/r_translucent_pass.h +++ b/src/swrenderer/scene/r_translucent_pass.h @@ -49,7 +49,7 @@ namespace swrenderer private: void CollectPortals(); - void DrawMaskedSingle(bool renew); + void DrawMaskedSingle(bool renew, Fake3DTranslucent clip3DFloor); TArray portaldrawsegs; }; diff --git a/src/swrenderer/things/r_model.cpp b/src/swrenderer/things/r_model.cpp index f86a7e3849..4b68db2194 100644 --- a/src/swrenderer/things/r_model.cpp +++ b/src/swrenderer/things/r_model.cpp @@ -64,7 +64,7 @@ namespace swrenderer this->idepth = idepth; } - void RenderModel::Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ) + void RenderModel::Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) { SWModelRenderer renderer(thread); renderer.RenderModel(x, y, z, smf, actor); diff --git a/src/swrenderer/things/r_model.h b/src/swrenderer/things/r_model.h index 94ca1d9097..3f6fd0e906 100644 --- a/src/swrenderer/things/r_model.h +++ b/src/swrenderer/things/r_model.h @@ -40,7 +40,7 @@ namespace swrenderer static void Project(RenderThread *thread, float x, float y, float z, FSpriteModelFrame *smf, AActor *actor); protected: - void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ) override; + void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) override; bool IsModel() const override { return true; } private: diff --git a/src/swrenderer/things/r_particle.cpp b/src/swrenderer/things/r_particle.cpp index ee791b56b3..0e167f7c4c 100644 --- a/src/swrenderer/things/r_particle.cpp +++ b/src/swrenderer/things/r_particle.cpp @@ -225,7 +225,7 @@ namespace swrenderer thread->SpriteList->Push(vis); } - void RenderParticle::Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ) + void RenderParticle::Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) { auto vis = this; @@ -239,7 +239,7 @@ namespace swrenderer if (ycount <= 0 || countbase <= 0) return; - DrawMaskedSegsBehindParticle(thread); + DrawMaskedSegsBehindParticle(thread, clip3DFloor); uint32_t fg = LightBgra::shade_pal_index_simple(color, LightBgra::calc_light_multiplier(LIGHTSCALE(0, vis->Light.ColormapNum << FRACBITS))); @@ -278,7 +278,7 @@ namespace swrenderer } } - void RenderParticle::DrawMaskedSegsBehindParticle(RenderThread *thread) + void RenderParticle::DrawMaskedSegsBehindParticle(RenderThread *thread, const Fake3DTranslucent &clip3DFloor) { // Draw any masked textures behind this particle so that when the // particle is drawn, it will be in front of them. @@ -297,7 +297,7 @@ namespace swrenderer if (ds->CurrentPortalUniq == CurrentPortalUniq) { RenderDrawSegment renderer(thread); - renderer.Render(ds, MAX(ds->x1, x1), MIN(ds->x2, x2)); + renderer.Render(ds, MAX(ds->x1, x1), MIN(ds->x2, x2), clip3DFloor); } } } diff --git a/src/swrenderer/things/r_particle.h b/src/swrenderer/things/r_particle.h index 84bd10aae3..79d10b7c5f 100644 --- a/src/swrenderer/things/r_particle.h +++ b/src/swrenderer/things/r_particle.h @@ -14,10 +14,10 @@ namespace swrenderer protected: bool IsParticle() const override { return true; } - void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ) override; + void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) override; private: - void DrawMaskedSegsBehindParticle(RenderThread *thread); + void DrawMaskedSegsBehindParticle(RenderThread *thread, const Fake3DTranslucent &clip3DFloor); fixed_t xscale = 0; fixed_t startfrac = 0; // horizontal position of x1 diff --git a/src/swrenderer/things/r_sprite.cpp b/src/swrenderer/things/r_sprite.cpp index b9ed668bc4..74a76a79f8 100644 --- a/src/swrenderer/things/r_sprite.cpp +++ b/src/swrenderer/things/r_sprite.cpp @@ -303,7 +303,7 @@ namespace swrenderer thread->SpriteList->Push(vis); } - void RenderSprite::Render(RenderThread *thread, short *mfloorclip, short *mceilingclip, int, int) + void RenderSprite::Render(RenderThread *thread, short *mfloorclip, short *mceilingclip, int, int, Fake3DTranslucent) { auto vis = this; diff --git a/src/swrenderer/things/r_sprite.h b/src/swrenderer/things/r_sprite.h index 55d504fc9a..8fe53080ec 100644 --- a/src/swrenderer/things/r_sprite.h +++ b/src/swrenderer/things/r_sprite.h @@ -10,7 +10,7 @@ namespace swrenderer static void Project(RenderThread *thread, AActor *thing, const DVector3 &pos, FTexture *tex, const DVector2 &spriteScale, int renderflags, WaterFakeSide fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector, int spriteshade, bool foggy, FDynamicColormap *basecolormap); protected: - void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ) override; + void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) override; private: fixed_t xscale = 0; diff --git a/src/swrenderer/things/r_visiblesprite.cpp b/src/swrenderer/things/r_visiblesprite.cpp index a128734ead..5753d2e483 100644 --- a/src/swrenderer/things/r_visiblesprite.cpp +++ b/src/swrenderer/things/r_visiblesprite.cpp @@ -49,11 +49,11 @@ EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor); namespace swrenderer { - void VisibleSprite::Render(RenderThread *thread) + void VisibleSprite::Render(RenderThread *thread, Fake3DTranslucent clip3DFloor) { if (IsModel()) { - Render(thread, nullptr, nullptr, 0, 0); + Render(thread, nullptr, nullptr, 0, 0, clip3DFloor); return; } @@ -74,10 +74,10 @@ namespace swrenderer if (spr->IsParticle()) { // kg3D - reject invisible parts - if ((clip3d->fake3D & FAKE3D_CLIPBOTTOM) && spr->gpos.Z <= clip3d->sclipBottom) return; - if ((clip3d->fake3D & FAKE3D_CLIPTOP) && spr->gpos.Z >= clip3d->sclipTop) return; + if (clip3DFloor.clipBottom && spr->gpos.Z <= clip3DFloor.sclipBottom) return; + if (clip3DFloor.clipTop && spr->gpos.Z >= clip3DFloor.sclipTop) return; - spr->Render(thread, nullptr, nullptr, 0, 0); + spr->Render(thread, nullptr, nullptr, 0, 0, clip3DFloor); return; } @@ -93,27 +93,27 @@ namespace swrenderer return; // kg3D - reject invisible parts - if ((clip3d->fake3D & FAKE3D_CLIPBOTTOM) && spr->gzt <= clip3d->sclipBottom) return; - if ((clip3d->fake3D & FAKE3D_CLIPTOP) && spr->gzb >= clip3d->sclipTop) return; + if (clip3DFloor.clipBottom && spr->gzt <= clip3DFloor.sclipBottom) return; + if (clip3DFloor.clipTop && spr->gzb >= clip3DFloor.sclipTop) return; // kg3D - correct colors now CameraLight *cameraLight = CameraLight::Instance(); if (!cameraLight->FixedColormap() && cameraLight->FixedLightLevel() < 0 && spr->sector->e && spr->sector->e->XFloor.lightlist.Size()) { - if (!(clip3d->fake3D & FAKE3D_CLIPTOP)) + if (!clip3DFloor.clipTop) { - clip3d->sclipTop = spr->sector->ceilingplane.ZatPoint(thread->Viewport->viewpoint.Pos); + clip3DFloor.sclipTop = spr->sector->ceilingplane.ZatPoint(thread->Viewport->viewpoint.Pos); } sector_t *sec = nullptr; FDynamicColormap *mybasecolormap = nullptr; for (int i = spr->sector->e->XFloor.lightlist.Size() - 1; i >= 0; i--) { - if (clip3d->sclipTop <= spr->sector->e->XFloor.lightlist[i].plane.Zat0()) + if (clip3DFloor.sclipTop <= spr->sector->e->XFloor.lightlist[i].plane.Zat0()) { rover = spr->sector->e->XFloor.lightlist[i].caster; if (rover) { - if (rover->flags & FF_DOUBLESHADOW && clip3d->sclipTop <= rover->bottom.plane->Zat0()) + if (rover->flags & FF_DOUBLESHADOW && clip3DFloor.sclipTop <= rover->bottom.plane->Zat0()) { break; } @@ -229,15 +229,15 @@ namespace swrenderer } } - if (clip3d->fake3D & FAKE3D_CLIPBOTTOM) + if (clip3DFloor.clipBottom) { if (!spr->IsVoxel()) { - double hz = clip3d->sclipBottom; + double hz = clip3DFloor.sclipBottom; if (spr->fakefloor) { double floorz = spr->fakefloor->top.plane->Zat0(); - if (viewport->viewpoint.Pos.Z > floorz && floorz == clip3d->sclipBottom) + if (viewport->viewpoint.Pos.Z > floorz && floorz == clip3DFloor.sclipBottom) { hz = spr->fakefloor->bottom.plane->Zat0(); } @@ -248,17 +248,17 @@ namespace swrenderer botclip = MAX(0, h); } } - hzb = MAX(hzb, clip3d->sclipBottom); + hzb = MAX(hzb, clip3DFloor.sclipBottom); } - if (clip3d->fake3D & FAKE3D_CLIPTOP) + if (clip3DFloor.clipTop) { if (!spr->IsVoxel()) { - double hz = clip3d->sclipTop; + double hz = clip3DFloor.sclipTop; if (spr->fakeceiling != nullptr) { double ceilingZ = spr->fakeceiling->bottom.plane->Zat0(); - if (viewport->viewpoint.Pos.Z < ceilingZ && ceilingZ == clip3d->sclipTop) + if (viewport->viewpoint.Pos.Z < ceilingZ && ceilingZ == clip3DFloor.sclipTop) { hz = spr->fakeceiling->top.plane->Zat0(); } @@ -269,7 +269,7 @@ namespace swrenderer topclip = short(MIN(h, viewheight)); } } - hzt = MIN(hzt, clip3d->sclipTop); + hzt = MIN(hzt, clip3DFloor.sclipTop); } if (topclip >= botclip) @@ -320,7 +320,7 @@ namespace swrenderer int r2 = MIN(ds->x2, x2); RenderDrawSegment renderer(thread); - renderer.Render(ds, r1, r2); + renderer.Render(ds, r1, r2, clip3DFloor); } } } @@ -431,7 +431,7 @@ namespace swrenderer if (!spr->IsVoxel()) { - spr->Render(thread, clipbot, cliptop, 0, 0); + spr->Render(thread, clipbot, cliptop, 0, 0, clip3DFloor); } else { @@ -465,7 +465,7 @@ namespace swrenderer } int minvoxely = spr->gzt <= hzt ? 0 : xs_RoundToInt((spr->gzt - hzt) / spr->yscale); int maxvoxely = spr->gzb > hzb ? INT_MAX : xs_RoundToInt((spr->gzt - hzb) / spr->yscale); - spr->Render(thread, cliptop, clipbot, minvoxely, maxvoxely); + spr->Render(thread, cliptop, clipbot, minvoxely, maxvoxely, clip3DFloor); } spr->Light.BaseColormap = colormap; spr->Light.ColormapNum = colormapnum; diff --git a/src/swrenderer/things/r_visiblesprite.h b/src/swrenderer/things/r_visiblesprite.h index c9fff33270..7821964863 100644 --- a/src/swrenderer/things/r_visiblesprite.h +++ b/src/swrenderer/things/r_visiblesprite.h @@ -38,7 +38,7 @@ namespace swrenderer VisibleSprite() { RenderStyle = STYLE_Normal; } virtual ~VisibleSprite() { } - void Render(RenderThread *thread); + void Render(RenderThread *thread, Fake3DTranslucent clip3DFloor); bool IsCurrentPortalUniq(int portalUniq) const { return CurrentPortalUniq == portalUniq; } const FVector3 &WorldPos() const { return gpos; } @@ -54,7 +54,7 @@ namespace swrenderer virtual bool IsWallSprite() const { return false; } virtual bool IsModel() const { return false; } - virtual void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ) = 0; + virtual void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) = 0; FTexture *pic = nullptr; diff --git a/src/swrenderer/things/r_voxel.cpp b/src/swrenderer/things/r_voxel.cpp index 75b0a2c077..a3c12a8655 100644 --- a/src/swrenderer/things/r_voxel.cpp +++ b/src/swrenderer/things/r_voxel.cpp @@ -205,7 +205,7 @@ namespace swrenderer thread->SpriteList->Push(vis); } - void RenderVoxel::Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ) + void RenderVoxel::Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) { auto spr = this; auto viewport = thread->Viewport.get(); diff --git a/src/swrenderer/things/r_voxel.h b/src/swrenderer/things/r_voxel.h index bef22d4808..7121d34982 100644 --- a/src/swrenderer/things/r_voxel.h +++ b/src/swrenderer/things/r_voxel.h @@ -64,7 +64,7 @@ namespace swrenderer protected: bool IsVoxel() const override { return true; } - void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ) override; + void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) override; private: struct posang diff --git a/src/swrenderer/things/r_wallsprite.cpp b/src/swrenderer/things/r_wallsprite.cpp index 1555e7124b..be4c4195eb 100644 --- a/src/swrenderer/things/r_wallsprite.cpp +++ b/src/swrenderer/things/r_wallsprite.cpp @@ -145,7 +145,7 @@ namespace swrenderer thread->SpriteList->Push(vis); } - void RenderWallSprite::Render(RenderThread *thread, short *mfloorclip, short *mceilingclip, int, int) + void RenderWallSprite::Render(RenderThread *thread, short *mfloorclip, short *mceilingclip, int, int, Fake3DTranslucent) { auto spr = this; diff --git a/src/swrenderer/things/r_wallsprite.h b/src/swrenderer/things/r_wallsprite.h index 2c2ca269cb..c248c6c8c8 100644 --- a/src/swrenderer/things/r_wallsprite.h +++ b/src/swrenderer/things/r_wallsprite.h @@ -14,7 +14,7 @@ namespace swrenderer protected: bool IsWallSprite() const override { return true; } - void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ) override; + void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) override; private: static void DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip);