mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 12:11:25 +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]
|
||||
// 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
|
||||
{
|
||||
// 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...)
|
||||
// crashes at the first frame of the first map of Action2.wad
|
||||
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])
|
||||
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
|
||||
if (!P_PointOnLineSide(x, y, line))
|
||||
if (!P_PointOnLineSidePrecise(x, y, line))
|
||||
continue;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// R_DrawVisSprite
|
||||
// mfloorclip and mceilingclip should also be set.
|
||||
|
@ -2332,6 +2354,7 @@ void R_DrawHeightPlanes(fixed_t height); // kg3D - fake planes
|
|||
|
||||
void R_DrawMasked (void)
|
||||
{
|
||||
R_CollectPortals();
|
||||
R_SortVisSprites (DrewAVoxel ? sv_compare2d : sv_compare, firstvissprite - vissprites);
|
||||
|
||||
if (height_top == NULL)
|
||||
|
|
Loading…
Reference in a new issue