mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-23 03:12:38 +00:00
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:
parent
25b56ffecd
commit
1c14062e8b
5 changed files with 77 additions and 44 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue