diff --git a/src/rendering/hwrenderer/scene/hw_bsp.cpp b/src/rendering/hwrenderer/scene/hw_bsp.cpp index 488638203c..e37b768df6 100644 --- a/src/rendering/hwrenderer/scene/hw_bsp.cpp +++ b/src/rendering/hwrenderer/scene/hw_bsp.cpp @@ -147,10 +147,16 @@ void HWDrawInfo::WorkerThread() { auto portal = seg->linedef->getPortal(); backsector = portal->mDestination->frontsector; + back = hw_FakeFlat(backsector, in_area, true); + if (front->floorplane.isSlope() || front->ceilingplane.isSlope() || back->floorplane.isSlope() || back->ceilingplane.isSlope()) + { + // Having a one-sided portal like this with slopes is too messy so let's ignore that case. + back = nullptr; + } } - if (backsector) + else if (backsector) { - if (front->sectornum == backsector->sectornum || ((seg->sidedef->Flags & WALLF_POLYOBJ) && !seg->linedef->isVisualPortal())) + if (front->sectornum == backsector->sectornum || (seg->sidedef->Flags & WALLF_POLYOBJ)) { back = front; } diff --git a/src/rendering/hwrenderer/scene/hw_drawstructs.h b/src/rendering/hwrenderer/scene/hw_drawstructs.h index 113c0aaac7..063be282a3 100644 --- a/src/rendering/hwrenderer/scene/hw_drawstructs.h +++ b/src/rendering/hwrenderer/scene/hw_drawstructs.h @@ -234,7 +234,7 @@ public: sector_t * front, sector_t * back, sector_t * realfront, sector_t * realback, float fch1, float fch2, float ffh1, float ffh2, - float bch1, float bch2, float bfh1, float bfh2); + float bch1, float bch2, float bfh1, float bfh2, float zalign); void GetPlanePos(F3DFloor::planeref * planeref, float & left, float & right); diff --git a/src/rendering/hwrenderer/scene/hw_walls.cpp b/src/rendering/hwrenderer/scene/hw_walls.cpp index 6ae94fc966..4abf8d33d8 100644 --- a/src/rendering/hwrenderer/scene/hw_walls.cpp +++ b/src/rendering/hwrenderer/scene/hw_walls.cpp @@ -1251,7 +1251,7 @@ void HWWall::DoMidTexture(HWDrawInfo *di, seg_t * seg, bool drawfogboundary, sector_t * front, sector_t * back, sector_t * realfront, sector_t * realback, float fch1, float fch2, float ffh1, float ffh2, - float bch1, float bch2, float bfh1, float bfh2) + float bch1, float bch2, float bfh1, float bfh2, float zalign) { FTexCoordInfo tci; @@ -1282,12 +1282,12 @@ void HWWall::DoMidTexture(HWDrawInfo *di, seg_t * seg, bool drawfogboundary, rowoffset = tci.RowOffset(seg->sidedef->GetTextureYOffset(side_t::mid)); if ((seg->linedef->flags & ML_DONTPEGBOTTOM) >0) { - texturebottom = MAX(realfront->GetPlaneTexZ(sector_t::floor), realback->GetPlaneTexZ(sector_t::floor)) + rowoffset; + texturebottom = MAX(realfront->GetPlaneTexZ(sector_t::floor), realback->GetPlaneTexZ(sector_t::floor) + zalign) + rowoffset; texturetop = texturebottom + tci.mRenderHeight; } else { - texturetop = MIN(realfront->GetPlaneTexZ(sector_t::ceiling), realback->GetPlaneTexZ(sector_t::ceiling)) + rowoffset; + texturetop = MIN(realfront->GetPlaneTexZ(sector_t::ceiling), realback->GetPlaneTexZ(sector_t::ceiling) + zalign) + rowoffset; texturebottom = texturetop - tci.mRenderHeight; } } @@ -2091,9 +2091,42 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_ float bfh2 = segback->floorplane.ZatPoint(v2); float bch1 = segback->ceilingplane.ZatPoint(v1); float bch2 = segback->ceilingplane.ZatPoint(v2); + float zalign = 0.f; - SkyTop(di, seg, frontsector, backsector, v1, v2); - SkyBottom(di, seg, frontsector, backsector, v1, v2); + + if (isportal && seg->backsector == nullptr) + { + SkyNormal(di, frontsector, v1, v2); // For sky rendering purposes this needs to be treated as a one-sided wall. + + // If this is a one-sided portal and we got floor or ceiling alignment, the upper/lower texture position needs to be adjusted for that. + // (We assume that this portal won't involve slopes!) + switch (seg->linedef->getPortalAlignment()) + { + case PORG_FLOOR: + zalign = ffh1 - bfh1; + bch1 += zalign; + bch2 += zalign; + bfh1 += zalign; + bfh2 += zalign; + return; + + case PORG_CEILING: + zalign = fch1 - bch1; + bch1 += zalign; + bch2 += zalign; + bfh1 += zalign; + bfh2 += zalign; + return; + + default: + break; + } + } + else + { + SkyTop(di, seg, frontsector, backsector, v1, v2); + SkyBottom(di, seg, frontsector, backsector, v1, v2); + } // upper texture if (frontsector->GetTexture(sector_t::ceiling) != skyflatnum || backsector->GetTexture(sector_t::ceiling) != skyflatnum) @@ -2174,7 +2207,7 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_ if (texture && seg->backsector != nullptr) { DoMidTexture(di, seg, drawfogboundary, frontsector, backsector, realfront, realback, - fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2); + fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2, zalign); } } else @@ -2182,7 +2215,7 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_ if (texture || drawfogboundary) { DoMidTexture(di, seg, drawfogboundary, frontsector, backsector, realfront, realback, - fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2); + fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2, zalign); } if (backsector->e->XFloor.ffloors.Size() || frontsector->e->XFloor.ffloors.Size())