Skip to content

Commit 2c4ac88

Browse files
dileepvrmadame-rachelle
authored andcommitted
Stacked sector portals now render for OoB viewpoints.
1 parent dc5a250 commit 2c4ac88

File tree

3 files changed

+32
-3
lines changed

3 files changed

+32
-3
lines changed

src/rendering/hwrenderer/scene/hw_portal.cpp

+26-1
Original file line numberDiff line numberDiff line change
@@ -805,17 +805,26 @@ bool HWSectorStackPortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *c
805805
vp.Pos += origin->mDisplacement;
806806
vp.ActorPos += origin->mDisplacement;
807807
vp.ViewActor = nullptr;
808+
vp.OffPos += origin->mDisplacement;
808809

809810
// avoid recursions!
810811
if (origin->plane != -1) screen->instack[origin->plane]++;
811-
812+
if (lines.Size() > 0)
813+
{
814+
flat.plane.GetFromSector(lines[0].sub->sector,
815+
lines[0].sub->sector->GetPortal(sector_t::ceiling)->mType & (PORTS_STACKEDSECTORTHING | PORTS_PORTAL | PORTS_LINKEDPORTAL) ?
816+
sector_t::ceiling : sector_t::floor);
817+
di->SetClipHeight(flat.plane.plane.ZatPoint(vp.Pos),
818+
flat.plane.plane.Normal().Z > 0 ? -1.f : 1.f);
819+
}
812820
di->SetupView(rstate, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(state->MirrorFlag & 1), !!(state->PlaneMirrorFlag & 1));
813821
SetupCoverage(di);
814822
ClearClipper(di, clipper);
815823

816824
// If the viewpoint is not within the portal, we need to invalidate the entire clip area.
817825
// The portal will re-validate the necessary parts when its subsectors get traversed.
818826
subsector_t *sub = di->Level->PointInRenderSubsector(vp.Pos);
827+
if (vp.IsAllowedOoB()) sub = di->Level->PointInRenderSubsector(vp.OffPos);
819828
if (!(di->ss_renderflags[sub->Index()] & SSRF_SEEN))
820829
{
821830
clipper->SafeAddClipRange(0, ANGLE_MAX);
@@ -825,6 +834,22 @@ bool HWSectorStackPortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *c
825834
}
826835

827836

837+
void HWSectorStackPortal::DrawPortalStencil(FRenderState &state, int pass)
838+
{
839+
bool isceiling = planesused & (1 << sector_t::ceiling);
840+
for (unsigned int i = 0; i < lines.Size(); i++)
841+
{
842+
flat.section = lines[i].sub->section;
843+
flat.iboindex = lines[i].sub->sector->iboindex[isceiling ? sector_t::ceiling : sector_t::floor];
844+
flat.plane.GetFromSector(lines[i].sub->sector, isceiling ? sector_t::ceiling : sector_t::floor);
845+
// if (isceiling) flat.plane.plane.FlipVert(); // Doesn't do anything. Stencil is a screen-space projection
846+
847+
state.SetNormal(flat.plane.plane.Normal().X, flat.plane.plane.Normal().Z, flat.plane.plane.Normal().Y);
848+
state.DrawIndexed(DT_Triangles, flat.iboindex + flat.section->vertexindex, flat.section->vertexcount, i == 0);
849+
}
850+
}
851+
852+
828853
void HWSectorStackPortal::Shutdown(HWDrawInfo *di, FRenderState &rstate)
829854
{
830855
if (origin->plane != -1) screen->instack[origin->plane]--;

src/rendering/hwrenderer/scene/hw_portal.h

+1
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ struct HWSectorStackPortal : public HWScenePortalBase
270270
TArray<subsector_t *> subsectors;
271271
protected:
272272
bool Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *clipper) override;
273+
void DrawPortalStencil(FRenderState &state, int pass) override;
273274
void Shutdown(HWDrawInfo *di, FRenderState &rstate) override;
274275
virtual void * GetSource() const { return origin; }
275276
virtual bool IsSky() { return true; } // although this isn't a real sky it can be handled as one.

src/rendering/hwrenderer/scene/hw_sky.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -154,12 +154,15 @@ void HWWall::SkyPlane(HWWallDispatcher *di, sector_t *sector, int plane, bool al
154154
case PORTS_PORTAL:
155155
case PORTS_LINKEDPORTAL:
156156
{
157-
if (di->di && di->di->Viewpoint.IsAllowedOoB()) return; // Almost works (with planemirrorportal stencil), but no quite
157+
if (di->di && di->di->Viewpoint.IsAllowedOoB())
158+
{
159+
secplane_t myplane = plane ? sector->ceilingplane : sector->floorplane;
160+
if (di->di->Viewpoint.ViewVector3D.dot(myplane.Normal()) > 0.0) return;
161+
}
158162
auto glport = sector->GetPortalGroup(plane);
159163
if (glport != NULL)
160164
{
161165
if (sector->PortalBlocksView(plane)) return;
162-
163166
if (di->di && screen->instack[1 - plane]) return;
164167
ptype = PORTALTYPE_SECTORSTACK;
165168
portal = glport;

0 commit comments

Comments
 (0)