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();
SetupPerspectiveMatrix();
MainPortal.SetViewpoint(WorldToClip, GetNextStencilValue());
MainPortal.Render();
MainPortal.Render(0);
Skydome.Render(WorldToClip);
MainPortal.RenderTranslucent();
MainPortal.RenderTranslucent(0);
PlayerSprites.Render();
DrawerCommandQueue::WaitForWorkers();

View file

@ -48,15 +48,18 @@ void RenderPolyPortal::SetViewpoint(const TriMatrix &worldToClip, uint32_t stenc
StencilValue = stencilValue;
}
void RenderPolyPortal::Render()
void RenderPolyPortal::Render(int portalDepth)
{
ClearBuffers();
Cull.CullScene(WorldToClip);
RenderSectors();
for (auto &portal : SectorPortals)
portal->Render();
for (auto &portal : LinePortals)
portal->Render();
if (portalDepth < r_portal_recursions)
{
for (auto &portal : SectorPortals)
portal->Render(portalDepth + 1);
for (auto &portal : LinePortals)
portal->Render(portalDepth + 1);
}
}
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;
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)
for (auto it = SectorPortals.rbegin(); it != SectorPortals.rend(); ++it)
{
args.vinput = verts.Vertices;
args.vcount = verts.Count;
args.ccw = verts.Ccw;
args.uniforms.subsectorDepth = verts.SubsectorDepth;
PolyTriangleDrawer::draw(args, TriDrawVariant::StencilClose, TriBlendMode::Copy);
auto &portal = *it;
portal->RenderTranslucent(portalDepth + 1);
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;
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)
{
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)
for (auto it = LinePortals.rbegin(); it != LinePortals.rend(); ++it)
{
args.vinput = verts.Vertices;
args.vcount = verts.Count;
args.ccw = verts.Ccw;
args.uniforms.subsectorDepth = verts.SubsectorDepth;
PolyTriangleDrawer::draw(args, TriDrawVariant::StencilClose, TriBlendMode::Copy);
auto &portal = *it;
portal->RenderTranslucent(portalDepth + 1);
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;
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();
}
void PolyDrawSectorPortal::Render()
void PolyDrawSectorPortal::Render(int portalDepth)
{
if (Portal->mType != PORTS_SKYVIEWPOINT)
return;
static int recursion = 0;
if (recursion >= 1/*r_portal_recursions*/)
return;
recursion++;
SaveGlobals();
// 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;
RenderPortal.SetViewpoint(worldToClip, StencilValue);
RenderPortal.Render();
RenderPortal.Render(portalDepth);
RestoreGlobals();
recursion--;
}
void PolyDrawSectorPortal::RenderTranslucent()
void PolyDrawSectorPortal::RenderTranslucent(int portalDepth)
{
if (Portal->mType != PORTS_SKYVIEWPOINT)
return;
static int recursion = 0;
if (recursion >= 1/*r_portal_recursions*/)
return;
recursion++;
RenderPortal.RenderTranslucent();
recursion--;
RenderPortal.RenderTranslucent(portalDepth);
}
void PolyDrawSectorPortal::SaveGlobals()
@ -357,12 +349,12 @@ PolyDrawLinePortal::PolyDrawLinePortal(line_t *src, line_t *dest, bool mirror) :
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();
void SetViewpoint(const TriMatrix &worldToClip, uint32_t stencilValue);
void Render();
void RenderTranslucent();
void Render(int portalDepth);
void RenderTranslucent(int portalDepth);
static const uint32_t SkySubsectorDepth = 0x7fffffff;
@ -124,8 +124,8 @@ class PolyDrawSectorPortal
public:
PolyDrawSectorPortal(FSectorPortal *portal, bool ceiling);
void Render();
void RenderTranslucent();
void Render(int portalDepth);
void RenderTranslucent(int portalDepth);
FSectorPortal *Portal;
uint32_t StencilValue = 0;
@ -151,8 +151,8 @@ class PolyDrawLinePortal
public:
PolyDrawLinePortal(line_t *src, line_t *dest, bool mirror);
void Render();
void RenderTranslucent();
void Render(int portalDepth);
void RenderTranslucent(int portalDepth);
uint32_t StencilValue = 0;
std::vector<PolyPortalVertexRange> Shape;