Implement portal recursion limit

This commit is contained in:
Magnus Norddahl 2016-11-25 18:15:48 +01:00
parent 93af906a1d
commit 864358389e
3 changed files with 60 additions and 68 deletions

View file

@ -45,9 +45,9 @@ void RenderPolyScene::Render()
SetSceneViewport(); SetSceneViewport();
SetupPerspectiveMatrix(); SetupPerspectiveMatrix();
MainPortal.SetViewpoint(WorldToClip, GetNextStencilValue()); MainPortal.SetViewpoint(WorldToClip, GetNextStencilValue());
MainPortal.Render(); MainPortal.Render(0);
Skydome.Render(WorldToClip); Skydome.Render(WorldToClip);
MainPortal.RenderTranslucent(); MainPortal.RenderTranslucent(0);
PlayerSprites.Render(); PlayerSprites.Render();
DrawerCommandQueue::WaitForWorkers(); DrawerCommandQueue::WaitForWorkers();

View file

@ -48,15 +48,18 @@ void RenderPolyPortal::SetViewpoint(const TriMatrix &worldToClip, uint32_t stenc
StencilValue = stencilValue; StencilValue = stencilValue;
} }
void RenderPolyPortal::Render() void RenderPolyPortal::Render(int portalDepth)
{ {
ClearBuffers(); ClearBuffers();
Cull.CullScene(WorldToClip); Cull.CullScene(WorldToClip);
RenderSectors(); RenderSectors();
for (auto &portal : SectorPortals) if (portalDepth < r_portal_recursions)
portal->Render(); {
for (auto &portal : LinePortals) for (auto &portal : SectorPortals)
portal->Render(); portal->Render(portalDepth + 1);
for (auto &portal : LinePortals)
portal->Render(portalDepth + 1);
}
} }
void RenderPolyPortal::ClearBuffers() void RenderPolyPortal::ClearBuffers()
@ -189,45 +192,48 @@ void RenderPolyPortal::RenderLine(subsector_t *sub, seg_t *line, sector_t *front
} }
} }
void RenderPolyPortal::RenderTranslucent() void RenderPolyPortal::RenderTranslucent(int portalDepth)
{ {
for (auto it = SectorPortals.rbegin(); it != SectorPortals.rend(); ++it) if (portalDepth < r_portal_recursions)
{ {
auto &portal = *it; for (auto it = SectorPortals.rbegin(); it != SectorPortals.rend(); ++it)
portal->RenderTranslucent();
PolyDrawArgs args;
args.objectToClip = &WorldToClip;
args.mode = TriangleDrawMode::Fan;
args.stenciltestvalue = portal->StencilValue + 1;
args.stencilwritevalue = StencilValue;
for (const auto &verts : portal->Shape)
{ {
args.vinput = verts.Vertices; auto &portal = *it;
args.vcount = verts.Count; portal->RenderTranslucent(portalDepth + 1);
args.ccw = verts.Ccw;
args.uniforms.subsectorDepth = verts.SubsectorDepth; PolyDrawArgs args;
PolyTriangleDrawer::draw(args, TriDrawVariant::StencilClose, TriBlendMode::Copy); args.objectToClip = &WorldToClip;
args.mode = TriangleDrawMode::Fan;
args.stenciltestvalue = portal->StencilValue + 1;
args.stencilwritevalue = StencilValue;
for (const auto &verts : portal->Shape)
{
args.vinput = verts.Vertices;
args.vcount = verts.Count;
args.ccw = verts.Ccw;
args.uniforms.subsectorDepth = verts.SubsectorDepth;
PolyTriangleDrawer::draw(args, TriDrawVariant::StencilClose, TriBlendMode::Copy);
}
} }
}
for (auto it = LinePortals.rbegin(); it != LinePortals.rend(); ++it) for (auto it = LinePortals.rbegin(); it != LinePortals.rend(); ++it)
{
auto &portal = *it;
portal->RenderTranslucent();
PolyDrawArgs args;
args.objectToClip = &WorldToClip;
args.mode = TriangleDrawMode::Fan;
args.stenciltestvalue = portal->StencilValue + 1;
args.stencilwritevalue = StencilValue;
for (const auto &verts : portal->Shape)
{ {
args.vinput = verts.Vertices; auto &portal = *it;
args.vcount = verts.Count; portal->RenderTranslucent(portalDepth + 1);
args.ccw = verts.Ccw;
args.uniforms.subsectorDepth = verts.SubsectorDepth; PolyDrawArgs args;
PolyTriangleDrawer::draw(args, TriDrawVariant::StencilClose, TriBlendMode::Copy); args.objectToClip = &WorldToClip;
args.mode = TriangleDrawMode::Fan;
args.stenciltestvalue = portal->StencilValue + 1;
args.stencilwritevalue = StencilValue;
for (const auto &verts : portal->Shape)
{
args.vinput = verts.Vertices;
args.vcount = verts.Count;
args.ccw = verts.Ccw;
args.uniforms.subsectorDepth = verts.SubsectorDepth;
PolyTriangleDrawer::draw(args, TriDrawVariant::StencilClose, TriBlendMode::Copy);
}
} }
} }
@ -263,16 +269,11 @@ PolyDrawSectorPortal::PolyDrawSectorPortal(FSectorPortal *portal, bool ceiling)
StencilValue = RenderPolyScene::Instance()->GetNextStencilValue(); StencilValue = RenderPolyScene::Instance()->GetNextStencilValue();
} }
void PolyDrawSectorPortal::Render() void PolyDrawSectorPortal::Render(int portalDepth)
{ {
if (Portal->mType != PORTS_SKYVIEWPOINT) if (Portal->mType != PORTS_SKYVIEWPOINT)
return; return;
static int recursion = 0;
if (recursion >= 1/*r_portal_recursions*/)
return;
recursion++;
SaveGlobals(); SaveGlobals();
// To do: get this information from RenderPolyScene instead of duplicating the code.. // To do: get this information from RenderPolyScene instead of duplicating the code..
@ -294,26 +295,17 @@ void PolyDrawSectorPortal::Render()
TriMatrix worldToClip = TriMatrix::perspective(fovy, ratio, 5.0f, 65535.0f) * worldToView; TriMatrix worldToClip = TriMatrix::perspective(fovy, ratio, 5.0f, 65535.0f) * worldToView;
RenderPortal.SetViewpoint(worldToClip, StencilValue); RenderPortal.SetViewpoint(worldToClip, StencilValue);
RenderPortal.Render(); RenderPortal.Render(portalDepth);
RestoreGlobals(); RestoreGlobals();
recursion--;
} }
void PolyDrawSectorPortal::RenderTranslucent() void PolyDrawSectorPortal::RenderTranslucent(int portalDepth)
{ {
if (Portal->mType != PORTS_SKYVIEWPOINT) if (Portal->mType != PORTS_SKYVIEWPOINT)
return; return;
static int recursion = 0; RenderPortal.RenderTranslucent(portalDepth);
if (recursion >= 1/*r_portal_recursions*/)
return;
recursion++;
RenderPortal.RenderTranslucent();
recursion--;
} }
void PolyDrawSectorPortal::SaveGlobals() void PolyDrawSectorPortal::SaveGlobals()
@ -357,12 +349,12 @@ PolyDrawLinePortal::PolyDrawLinePortal(line_t *src, line_t *dest, bool mirror) :
StencilValue = RenderPolyScene::Instance()->GetNextStencilValue(); StencilValue = RenderPolyScene::Instance()->GetNextStencilValue();
} }
void PolyDrawLinePortal::Render() void PolyDrawLinePortal::Render(int portalDepth)
{ {
RenderPortal.Render(); RenderPortal.Render(portalDepth);
} }
void PolyDrawLinePortal::RenderTranslucent() void PolyDrawLinePortal::RenderTranslucent(int portalDepth)
{ {
RenderPortal.RenderTranslucent(); RenderPortal.RenderTranslucent(portalDepth);
} }

