Create class for draw segment list

This commit is contained in:
Magnus Norddahl 2017-01-26 08:01:44 +01:00
parent 2821c15795
commit 6899b351a2
8 changed files with 104 additions and 86 deletions

View file

@ -321,7 +321,7 @@ namespace swrenderer
I_FatalError("Bad R_StoreWallRange: %i to %i", start, stop);
#endif
DrawSegment *draw_segment = R_AddDrawSegment();
DrawSegment *draw_segment = DrawSegmentList::Instance()->Add();
if (!rw_prepped)
{
@ -519,8 +519,8 @@ namespace swrenderer
if (draw_segment->bFogBoundary || draw_segment->maskedtexturecol != nullptr)
{
size_t drawsegnum = draw_segment - drawsegs;
InterestingDrawsegs.Push(drawsegnum);
size_t drawsegnum = draw_segment - DrawSegmentList::Instance()->drawsegs;
DrawSegmentList::Instance()->InterestingDrawsegs.Push(drawsegnum);
}
}
}

View file

@ -93,6 +93,7 @@ namespace swrenderer
numskyboxes = 0;
VisiblePlaneList *planes = VisiblePlaneList::Instance();
DrawSegmentList *drawseglist = DrawSegmentList::Instance();
if (!planes->HasPortalPlanes())
return;
@ -103,8 +104,8 @@ namespace swrenderer
int savedextralight = extralight;
DVector3 savedpos = ViewPos;
DAngle savedangle = ViewAngle;
ptrdiff_t savedds_p = ds_p - drawsegs;
size_t savedinteresting = FirstInterestingDrawseg;
ptrdiff_t savedds_p = drawseglist->ds_p - drawseglist->drawsegs;
size_t savedinteresting = drawseglist->FirstInterestingDrawseg;
double savedvisibility = R_GetVisibility();
AActor *savedcamera = camera;
sector_t *savedsector = viewsector;
@ -187,7 +188,7 @@ namespace swrenderer
}
// Create a drawseg to clip sprites to the sky plane
DrawSegment *draw_segment = R_AddDrawSegment();
DrawSegment *draw_segment = drawseglist->Add();
draw_segment->CurrentPortalUniq = CurrentPortalUniq;
draw_segment->siz1 = INT_MAX;
draw_segment->siz2 = INT_MAX;
@ -207,11 +208,11 @@ namespace swrenderer
memcpy(draw_segment->sprbottomclip, floorclip + pl->left, (pl->right - pl->left) * sizeof(short));
memcpy(draw_segment->sprtopclip, ceilingclip + pl->left, (pl->right - pl->left) * sizeof(short));
firstdrawseg = draw_segment;
FirstInterestingDrawseg = InterestingDrawsegs.Size();
drawseglist->firstdrawseg = draw_segment;
drawseglist->FirstInterestingDrawseg = drawseglist->InterestingDrawsegs.Size();
interestingStack.Push(FirstInterestingDrawseg);
ptrdiff_t diffnum = firstdrawseg - drawsegs;
interestingStack.Push(drawseglist->FirstInterestingDrawseg);
ptrdiff_t diffnum = drawseglist->firstdrawseg - drawseglist->drawsegs;
drawsegStack.Push(diffnum);
VisibleSpriteList::Instance()->PushPortal();
viewposStack.Push(ViewPos);
@ -228,19 +229,19 @@ namespace swrenderer
// Draw all the masked textures in a second pass, in the reverse order they
// were added. This must be done separately from the previous step for the
// sake of nested skyboxes.
while (interestingStack.Pop(FirstInterestingDrawseg))
while (interestingStack.Pop(drawseglist->FirstInterestingDrawseg))
{
ptrdiff_t pd = 0;
drawsegStack.Pop(pd);
firstdrawseg = drawsegs + pd;
drawseglist->firstdrawseg = drawseglist->drawsegs + pd;
// Masked textures and planes need the view coordinates restored for proper positioning.
viewposStack.Pop(ViewPos);
RenderTranslucentPass::Render();
ds_p = firstdrawseg;
drawseglist->ds_p = drawseglist->firstdrawseg;
VisibleSpriteList::Instance()->PopPortal();
@ -251,10 +252,10 @@ namespace swrenderer
pl->Render(pl->Alpha, pl->Additive, true);
}
}
firstdrawseg = drawsegs;
ds_p = drawsegs + savedds_p;
InterestingDrawsegs.Resize((unsigned int)FirstInterestingDrawseg);
FirstInterestingDrawseg = savedinteresting;
drawseglist->firstdrawseg = drawseglist->drawsegs;
drawseglist->ds_p = drawseglist->drawsegs + savedds_p;
drawseglist->InterestingDrawsegs.Resize((unsigned int)drawseglist->FirstInterestingDrawseg);
drawseglist->FirstInterestingDrawseg = savedinteresting;
camera = savedcamera;
viewsector = savedsector;

