- 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) if (startAngle-endAngle >= ANGLE_180)
{ {
clipper.SafeRemoveClipRange(startAngle, endAngle); clipper.SafeRemoveClipRange(startAngle, endAngle);
clipper.SetBlocked(false);
} }
seg++; seg++;
} }
@ -444,6 +445,7 @@ static void DoSubsector(subsector_t * sub)
// range this subsector spans before going on. // range this subsector spans before going on.
UnclipSubsector(sub); 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); fakesector=gl_FakeFlat(sector, &fake, false);

View file

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

View file

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

View file

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