Vissprite clipping improvements.

Vissprites are now only clipped against their respective portal's geometry obtained from their BSP run.
Additionally, if a portal is provided, they're clipped to the portal's clip boundaries.
The work on this branch should conclude after a pair of remaining glitches are fixed.
This commit is contained in:
Nev3r 2019-06-05 16:35:48 +02:00
parent 25b56ffecd
commit 1c14062e8b
5 changed files with 77 additions and 44 deletions

View File

@ -1061,8 +1061,7 @@ void R_RenderPlayerView(player_t *player)
masks[nummasks - 1].drawsegs[1] = ds_p - drawsegs;
masks[nummasks - 1].vissprites[1] = visspritecount;
R_ClipSprites();
R_ClipSprites(drawsegs, NULL);
#ifdef TIMING
RDMSR(0x10, &mycount);
mytotal += mycount; // 64bit add
@ -1108,7 +1107,8 @@ void R_RenderPlayerView(player_t *player)
R_RenderBSPNode((INT32)numnodes - 1);
masks[nummasks - 1].drawsegs[1] = ds_p - drawsegs;
masks[nummasks - 1].vissprites[1] = visspritecount;
R_ClipSprites();
R_ClipSprites(ds_p - (masks[nummasks - 1].drawsegs[1] - masks[nummasks - 1].drawsegs[0]), portal);
Portal_Remove(portal);
}

View File

@ -17,6 +17,7 @@
#include "doomstat.h"
#include "p_spec.h" // Skybox viewpoints
#include "z_zone.h"
#include "r_things.h"
UINT8 portalrender; /**< When rendering a portal, it establishes the depth of the current BSP traversal. */
sector_t *portalcullsector;
@ -98,9 +99,9 @@ void Portal_ClipApply (const portal_t* portal)
portal_t* Portal_Add (const INT16 x1, const INT16 x2)
{
portal_t *portal = Z_Malloc(sizeof(portal_t), PU_LEVEL, NULL);
INT16 *ceilingclipsave = Z_Malloc(sizeof(INT16)*(x2-x1), PU_LEVEL, NULL);
INT16 *floorclipsave = Z_Malloc(sizeof(INT16)*(x2-x1), PU_LEVEL, NULL);
fixed_t *frontscalesave = Z_Malloc(sizeof(fixed_t)*(x2-x1), PU_LEVEL, NULL);
INT16 *ceilingclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL);
INT16 *floorclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL);
fixed_t *frontscalesave = Z_Malloc(sizeof(fixed_t)*(x2-x1 + 1), PU_LEVEL, NULL);
// Linked list.
if (!portal_base)
@ -199,15 +200,7 @@ static void Portal_ClipVisplane (const visplane_t* plane, portal_t* portal)
for (i = 0; i < end - start; i++)
{
if (plane->bottom[i + start] == 0)
{
portal->ceilingclip[i] = 0;
portal->floorclip[i] = 0;
continue;
}
portal->ceilingclip[i] = plane->top[i + start] - 1;
portal->ceilingclip[i] = plane->top[i + start];
portal->floorclip[i] = plane->bottom[i + start] + 1;
portal->frontscale[i] = INT32_MAX;
}
@ -230,6 +223,25 @@ void Portal_AddSkybox (const visplane_t* plane)
if (!(start < end))
return;
/** Trims a visplane's horizontal gap to match its render area.
*
* Visplanes' minx/maxx may sometimes exceed the area they're
* covering. This merely adjusts the boundaries to the next
* valid area.
*/
while (plane->bottom[start] == 0 && plane->top[start] == 65535 && start < end)
{
start++;
}
while (plane->bottom[end - 1] == 0 && plane->top[start] == 65535 && end > start)
{
end--;
}
portal = Portal_Add(start, end);
Portal_ClipVisplane(plane, portal);

View File

@ -11,6 +11,9 @@
/// \file r_portal.h
/// \brief Software renderer portal struct, functions, linked list extern.
#ifndef __R_PORTAL__
#define __R_PORTAL__
#include "r_data.h"
#include "r_plane.h" // visplanes
@ -52,3 +55,5 @@ void Portal_AddSkybox (const visplane_t* plane);
void Portal_ClipRange (portal_t* portal);
void Portal_ClipApply (const portal_t* portal);
#endif

View File