View file

@ -132,7 +132,7 @@ namespace swrenderer
// Clear buffers.
RenderClipSegment::Instance()->Clear(0, viewwidth);
R_ClearDrawSegs();
DrawSegmentList::Instance()->Clear();
VisiblePlaneList::Instance()->Clear();
RenderTranslucentPass::Clear();
@ -269,7 +269,7 @@ namespace swrenderer
{
RenderTranslucentPass::Deinit();
Clip3DFloors::Instance()->Cleanup();
R_FreeDrawSegs();
DrawSegmentList::Instance()->Deinit();
}
/////////////////////////////////////////////////////////////////////////

View file

@ -68,7 +68,8 @@ namespace swrenderer
// a) exit early if no relevant info is found and
// b) skip most of the collected drawsegs which have no portal attached.
portaldrawsegs.Clear();
for (DrawSegment* seg = ds_p; seg-- > firstdrawseg; ) // copied code from killough below
DrawSegmentList *drawseglist = DrawSegmentList::Instance();
for (DrawSegment* seg = drawseglist->ds_p; seg-- > drawseglist->firstdrawseg; )
{
// I don't know what makes this happen (some old top-down portal code or possibly skybox code? something adds null lines...)
// crashes at the first frame of the first map of Action2.wad
@ -133,17 +134,12 @@ namespace swrenderer
// render any remaining masked mid textures
// Modified by Lee Killough:
// (pointer check was originally nonportable
// and buggy, by going past LEFT end of array):
// for (ds=ds_p-1 ; ds >= drawsegs ; ds--) old buggy code
if (renew)
{
Clip3DFloors::Instance()->fake3D |= FAKE3D_REFRESHCLIP;
}
for (DrawSegment *ds = ds_p; ds-- > firstdrawseg; ) // new -- killough
DrawSegmentList *drawseglist = DrawSegmentList::Instance();
for (DrawSegment *ds = drawseglist->ds_p; ds-- > drawseglist->firstdrawseg; )
{
// [ZZ] the same as above
if (ds->CurrentPortalUniq != renderportal->CurrentPortalUniq)
@ -152,7 +148,8 @@ namespace swrenderer
if (ds->fake) continue;
if (ds->maskedtexturecol != nullptr || ds->bFogBoundary)
{
R_RenderMaskedSegRange(ds, ds->x1, ds->x2);
RenderDrawSegment renderer;
renderer.Render(ds, ds->x1, ds->x2);
}
}
}

View file

