Masked elements are now fully grouped individually for each portal/view; fixed viewz-related glitches,.

The drawnodes are now fully grouped in separate lists, and then sorted individually. This fixes sorting problems caused by portals belonging to differently perceived scales (skyboxes for example).

Drawsegs and vissprite/drawnode sorting require the viewz, so the viewz is stored for each portal/view, and then restored when needed; without this, the rendering process erroneously sorts the elements, and draws some at wrong positions.
This commit is contained in:
Nev3r 2019-06-05 12:10:59 +02:00
parent b22aa784fb
commit 25b56ffecd
4 changed files with 32 additions and 22 deletions

View File

@ -1056,6 +1056,7 @@ void R_RenderPlayerView(player_t *player)
masks[nummasks - 1].drawsegs[0] = 0;
masks[nummasks - 1].vissprites[0] = 0;
masks[nummasks - 1].viewz = viewz;
R_RenderBSPNode((INT32)numnodes - 1);
masks[nummasks - 1].drawsegs[1] = ds_p - drawsegs;
masks[nummasks - 1].vissprites[1] = visspritecount;
@ -1103,6 +1104,7 @@ void R_RenderPlayerView(player_t *player)
masks[nummasks - 1].drawsegs[0] = ds_p - drawsegs;
masks[nummasks - 1].vissprites[0] = visspritecount;
masks[nummasks - 1].viewz = viewz;
R_RenderBSPNode((INT32)numnodes - 1);
masks[nummasks - 1].drawsegs[1] = ds_p - drawsegs;
masks[nummasks - 1].vissprites[1] = visspritecount;
@ -1118,6 +1120,7 @@ void R_RenderPlayerView(player_t *player)
#ifdef FLOORSPLATS
R_DrawVisibleFloorSplats();
#endif
// draw mid texture and sprite
// And now 3D floors/sides!
R_DrawMasked(masks, nummasks);

View File

@ -199,7 +199,15 @@ static void Portal_ClipVisplane (const visplane_t* plane, portal_t* portal)
for (i = 0; i < end - start; i++)
{
portal->ceilingclip[i] = plane->top[i + start];
if (plane->bottom[i + start] == 0)
{
portal->ceilingclip[i] = 0;
portal->floorclip[i] = 0;
continue;
}
portal->ceilingclip[i] = plane->top[i + start] - 1;
portal->floorclip[i] = plane->bottom[i + start] + 1;
portal->frontscale[i] = INT32_MAX;
}

View File

@ -1697,9 +1697,7 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
//
// R_SortVisSprites
//
static vissprite_t vsprsortedhead;
void R_SortVisSprites(void)
static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 end)
{
UINT32 i, linkedvissprites = 0;
vissprite_t *ds, *dsprev, *dsnext, *dsfirst;
@ -1708,20 +1706,17 @@ void R_SortVisSprites(void)
fixed_t bestscale;
INT32 bestdispoffset;
if (!visspritecount)
return;
unsorted.next = unsorted.prev = &unsorted;
dsfirst = R_GetVisSprite(0);
dsfirst = R_GetVisSprite(start);
// The first's prev and last's next will be set to
// nonsense, but are fixed in a moment
for (i = 0, dsnext = dsfirst, ds = NULL; i < visspritecount; i++)
for (i = start, dsnext = dsfirst, ds = NULL; i < end; i++)
{
dsprev = ds;
ds = dsnext;
if (i < visspritecount - 1) dsnext = R_GetVisSprite(i + 1);
if (i < end - 1) dsnext = R_GetVisSprite(i + 1);
ds->next = dsnext;
ds->prev = dsprev;
@ -1799,8 +1794,8 @@ void R_SortVisSprites(void)
}
// pull the vissprites out by scale
vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead;
for (i = 0; i < visspritecount-linkedvissprites; i++)
vsprsortedhead->next = vsprsortedhead->prev = vsprsortedhead;
for (i = start; i < end-linkedvissprites; i++)
{
bestscale = bestdispoffset = INT32_MAX;
for (ds = unsorted.next; ds != &unsorted; ds = ds->next)
@ -1825,10 +1820,10 @@ void R_SortVisSprites(void)
}
best->next->prev = best->prev;
best->prev->next = best->next;
best->next = &vsprsortedhead;
best->prev = vsprsortedhead.prev;
vsprsortedhead.prev->next = best;
vsprsortedhead.prev = best;
best->next = vsprsortedhead;
best->prev = vsprsortedhead->prev;
vsprsortedhead->prev->next = best;
vsprsortedhead->prev = best;
}
}
@ -1846,6 +1841,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
INT32 i, p, best, x1, x2;
fixed_t bestdelta, delta;
vissprite_t *rover;
static vissprite_t vsprsortedhead;
drawnode_t *r2;
visplane_t *plane;
INT32 sintersect;
@ -1950,10 +1946,12 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps
}
#endif
if (visspritecount == 0)
// No vissprites in this mask?
if (mask->vissprites[1] - mask->vissprites[0] == 0)
return;
R_SortVisSprites();
R_SortVisSprites(&vsprsortedhead, mask->vissprites[0], mask->vissprites[1]);
for (rover = vsprsortedhead.prev; rover != &vsprsortedhead; rover = rover->prev)
{
if (rover->szt > vid.height || rover->sz < 0)
@ -2436,14 +2434,14 @@ static void R_DrawMaskedList (drawnode_t* head)
void R_DrawMasked(maskcount_t* masks, UINT8 nummasks)
{
drawnode_t heads[nummasks];
drawnode_t heads[nummasks]; /**< Drawnode lists; as many as number of views/portals. */
INT8 i;
for (i = 0; i < nummasks; i++)
{
heads[i].next = heads[i].prev = &heads[i];
R_CreateDrawNodes(&masks[i], &heads[i], i != 0 ? true : false);
viewz = masks[i].viewz;
R_CreateDrawNodes(&masks[i], &heads[i], false);
}
for (i = 0; i < nummasks; i++)
@ -2451,6 +2449,7 @@ void R_DrawMasked(maskcount_t* masks, UINT8 nummasks)
for (; nummasks > 0; nummasks--)
{
viewz = masks[nummasks - 1].viewz;
R_DrawMaskedList(&heads[nummasks - 1]);
R_ClearDrawNodes(&heads[nummasks - 1]);
}

View File

@ -45,7 +45,6 @@ extern fixed_t windowbottom;
void R_DrawMaskedColumn(column_t *column);
void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight);
void R_SortVisSprites(void);
//faB: find sprites in wadfile, replace existing, add new ones
// (only sprites from namelist are added or replaced)
@ -65,6 +64,7 @@ typedef struct
{
size_t drawsegs[2];
size_t vissprites[2];
fixed_t viewz; /**< View z stored at the time of the BSP traversal for the view/portal. Masked sorting/drawing needs it. */
} maskcount_t;
void R_DrawMasked(maskcount_t* masks, UINT8 nummasks);