Remove the 1000 portal segment limit and make WallPortals private to RenderPortal

This commit is contained in:
Magnus Norddahl 2017-01-24 05:31:39 +01:00
parent 946ab93ff6
commit 12271cbfb5
6 changed files with 48 additions and 39 deletions

View file

@ -601,31 +601,7 @@ namespace swrenderer
if (rw_markportal) if (rw_markportal)
{ {
PortalDrawseg pds; RenderPortal::Instance()->AddLinePortal(curline->linedef, draw_segment->x1, draw_segment->x2, draw_segment->sprtopclip, draw_segment->sprbottomclip);
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);
} }
return (clip3d->fake3D & FAKE3D_FAKEMASK) == 0; return (clip3d->fake3D & FAKE3D_FAKEMASK) == 0;

View file

@ -279,7 +279,7 @@ namespace swrenderer
size_t lastportal = WallPortals.Size(); size_t lastportal = WallPortals.Size();
for (unsigned int i = 0; i < lastportal; i++) for (unsigned int i = 0; i < lastportal; i++)
{ {
RenderLinePortal(&WallPortals[i], 0); RenderLinePortal(WallPortals[i], 0);
} }
CurrentPortal = nullptr; CurrentPortal = nullptr;
@ -449,7 +449,7 @@ namespace swrenderer
unsigned int portalsAtEnd = WallPortals.Size(); unsigned int portalsAtEnd = WallPortals.Size();
for (; portalsAtStart < portalsAtEnd; portalsAtStart++) for (; portalsAtStart < portalsAtEnd; portalsAtStart++)
{ {
RenderLinePortal(&WallPortals[portalsAtStart], depth + 1); RenderLinePortal(WallPortals[portalsAtStart], depth + 1);
} }
int prevuniq2 = CurrentPortalUniq; int prevuniq2 = CurrentPortalUniq;
CurrentPortalUniq = prevuniq; CurrentPortalUniq = prevuniq;
@ -532,6 +532,12 @@ namespace swrenderer
MirrorFlags = 0; MirrorFlags = 0;
CurrentPortal = nullptr; CurrentPortal = nullptr;
CurrentPortalUniq = 0; CurrentPortalUniq = 0;
WallPortals.Clear();
}
void RenderPortal::AddLinePortal(line_t *linedef, int x1, int x2, const short *topclip, const short *bottomclip)
{
WallPortals.Push(RenderMemory::NewObject<PortalDrawseg>(linedef, x1, x2, topclip, bottomclip));
} }
} }

View file

@ -30,6 +30,8 @@ namespace swrenderer
void RenderPlanePortals(); void RenderPlanePortals();
void RenderLinePortals(); void RenderLinePortals();
void AddLinePortal(line_t *linedef, int x1, int x2, const short *topclip, const short *bottomclip);
int WindowLeft = 0; int WindowLeft = 0;
int WindowRight = 0; int WindowRight = 0;
uint16_t MirrorFlags = 0; uint16_t MirrorFlags = 0;
@ -57,5 +59,6 @@ namespace swrenderer
TArray<ptrdiff_t> drawsegStack; TArray<ptrdiff_t> drawsegStack;
TArray<DVector3> viewposStack; TArray<DVector3> viewposStack;
TArray<VisiblePlane *> visplaneStack; TArray<VisiblePlane *> visplaneStack;
TArray<PortalDrawseg *> WallPortals;
}; };
} }

View file

@ -187,7 +187,6 @@ namespace swrenderer
NetUpdate(); NetUpdate();
} }
WallPortals.Clear();
interpolator.RestoreInterpolations(); interpolator.RestoreInterpolations();
// If we don't want shadered colormaps, NULL it now so that the // If we don't want shadered colormaps, NULL it now so that the

View file

@ -31,8 +31,33 @@
#include "po_man.h" #include "po_man.h"
#include "r_data/colormaps.h" #include "r_data/colormaps.h"
#include "swrenderer/segments/r_portalsegment.h" #include "swrenderer/segments/r_portalsegment.h"
#include "swrenderer/r_memory.h"
namespace swrenderer namespace swrenderer
{ {
TArray<PortalDrawseg> 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<short>(len);
floorclip = RenderMemory::AllocMemory<short>(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;
}
} }

View file

@ -18,18 +18,18 @@ namespace swrenderer
/* portal structure, this is used in r_ code in order to store drawsegs with portals (and mirrors) */ /* portal structure, this is used in r_ code in order to store drawsegs with portals (and mirrors) */
struct PortalDrawseg struct PortalDrawseg
{ {
line_t* src; // source line (the one drawn) this doesn't change over render loops PortalDrawseg(line_t *linedef, int x1, int x2, const short *topclip, const short *bottomclip);
line_t* dst; // destination line (the one that the portal is linked with, equals 'src' for mirrors)
int x1; // drawseg x1 line_t* src = nullptr; // source line (the one drawn) this doesn't change over render loops
int x2; // drawseg x2 line_t* dst = nullptr; // destination line (the one that the portal is linked with, equals 'src' for mirrors)
int len; int x1 = 0; // drawseg x1
TArray<short> ceilingclip; int x2 = 0; // drawseg x2
TArray<short> floorclip;
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<PortalDrawseg> WallPortals;
} }