@ -45,35 +45,13 @@ EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor);
namespace swrenderer
{
DrawSegment *firstdrawseg;
DrawSegment *ds_p;
DrawSegment *drawsegs;
size_t FirstInterestingDrawseg;
TArray<size_t> InterestingDrawsegs;
namespace
DrawSegmentList *DrawSegmentList::Instance()
{
size_t MaxDrawSegs;
sector_t *frontsector;
sector_t *backsector;
seg_t *curline;
FWallCoords WallC;
FWallTmapVals WallT;
float rw_light;
float rw_lightstep;
fixed_t rw_offset;
FTexture *rw_pic;
ProjectedWallLine wallupper;
ProjectedWallLine walllower;
static DrawSegmentList instance;
return &instance;
}
void R_FreeDrawSegs()
void DrawSegmentList::Deinit()
{
if (drawsegs != nullptr)
{
@ -82,7 +60,7 @@ namespace swrenderer
}
}
void R_ClearDrawSegs()
void DrawSegmentList::Clear()
{
if (drawsegs == nullptr)
{
@ -94,7 +72,7 @@ namespace swrenderer
ds_p = drawsegs;
}
DrawSegment *R_AddDrawSegment()
DrawSegment *DrawSegmentList::Add()
{
if (ds_p == &drawsegs[MaxDrawSegs])
{ // [RH] Grab some more drawsegs
@ -110,8 +88,10 @@ namespace swrenderer
return ds_p++;
}
/////////////////////////////////////////////////////////////////////////
// Clip a midtexture to the floor and ceiling of the sector in front of it.
void ClipMidtex(int x1, int x2)
void RenderDrawSegment::ClipMidtex(int x1, int x2)
{
ProjectedWallLine most;
@ -131,7 +111,7 @@ namespace swrenderer
}
}
void R_GetMaskedWallTopBottom(DrawSegment *ds, double &top, double &bot)
void RenderDrawSegment::GetMaskedWallTopBottom(DrawSegment *ds, double &top, double &bot)
{
double frontcz1 = ds->curline->frontsector->ceilingplane.ZatPoint(ds->curline->v1);
double frontfz1 = ds->curline->frontsector->floorplane.ZatPoint(ds->curline->v1);
@ -151,7 +131,7 @@ namespace swrenderer
}
}
void R_RenderMaskedSegRange(DrawSegment *ds, int x1, int x2)
void RenderDrawSegment::Render(DrawSegment *ds, int x1, int x2)
{
float *MaskedSWall = nullptr, MaskedScaleY = 0, rw_scalestep = 0;
fixed_t *maskedtexturecol = nullptr;
@ -448,7 +428,7 @@ namespace swrenderer
rw_pic = tex;
double top, bot;
R_GetMaskedWallTopBottom(ds, top, bot);
GetMaskedWallTopBottom(ds, top, bot);
RenderWallPart renderWallpart;
renderWallpart.Render(frontsector, curline, WallC, rw_pic, x1, x2, mceilingclip, mfloorclip, texturemid, MaskedSWall, maskedtexturecol, ds->yscale, top, bot, true, wallshade, rw_offset, rw_light, rw_lightstep, nullptr, ds->foggy, basecolormap);
@ -457,7 +437,7 @@ namespace swrenderer
clearfog:
if (ds->bFakeBoundary & 3)
{
R_RenderFakeWallRange(ds, x1, x2, wallshade);
RenderFakeWallRange(ds, x1, x2, wallshade);
}
if (!notrelevant)
{
@ -478,7 +458,7 @@ namespace swrenderer
}
// kg3D - render one fake wall
void R_RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, int wallshade, FDynamicColormap *basecolormap)
void RenderDrawSegment::RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, int wallshade, FDynamicColormap *basecolormap)
{
int i;
double xscale;
@ -578,14 +558,14 @@ namespace swrenderer
walltexcoords.ProjectPos(curline->sidedef->TexelLength*xscale, ds->sx1, ds->sx2, WallT);
double top, bot;
R_GetMaskedWallTopBottom(ds, top, bot);
GetMaskedWallTopBottom(ds, top, bot);
RenderWallPart renderWallpart;
renderWallpart.Render(frontsector, curline, WallC, rw_pic, x1, x2, wallupper.ScreenY, walllower.ScreenY, texturemid, MaskedSWall, walltexcoords.UPos, yscale, top, bot, true, wallshade, rw_offset, rw_light, rw_lightstep, nullptr, ds->foggy, basecolormap);
}
// kg3D - walls of fake floors
void R_RenderFakeWallRange(DrawSegment *ds, int x1, int x2, int wallshade)
void RenderDrawSegment::RenderFakeWallRange(DrawSegment *ds, int x1, int x2, int wallshade)
{
FTexture *const DONT_DRAW = ((FTexture*)(intptr_t)-1);
int i, j;
@ -800,7 +780,7 @@ namespace swrenderer
}
if (rw_pic != DONT_DRAW)
{
R_RenderFakeWall(ds, x1, x2, fover ? fover : rover, wallshade, basecolormap);
RenderFakeWall(ds, x1, x2, fover ? fover : rover, wallshade, basecolormap);
}
else rw_pic = nullptr;
break;
@ -975,7 +955,7 @@ namespace swrenderer
if (rw_pic != DONT_DRAW)
{
R_RenderFakeWall(ds, x1, x2, fover ? fover : rover, wallshade, basecolormap);
RenderFakeWall(ds, x1, x2, fover ? fover : rover, wallshade, basecolormap);
}
else
{

View file

@ -46,21 +46,53 @@ namespace swrenderer
int fake; // ident fake drawseg, don't draw and clip sprites backups
int CurrentPortalUniq; // [ZZ] to identify the portal that this drawseg is in. used for sprite clipping.
};
extern DrawSegment *firstdrawseg;
extern DrawSegment *ds_p;
extern DrawSegment *drawsegs;
extern TArray<size_t> InterestingDrawsegs; // drawsegs that have something drawn on them
extern size_t FirstInterestingDrawseg;
void R_ClearDrawSegs();
void R_FreeDrawSegs();
class DrawSegmentList
{
public:
static DrawSegmentList *Instance();
DrawSegment *R_AddDrawSegment();
void ClipMidtex(int x1, int x2);
void R_RenderMaskedSegRange(DrawSegment *ds, int x1, int x2);
void R_RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, int wallshade, FDynamicColormap *basecolormap);
void R_RenderFakeWallRange(DrawSegment *ds, int x1, int x2, int wallshade);
void R_GetMaskedWallTopBottom(DrawSegment *ds, double &top, double &bot);
DrawSegment *firstdrawseg = nullptr;
DrawSegment *ds_p = nullptr;
DrawSegment *drawsegs = nullptr;
TArray<size_t> InterestingDrawsegs; // drawsegs that have something drawn on them
size_t FirstInterestingDrawseg = 0;
void Clear();
void Deinit();
DrawSegment *Add();
private:
size_t MaxDrawSegs = 0;
};
class RenderDrawSegment
{
public:
void Render(DrawSegment *ds, int x1, int x2);
private:
void ClipMidtex(int x1, int x2);
void RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, int wallshade, FDynamicColormap *basecolormap);
void RenderFakeWallRange(DrawSegment *ds, int x1, int x2, int wallshade);
void GetMaskedWallTopBottom(DrawSegment *ds, double &top, double &bot);
sector_t *frontsector = nullptr;
sector_t *backsector = nullptr;
seg_t *curline = nullptr;
FWallCoords WallC;
FWallTmapVals WallT;
float rw_light = 0.0f;
float rw_lightstep = 0.0f;
fixed_t rw_offset = 0;
FTexture *rw_pic = nullptr;
ProjectedWallLine wallupper;
ProjectedWallLine walllower;
};
}

