mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-28 06:42:09 +00:00
Create class for draw segment list
This commit is contained in:
parent
2821c15795
commit
6899b351a2
8 changed files with 104 additions and 86 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue