- do not process subsectors if rendering a stacked sector portal and the clipper is set to 'blocked', i.e. no visible parts are present.

This solves the most severe occurences of sprites being drawn in front of a portal's contents. It is not a full fix, though, there's still some extreme cases where portals may glitch if some stuff gets between the camera and the actual portal area.
Normally this has to perform a full check of the subsector against the portal's camera-facing linedefs but that's too costly for those rare cases where it may be an issue.
This commit is contained in:
Christoph Oelckers 2016-07-23 10:23:34 +02:00
parent d405cf5b7c
commit 54a120d612
4 changed files with 16 additions and 0 deletions

View file

@ -79,6 +79,7 @@ static void UnclipSubsector(subsector_t *sub)
if (startAngle-endAngle >= ANGLE_180)
{
clipper.SafeRemoveClipRange(startAngle, endAngle);
clipper.SetBlocked(false);
}
seg++;
}
@ -444,6 +445,7 @@ static void DoSubsector(subsector_t * sub)
// range this subsector spans before going on.
UnclipSubsector(sub);
}
if (clipper.IsBlocked()) return; // if we are inside a stacked sector portal which hasn't unclipped anything yet.
fakesector=gl_FakeFlat(sector, &fake, false);

View file

@ -92,6 +92,7 @@ void Clipper::Clear()
ClipNode *node = cliphead;
ClipNode *temp;
blocked = false;
while (node != NULL)
{
temp = node;

View file

@ -54,6 +54,7 @@ class Clipper
ClipNode * clipnodes;
ClipNode * cliphead;
ClipNode * silhouette; // will be preserved even when RemoveClipRange is called
bool blocked;
static angle_t AngleToPseudo(angle_t ang);
bool IsRangeVisible(angle_t startangle, angle_t endangle);
@ -68,6 +69,7 @@ public:
Clipper()
{
blocked = false;
clipnodes=cliphead=NULL;
}
@ -129,6 +131,16 @@ public:
SafeRemoveClipRange(AngleToPseudo(startangle), AngleToPseudo(endangle));
}
void SetBlocked(bool on)
{
blocked = on;
}
bool IsBlocked() const
{
return blocked;
}
bool CheckBox(const float *bspcoord);
};

View file

@ -763,6 +763,7 @@ void GLSectorStackPortal::DrawContents()
if (!(gl_drawinfo->ss_renderflags[sub - ::subsectors] & SSRF_SEEN))
{
clipper.SafeAddClipRange(0, ANGLE_MAX);
clipper.SetBlocked(true);
}
GLRenderer->DrawScene(DM_PORTAL);