View file

@ -261,9 +261,10 @@ namespace swrenderer
{
// Draw any masked textures behind this particle so that when the
// particle is drawn, it will be in front of them.
for (unsigned int p = InterestingDrawsegs.Size(); p-- > FirstInterestingDrawseg; )
DrawSegmentList *segmentlist = DrawSegmentList::Instance();
for (unsigned int p = segmentlist->InterestingDrawsegs.Size(); p-- > segmentlist->FirstInterestingDrawseg; )
{
DrawSegment *ds = &drawsegs[InterestingDrawsegs[p]];
DrawSegment *ds = &segmentlist->drawsegs[segmentlist->InterestingDrawsegs[p]];
// kg3D - no fake segs
if (ds->fake) continue;
if (ds->x1 >= x2 || ds->x2 <= x1)
@ -274,7 +275,10 @@ namespace swrenderer
{
// [ZZ] only draw stuff that's inside the same portal as the particle, other portals will care for themselves
if (ds->CurrentPortalUniq == CurrentPortalUniq)
R_RenderMaskedSegRange(ds, MAX<int>(ds->x1, x1), MIN<int>(ds->x2, x2));
{
RenderDrawSegment renderer;
renderer.Render(ds, MAX<int>(ds->x1, x1), MIN<int>(ds->x2, x2));
}
}
}
}

View file

@ -282,7 +282,8 @@ namespace swrenderer
// for (ds=ds_p-1 ; ds >= drawsegs ; ds--) old buggy code
for (ds = ds_p; ds-- > firstdrawseg; ) // new -- killough
DrawSegmentList *segmentlist = DrawSegmentList::Instance();
for (ds = segmentlist->ds_p; ds-- > segmentlist->firstdrawseg; ) // new -- killough
{
// [ZZ] portal handling here
//if (ds->CurrentPortalUniq != spr->CurrentPortalUniq)
@ -327,7 +328,10 @@ namespace swrenderer
// seg is behind sprite, so draw the mid texture if it has one
if (ds->CurrentPortalUniq == renderportal->CurrentPortalUniq && // [ZZ] instead, portal uniq check is made here
(ds->maskedtexturecol != nullptr || ds->bFogBoundary))
R_RenderMaskedSegRange(ds, r1, r2);
{
RenderDrawSegment renderer;
renderer.Render(ds, r1, r2);
}
continue;
}