From 12271cbfb5c445f8959c0cc9f416710057020bc0 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Tue, 24 Jan 2017 05:31:39 +0100 Subject: [PATCH] Remove the 1000 portal segment limit and make WallPortals private to RenderPortal --- src/swrenderer/line/r_line.cpp | 26 +------------------- src/swrenderer/scene/r_portal.cpp | 10 ++++++-- src/swrenderer/scene/r_portal.h | 3 +++ src/swrenderer/scene/r_scene.cpp | 1 - src/swrenderer/segments/r_portalsegment.cpp | 27 ++++++++++++++++++++- src/swrenderer/segments/r_portalsegment.h | 20 +++++++-------- 6 files changed, 48 insertions(+), 39 deletions(-) diff --git a/src/swrenderer/line/r_line.cpp b/src/swrenderer/line/r_line.cpp index 95adff8aa2..077daa72a7 100644 --- a/src/swrenderer/line/r_line.cpp +++ b/src/swrenderer/line/r_line.cpp @@ -601,31 +601,7 @@ namespace swrenderer if (rw_markportal) { - PortalDrawseg pds; - pds.src = curline->linedef; - pds.dst = curline->linedef->special == Line_Mirror ? curline->linedef : curline->linedef->getPortalDestination(); - pds.x1 = draw_segment->x1; - pds.x2 = draw_segment->x2; - pds.len = pds.x2 - pds.x1; - pds.ceilingclip.Resize(pds.len); - memcpy(&pds.ceilingclip[0], draw_segment->sprtopclip, pds.len * sizeof(short)); - pds.floorclip.Resize(pds.len); - memcpy(&pds.floorclip[0], draw_segment->sprbottomclip, pds.len * sizeof(short)); - - for (int i = 0; i < pds.x2 - pds.x1; i++) - { - if (pds.ceilingclip[i] < 0) - pds.ceilingclip[i] = 0; - if (pds.ceilingclip[i] >= viewheight) - pds.ceilingclip[i] = viewheight - 1; - if (pds.floorclip[i] < 0) - pds.floorclip[i] = 0; - if (pds.floorclip[i] >= viewheight) - pds.floorclip[i] = viewheight - 1; - } - - pds.mirror = curline->linedef->special == Line_Mirror; - WallPortals.Push(pds); + RenderPortal::Instance()->AddLinePortal(curline->linedef, draw_segment->x1, draw_segment->x2, draw_segment->sprtopclip, draw_segment->sprbottomclip); } return (clip3d->fake3D & FAKE3D_FAKEMASK) == 0; diff --git a/src/swrenderer/scene/r_portal.cpp b/src/swrenderer/scene/r_portal.cpp index 4d18bcfd4b..82e72ab456 100644 --- a/src/swrenderer/scene/r_portal.cpp +++ b/src/swrenderer/scene/r_portal.cpp @@ -279,7 +279,7 @@ namespace swrenderer size_t lastportal = WallPortals.Size(); for (unsigned int i = 0; i < lastportal; i++) { - RenderLinePortal(&WallPortals[i], 0); + RenderLinePortal(WallPortals[i], 0); } CurrentPortal = nullptr; @@ -449,7 +449,7 @@ namespace swrenderer unsigned int portalsAtEnd = WallPortals.Size(); for (; portalsAtStart < portalsAtEnd; portalsAtStart++) { - RenderLinePortal(&WallPortals[portalsAtStart], depth + 1); + RenderLinePortal(WallPortals[portalsAtStart], depth + 1); } int prevuniq2 = CurrentPortalUniq; CurrentPortalUniq = prevuniq; @@ -532,6 +532,12 @@ namespace swrenderer MirrorFlags = 0; CurrentPortal = nullptr; CurrentPortalUniq = 0; + WallPortals.Clear(); + } + + void RenderPortal::AddLinePortal(line_t *linedef, int x1, int x2, const short *topclip, const short *bottomclip) + { + WallPortals.Push(RenderMemory::NewObject(linedef, x1, x2, topclip, bottomclip)); } } diff --git a/src/swrenderer/scene/r_portal.h b/src/swrenderer/scene/r_portal.h index 74bd4e3490..f62cab3eb0 100644 --- a/src/swrenderer/scene/r_portal.h +++ b/src/swrenderer/scene/r_portal.h @@ -29,6 +29,8 @@ namespace swrenderer void RenderPlanePortals(); void RenderLinePortals(); + + void AddLinePortal(line_t *linedef, int x1, int x2, const short *topclip, const short *bottomclip); int WindowLeft = 0; int WindowRight = 0; @@ -57,5 +59,6 @@ namespace swrenderer TArray drawsegStack; TArray viewposStack; TArray visplaneStack; + TArray WallPortals; }; } diff --git a/src/swrenderer/scene/r_scene.cpp b/src/swrenderer/scene/r_scene.cpp index 659505f0da..be23aae322 100644 --- a/src/swrenderer/scene/r_scene.cpp +++ b/src/swrenderer/scene/r_scene.cpp @@ -187,7 +187,6 @@ namespace swrenderer NetUpdate(); } - WallPortals.Clear(); interpolator.RestoreInterpolations(); // If we don't want shadered colormaps, NULL it now so that the diff --git a/src/swrenderer/segments/r_portalsegment.cpp b/src/swrenderer/segments/r_portalsegment.cpp index 302dbe3c9c..dbc8df9768 100644 --- a/src/swrenderer/segments/r_portalsegment.cpp +++ b/src/swrenderer/segments/r_portalsegment.cpp @@ -31,8 +31,33 @@ #include "po_man.h" #include "r_data/colormaps.h" #include "swrenderer/segments/r_portalsegment.h" +#include "swrenderer/r_memory.h" namespace swrenderer { - TArray WallPortals(1000); // note: this array needs to go away as reallocation can cause crashes. + PortalDrawseg::PortalDrawseg(line_t *linedef, int x1, int x2, const short *topclip, const short *bottomclip) : x1(x1), x2(x2) + { + src = linedef; + dst = linedef->special == Line_Mirror ? linedef : linedef->getPortalDestination(); + len = x2 - x1; + + ceilingclip = RenderMemory::AllocMemory(len); + floorclip = RenderMemory::AllocMemory(len); + memcpy(ceilingclip, topclip, len * sizeof(short)); + memcpy(floorclip, bottomclip, len * sizeof(short)); + + for (int i = 0; i < x2 - x1; i++) + { + if (ceilingclip[i] < 0) + ceilingclip[i] = 0; + if (ceilingclip[i] >= viewheight) + ceilingclip[i] = viewheight - 1; + if (floorclip[i] < 0) + floorclip[i] = 0; + if (floorclip[i] >= viewheight) + floorclip[i] = viewheight - 1; + } + + mirror = linedef->special == Line_Mirror; + } } diff --git a/src/swrenderer/segments/r_portalsegment.h b/src/swrenderer/segments/r_portalsegment.h index f1d757276e..9c6f644dfb 100644 --- a/src/swrenderer/segments/r_portalsegment.h +++ b/src/swrenderer/segments/r_portalsegment.h @@ -18,18 +18,18 @@ namespace swrenderer /* portal structure, this is used in r_ code in order to store drawsegs with portals (and mirrors) */ struct PortalDrawseg { - line_t* src; // source line (the one drawn) this doesn't change over render loops - line_t* dst; // destination line (the one that the portal is linked with, equals 'src' for mirrors) + PortalDrawseg(line_t *linedef, int x1, int x2, const short *topclip, const short *bottomclip); - int x1; // drawseg x1 - int x2; // drawseg x2 + line_t* src = nullptr; // source line (the one drawn) this doesn't change over render loops + line_t* dst = nullptr; // destination line (the one that the portal is linked with, equals 'src' for mirrors) - int len; - TArray ceilingclip; - TArray floorclip; + int x1 = 0; // drawseg x1 + int x2 = 0; // drawseg x2 - bool mirror; // true if this is a mirror (src should equal dst) + int len = 0; + short *ceilingclip = nullptr; + short *floorclip = nullptr; + + bool mirror = false; // true if this is a mirror (src should equal dst) }; - - extern TArray WallPortals; }