View file

@ -84,8 +84,8 @@ public:
RenderPolyPortal(); RenderPolyPortal();
~RenderPolyPortal(); ~RenderPolyPortal();
void SetViewpoint(const TriMatrix &worldToClip, uint32_t stencilValue); void SetViewpoint(const TriMatrix &worldToClip, uint32_t stencilValue);
void Render(); void Render(int portalDepth);
void RenderTranslucent(); void RenderTranslucent(int portalDepth);
static const uint32_t SkySubsectorDepth = 0x7fffffff; static const uint32_t SkySubsectorDepth = 0x7fffffff;
@ -124,8 +124,8 @@ class PolyDrawSectorPortal
public: public:
PolyDrawSectorPortal(FSectorPortal *portal, bool ceiling); PolyDrawSectorPortal(FSectorPortal *portal, bool ceiling);
void Render(); void Render(int portalDepth);
void RenderTranslucent(); void RenderTranslucent(int portalDepth);
FSectorPortal *Portal; FSectorPortal *Portal;
uint32_t StencilValue = 0; uint32_t StencilValue = 0;
@ -151,8 +151,8 @@ class PolyDrawLinePortal
public: public:
PolyDrawLinePortal(line_t *src, line_t *dest, bool mirror); PolyDrawLinePortal(line_t *src, line_t *dest, bool mirror);
void Render(); void Render(int portalDepth);
void RenderTranslucent(); void RenderTranslucent(int portalDepth);
uint32_t StencilValue = 0; uint32_t StencilValue = 0;
std::vector<PolyPortalVertexRange> Shape; std::vector<PolyPortalVertexRange> Shape;