mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 05:51:20 +00:00
- fixed some serious efficiency problems with clipping masked geometry against portals.
The function to do the work scanned the full list of drawsegs to find portals, which with a large amount of masked geometry and/or drawsegs could become extremely slow. Changed it so that R_DrawMasked collects all portal related drawsegs up front so that the actual clipping code can a) scan a far shorter list and b) can skip half of the validation. Also using P_PointOnLinePrecise to shave off a small bit of additional time.
This commit is contained in:
parent
0cf9cae7f3
commit
2321c9973f
1 changed files with 33 additions and 10 deletions
|
@ -324,18 +324,19 @@ nextpost:
|
||||||
// [ZZ]
|
// [ZZ]
|
||||||
// R_ClipSpriteColumnWithPortals
|
// R_ClipSpriteColumnWithPortals
|
||||||
//
|
//
|
||||||
static inline bool R_ClipSpriteColumnWithPortals (fixed_t x, fixed_t y, vissprite_t* spr)
|
|
||||||
{
|
|
||||||
// [ZZ] 10.01.2016: don't clip sprites from the root of a skybox.
|
|
||||||
if (CurrentPortalInSkybox)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
|
static TArray<drawseg_t *> portaldrawsegs;
|
||||||
|
|
||||||
|
static inline void R_CollectPortals()
|
||||||
|
{
|
||||||
|
// This function collects all drawsegs that may be of interest to R_ClipSpriteColumnWithPortals
|
||||||
|
// Having that function over the entire list of drawsegs can break down performance quite drastically.
|
||||||
|
// This is doing the costly stuff only once so that R_ClipSpriteColumnWithPortals can
|
||||||
|
// 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 (drawseg_t* seg = ds_p; seg-- > firstdrawseg; ) // copied code from killough below
|
for (drawseg_t* seg = ds_p; seg-- > firstdrawseg; ) // copied code from killough below
|
||||||
{
|
{
|
||||||
// ignore segs from other portals
|
|
||||||
if (seg->CurrentPortalUniq != CurrentPortalUniq)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// I don't know what makes this happen (some old top-down portal code or possibly skybox code? something adds null lines...)
|
// 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
|
// crashes at the first frame of the first map of Action2.wad
|
||||||
if (!seg->curline) continue;
|
if (!seg->curline) continue;
|
||||||
|
@ -352,8 +353,28 @@ static inline bool R_ClipSpriteColumnWithPortals (fixed_t x, fixed_t y, vissprit
|
||||||
if (seg->curline->sidedef != line->sidedef[0])
|
if (seg->curline->sidedef != line->sidedef[0])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
portaldrawsegs.Push(seg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool R_ClipSpriteColumnWithPortals(fixed_t x, fixed_t y, vissprite_t* spr)
|
||||||
|
{
|
||||||
|
// [ZZ] 10.01.2016: don't clip sprites from the root of a skybox.
|
||||||
|
if (CurrentPortalInSkybox)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for(drawseg_t *seg : portaldrawsegs)
|
||||||
|
{
|
||||||
|
// ignore segs from other portals
|
||||||
|
if (seg->CurrentPortalUniq != CurrentPortalUniq)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// (all checks that are already done in R_CollectPortals have been removed for performance reasons.)
|
||||||
|
|
||||||
|
line_t* line = seg->curline->linedef;
|
||||||
|
|
||||||
// don't clip if the sprite is in front of the portal
|
// don't clip if the sprite is in front of the portal
|
||||||
if (!P_PointOnLineSide(x, y, line))
|
if (!P_PointOnLineSidePrecise(x, y, line))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// now if current column is covered by this drawseg, we clip it away
|
// now if current column is covered by this drawseg, we clip it away
|
||||||
|
@ -364,6 +385,7 @@ static inline bool R_ClipSpriteColumnWithPortals (fixed_t x, fixed_t y, vissprit
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_DrawVisSprite
|
// R_DrawVisSprite
|
||||||
// mfloorclip and mceilingclip should also be set.
|
// mfloorclip and mceilingclip should also be set.
|
||||||
|
@ -2332,6 +2354,7 @@ void R_DrawHeightPlanes(fixed_t height); // kg3D - fake planes
|
||||||
|
|
||||||
void R_DrawMasked (void)
|
void R_DrawMasked (void)
|
||||||
{
|
{
|
||||||
|
R_CollectPortals();
|
||||||
R_SortVisSprites (DrewAVoxel ? sv_compare2d : sv_compare, firstvissprite - vissprites);
|
R_SortVisSprites (DrewAVoxel ? sv_compare2d : sv_compare, firstvissprite - vissprites);
|
||||||
|
|
||||||
if (height_top == NULL)
|
if (height_top == NULL)
|
||||||
|
|
Loading…
Reference in a new issue