@ -2185,7 +2185,7 @@ static void R_DrawPrecipitationSprite(vissprite_t *spr)
// R_ClipSprites
// Clips vissprites without drawing, so that portals can work. -Red
void R_ClipSprites(void)
void R_ClipSprites(drawseg_t* dsstart, portal_t* portal)
{
vissprite_t *spr;
for (; clippedvissprites < visspritecount; clippedvissprites++)
@ -2211,7 +2211,7 @@ void R_ClipSprites(void)
// and buggy, by going past LEFT end of array:
// for (ds = ds_p-1; ds >= drawsegs; ds--) old buggy code
for (ds = ds_p; ds-- > drawsegs ;)
for (ds = ds_p; ds-- > dsstart;)
{
// determine if the drawseg obscures the sprite
if (ds->x1 > spr->x2 ||
@ -2223,34 +2223,37 @@ void R_ClipSprites(void)
continue;
}
if (ds->portalpass > 0 && ds->portalpass <= portalrender)
continue; // is a portal
if (ds->portalpass != 66)
{
if (ds->portalpass > 0 && ds->portalpass <= portalrender)
continue; // is a portal
if (ds->scale1 > ds->scale2)
{
lowscale = ds->scale2;
scale = ds->scale1;
}
else
{
lowscale = ds->scale1;
scale = ds->scale2;
}
if (scale < spr->sortscale ||
(lowscale < spr->sortscale &&
!R_PointOnSegSide (spr->gx, spr->gy, ds->curline)))
{
// masked mid texture?
/*if (ds->maskedtexturecol)
R_RenderMaskedSegRange (ds, r1, r2);*/
// seg is behind sprite
continue;
}
}
r1 = ds->x1 < spr->x1 ? spr->x1 : ds->x1;
r2 = ds->x2 > spr->x2 ? spr->x2 : ds->x2;
if (ds->scale1 > ds->scale2)
{
lowscale = ds->scale2;
scale = ds->scale1;
}
else
{
lowscale = ds->scale1;
scale = ds->scale2;
}
if (scale < spr->sortscale ||
(lowscale < spr->sortscale &&
!R_PointOnSegSide (spr->gx, spr->gy, ds->curline)))
{
// masked mid texture?
/*if (ds->maskedtexturecol)
R_RenderMaskedSegRange (ds, r1, r2);*/
// seg is behind sprite
continue;
}
// clip this piece of the sprite
silhouette = ds->silhouette;
@ -2367,6 +2370,17 @@ void R_ClipSprites(void)
//Fab : 26-04-98: was -1, now clips against console bottom
spr->cliptop[x] = (INT16)con_clipviewtop;
}
if (portal)
{
for (x = spr->x1; x <= spr->x2; x++)
{
if (spr->clipbot[x] > portal->floorclip[x - portal->start])
spr->clipbot[x] = portal->floorclip[x - portal->start];
if (spr->cliptop[x] < portal->ceilingclip[x - portal->start])
spr->cliptop[x] = portal->ceilingclip[x - portal->start];
}
}
}
}
@ -2444,12 +2458,13 @@ void R_DrawMasked(maskcount_t* masks, UINT8 nummasks)
R_CreateDrawNodes(&masks[i], &heads[i], false);
}
for (i = 0; i < nummasks; i++)
CONS_Printf("Mask no.%d:\ndrawsegs: %d\n vissprites: %d\n\n", i, masks[i].drawsegs[1] - masks[i].drawsegs[0], masks[i].vissprites[1] - masks[i].vissprites[0]);
//for (i = 0; i < nummasks; i++)
// CONS_Printf("Mask no.%d:\ndrawsegs: %d\n vissprites: %d\n\n", i, masks[i].drawsegs[1] - masks[i].drawsegs[0], masks[i].vissprites[1] - masks[i].vissprites[0]);
for (; nummasks > 0; nummasks--)
{
viewz = masks[nummasks - 1].viewz;
R_DrawMaskedList(&heads[nummasks - 1]);
R_ClearDrawNodes(&heads[nummasks - 1]);
}

View File

@ -16,6 +16,7 @@
#include "sounds.h"
#include "r_plane.h"
#include "r_portal.h"
// "Left" and "Right" character symbols for additional rotation functionality
#define ROT_L ('L' - '0')
@ -54,7 +55,7 @@ void R_AddSpriteDefs(UINT16 wadnum);
void R_AddSprites(sector_t *sec, INT32 lightlevel);
void R_InitSprites(void);
void R_ClearSprites(void);
void R_ClipSprites(void);
void R_ClipSprites(drawseg_t* dsstart, portal_t* portal);
/** Used to count the amount of masked elements
* per portal to later group them in separate