Skip to content

Commit

Permalink
- restrict the sky portal shortcut to skies in scenes where there are…
Browse files Browse the repository at this point in the history
… no other portals.

This entire setup does not work with sector portals, causing various render glitches in Shadow Warrior's portals. This also applies to skies within portals so it is now restricted to single sky setups.
  • Loading branch information
coelckers committed May 3, 2021
1 parent 56fcf90 commit d8b8085
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 41 deletions.
48 changes: 8 additions & 40 deletions source/core/rendering/scene/hw_portal.cpp
Expand Up @@ -110,53 +110,21 @@ void FPortalSceneState::EndFrame(HWDrawInfo *di, FRenderState &state)

//-----------------------------------------------------------------------------
//
// Renders one sky portal without a stencil.
// In more complex scenes using a stencil for skies can severely stall
// the GPU and there's rarely more than one sky visible at a time.
// Renders one sky portal without a stencil. Only useful if this is the only portal in view.
//
//-----------------------------------------------------------------------------
bool FPortalSceneState::RenderFirstSkyPortal(int recursion, HWDrawInfo *outer_di, FRenderState &state)
{
HWPortal * p;
HWPortal * best = nullptr;
HWPortal* best = nullptr;
unsigned bestindex = 0;

// Find the one with the highest amount of lines.
// Normally this is also the one that saves the largest amount
// of time by drawing it before the scene itself.
auto &portals = outer_di->Portals;
for (int i = portals.Size() - 1; i >= 0; --i)
{
p = portals[i];
if (p->lines.Size() > 0 && p->IsSky())
{
// Cannot clear the depth buffer inside a portal recursion
if (recursion && p->NeedDepthBuffer()) continue;

if (!best || p->lines.Size() > best->lines.Size())
{
best = p;
bestindex = i;
}
if (recursion > 0 || outer_di->Portals.Size() != 1 || !outer_di->Portals[0]->IsSky()) return false;

// If the portal area contains the current camera viewpoint, let's always use it because it's likely to give the largest area.
if (p->boundingBox.contains(outer_di->Viewpoint.Pos))
{
best = p;
bestindex = i;
break;
}
}
}

if (best)
{
portals.Delete(bestindex);
RenderPortal(best, state, false, outer_di);
delete best;
return true;
}
return false;
best = outer_di->Portals[0];
outer_di->Portals.Clear();
RenderPortal(best, state, false, outer_di);
delete best;
return true;
}


Expand Down
1 change: 0 additions & 1 deletion source/core/rendering/scene/hw_portal.h
Expand Up @@ -352,7 +352,6 @@ struct HWSectorStackPortal : public HWScenePortalBase
bool Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *clipper) override;
void Shutdown(HWDrawInfo *di, FRenderState &rstate) override;
virtual void * GetSource() const { return origin; }
virtual bool IsSky() { return true; } // although this isn't a real sky it can be handled as one.
virtual const char *GetName();
virtual int GetType() { return PORTAL_SECTOR_CEILING; }
PortalDesc *origin;
Expand Down

0 comments on commit d8b8085

Please sign in to comment.