From 25b56ffecdd00cacd923c02e5a297a7c442575a1 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Wed, 5 Jun 2019 12:10:59 +0200 Subject: [PATCH] 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. --- src/r_main.c | 3 +++ src/r_portal.c | 10 +++++++++- src/r_things.c | 39 +++++++++++++++++++-------------------- src/r_things.h | 2 +- 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/r_main.c b/src/r_main.c index 6e5784f58..8e0989f3b 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -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); diff --git a/src/r_portal.c b/src/r_portal.c index 0a0f4777d..b3d363f63 100644 --- a/src/r_portal.c +++ b/src/r_portal.c @@ -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; } diff --git a/src/r_things.c b/src/r_things.c index f984d75d7..8be926adf 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -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]); } diff --git a/src/r_things.h b/src/r_things.h index 7aa594c79..08a13c1ce 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -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);