mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-14 08:31:23 +00:00
Fixed sprite clipping with drawsegs (removed unnecessary portal check)
This commit is contained in:
parent
f07d43943a
commit
29880026a6
4 changed files with 64 additions and 33 deletions
|
@ -625,32 +625,27 @@ void R_HighlightPortal (PortalDrawseg* pds)
|
||||||
// I believe it won't break. if it does, blame me. :(
|
// I believe it won't break. if it does, blame me. :(
|
||||||
|
|
||||||
BYTE color = (BYTE)BestColor((DWORD *)GPalette.BaseColors, 255, 0, 0, 0, 255);
|
BYTE color = (BYTE)BestColor((DWORD *)GPalette.BaseColors, 255, 0, 0, 0, 255);
|
||||||
RenderTarget->DrawLine(pds->x1, pds->ceilingclip[0], pds->x1, pds->floorclip[0], color, 0);
|
|
||||||
RenderTarget->DrawLine(pds->x2, pds->ceilingclip[pds->ceilingclip.Size()-1], pds->x2, pds->floorclip[pds->floorclip.Size()-1], color, 0);
|
|
||||||
|
|
||||||
BYTE* pixels = RenderTarget->GetBuffer();
|
BYTE* pixels = RenderTarget->GetBuffer();
|
||||||
// top edge
|
// top edge
|
||||||
for (int x = pds->x1+1; x < pds->x2; x++)
|
for (int x = pds->x1; x <= pds->x2; x++)
|
||||||
{
|
{
|
||||||
if (x < 0 || x >= RenderTarget->GetWidth())
|
if (x < 0 || x >= RenderTarget->GetWidth())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int p = x - pds->x1;
|
int p = x - pds->x1;
|
||||||
|
|
||||||
int Ytop = pds->ceilingclip[p];
|
int Ytop = pds->ceilingclip[p];
|
||||||
int Ybottom = pds->floorclip[p];
|
int Ybottom = pds->floorclip[p];
|
||||||
|
|
||||||
|
if (x == pds->x1 || x == pds->x2)
|
||||||
|
{
|
||||||
|
RenderTarget->DrawLine(x, Ytop, x, Ybottom, color, 0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
int YtopPrev = pds->ceilingclip[p-1];
|
int YtopPrev = pds->ceilingclip[p-1];
|
||||||
int YbottomPrev = pds->floorclip[p-1];
|
int YbottomPrev = pds->floorclip[p-1];
|
||||||
|
|
||||||
if (Ytop < 0) Ytop = 0;
|
|
||||||
if (Ybottom >= RenderTarget->GetHeight())
|
|
||||||
Ybottom = RenderTarget->GetHeight()-1;
|
|
||||||
|
|
||||||
if (YtopPrev < 0) YtopPrev = 0;
|
|
||||||
if (YbottomPrev >= RenderTarget->GetHeight())
|
|
||||||
YbottomPrev = RenderTarget->GetHeight()-1;
|
|
||||||
|
|
||||||
if (abs(Ytop-YtopPrev) > 1)
|
if (abs(Ytop-YtopPrev) > 1)
|
||||||
RenderTarget->DrawLine(x, YtopPrev, x, Ytop, color, 0);
|
RenderTarget->DrawLine(x, YtopPrev, x, Ytop, color, 0);
|
||||||
else *(pixels + Ytop * RenderTarget->GetPitch() + x) = color;
|
else *(pixels + Ytop * RenderTarget->GetPitch() + x) = color;
|
||||||
|
@ -678,10 +673,6 @@ void R_EnterPortal (PortalDrawseg* pds, int depth)
|
||||||
|
|
||||||
BYTE *dest = RenderTarget->GetBuffer() + x + Ytop * spacing;
|
BYTE *dest = RenderTarget->GetBuffer() + x + Ytop * spacing;
|
||||||
|
|
||||||
if (Ytop < 0) Ytop = 0;
|
|
||||||
if (Ybottom >= RenderTarget->GetHeight())
|
|
||||||
Ybottom = RenderTarget->GetHeight()-1;
|
|
||||||
|
|
||||||
for (int y = Ytop; y <= Ybottom; y++)
|
for (int y = Ytop; y <= Ybottom; y++)
|
||||||
{
|
{
|
||||||
*dest = color;
|
*dest = color;
|
||||||
|
@ -698,6 +689,7 @@ void R_EnterPortal (PortalDrawseg* pds, int depth)
|
||||||
angle_t startang = viewangle;
|
angle_t startang = viewangle;
|
||||||
fixed_t startx = viewx;
|
fixed_t startx = viewx;
|
||||||
fixed_t starty = viewy;
|
fixed_t starty = viewy;
|
||||||
|
fixed_t startz = viewz;
|
||||||
|
|
||||||
CurrentPortalUniq++;
|
CurrentPortalUniq++;
|
||||||
|
|
||||||
|
@ -758,13 +750,7 @@ void R_EnterPortal (PortalDrawseg* pds, int depth)
|
||||||
CurrentPortal = pds;
|
CurrentPortal = pds;
|
||||||
|
|
||||||
R_ClearPlanes (false);
|
R_ClearPlanes (false);
|
||||||
R_ClearClipSegs (pds->x1, pds->x2 + 1); // todo: check if this "+1" is actually needed
|
R_ClearClipSegs (pds->x1, pds->x2+1); // todo: check if this "+1" is actually needed
|
||||||
|
|
||||||
// some portals have height differences, account for this here
|
|
||||||
R_3D_EnterSkybox(); // push 3D floor height map
|
|
||||||
|
|
||||||
memcpy (ceilingclip + pds->x1, &pds->ceilingclip[0], pds->ceilingclip.Size()*sizeof(*ceilingclip));
|
|
||||||
memcpy (floorclip + pds->x1, &pds->floorclip[0], pds->floorclip.Size()*sizeof(*floorclip));
|
|
||||||
|
|
||||||
WindowLeft = pds->x1;
|
WindowLeft = pds->x1;
|
||||||
WindowRight = pds->x2;
|
WindowRight = pds->x2;
|
||||||
|
@ -778,6 +764,13 @@ void R_EnterPortal (PortalDrawseg* pds, int depth)
|
||||||
else MirrorFlags |= RF_XFLIP;
|
else MirrorFlags |= RF_XFLIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// some portals have height differences, account for this here
|
||||||
|
R_3D_EnterSkybox(); // push 3D floor height map
|
||||||
|
|
||||||
|
// first pass, set clipping
|
||||||
|
memcpy (ceilingclip + pds->x1, &pds->ceilingclip[0], pds->len*sizeof(*ceilingclip));
|
||||||
|
memcpy (floorclip + pds->x1, &pds->floorclip[0], pds->len*sizeof(*floorclip));
|
||||||
|
|
||||||
R_RenderBSPNode (nodes + numnodes - 1);
|
R_RenderBSPNode (nodes + numnodes - 1);
|
||||||
R_3D_ResetClip(); // reset clips (floor/ceiling)
|
R_3D_ResetClip(); // reset clips (floor/ceiling)
|
||||||
|
|
||||||
|
@ -786,6 +779,8 @@ void R_EnterPortal (PortalDrawseg* pds, int depth)
|
||||||
R_DrawSkyBoxes ();
|
R_DrawSkyBoxes ();
|
||||||
PlaneCycles.Unclock();
|
PlaneCycles.Unclock();
|
||||||
|
|
||||||
|
fixed_t vzp = viewz;
|
||||||
|
|
||||||
int prevuniq = CurrentPortalUniq;
|
int prevuniq = CurrentPortalUniq;
|
||||||
// depth check is in another place right now
|
// depth check is in another place right now
|
||||||
unsigned int portalsAtEnd = WallPortals.Size ();
|
unsigned int portalsAtEnd = WallPortals.Size ();
|
||||||
|
@ -793,6 +788,7 @@ void R_EnterPortal (PortalDrawseg* pds, int depth)
|
||||||
{
|
{
|
||||||
R_EnterPortal (&WallPortals[portalsAtStart], depth + 1);
|
R_EnterPortal (&WallPortals[portalsAtStart], depth + 1);
|
||||||
}
|
}
|
||||||
|
int prevuniq2 = CurrentPortalUniq;
|
||||||
CurrentPortalUniq = prevuniq;
|
CurrentPortalUniq = prevuniq;
|
||||||
|
|
||||||
NetUpdate();
|
NetUpdate();
|
||||||
|
@ -803,16 +799,19 @@ void R_EnterPortal (PortalDrawseg* pds, int depth)
|
||||||
|
|
||||||
NetUpdate();
|
NetUpdate();
|
||||||
|
|
||||||
|
R_3D_LeaveSkybox(); // pop 3D floor height map
|
||||||
|
CurrentPortalUniq = prevuniq2;
|
||||||
|
|
||||||
// draw a red line around a portal if it's being highlighted
|
// draw a red line around a portal if it's being highlighted
|
||||||
if (r_highlight_portals)
|
if (r_highlight_portals)
|
||||||
R_HighlightPortal(pds);
|
R_HighlightPortal(pds);
|
||||||
|
|
||||||
R_3D_LeaveSkybox(); // pop 3D floor height map
|
|
||||||
CurrentPortal = prevpds;
|
CurrentPortal = prevpds;
|
||||||
MirrorFlags = prevmf;
|
MirrorFlags = prevmf;
|
||||||
viewangle = startang;
|
viewangle = startang;
|
||||||
viewx = startx;
|
viewx = startx;
|
||||||
viewy = starty;
|
viewy = starty;
|
||||||
|
viewz = startz;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -897,6 +896,7 @@ void R_RenderActorView (AActor *actor, bool dontmaplines)
|
||||||
WindowRight = viewwidth - 1;
|
WindowRight = viewwidth - 1;
|
||||||
MirrorFlags = 0;
|
MirrorFlags = 0;
|
||||||
CurrentPortal = NULL;
|
CurrentPortal = NULL;
|
||||||
|
CurrentPortalUniq = 0;
|
||||||
|
|
||||||
r_dontmaplines = dontmaplines;
|
r_dontmaplines = dontmaplines;
|
||||||
|
|
||||||
|
@ -937,6 +937,9 @@ void R_RenderActorView (AActor *actor, bool dontmaplines)
|
||||||
R_EnterPortal(&WallPortals[i], 0);
|
R_EnterPortal(&WallPortals[i], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CurrentPortal = NULL;
|
||||||
|
CurrentPortalUniq = 0;
|
||||||
|
|
||||||
NetUpdate ();
|
NetUpdate ();
|
||||||
|
|
||||||
MaskedCycles.Clock();
|
MaskedCycles.Clock();
|
||||||
|
|
|
@ -689,7 +689,10 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl
|
||||||
sky == check->sky &&
|
sky == check->sky &&
|
||||||
CurrentPortalUniq == check->CurrentPortalUniq &&
|
CurrentPortalUniq == check->CurrentPortalUniq &&
|
||||||
MirrorFlags == check->MirrorFlags &&
|
MirrorFlags == check->MirrorFlags &&
|
||||||
CurrentSkybox == check->CurrentSkybox
|
CurrentSkybox == check->CurrentSkybox &&
|
||||||
|
viewx == check->viewx &&
|
||||||
|
viewy == check->viewy &&
|
||||||
|
viewz == check->viewz
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return check;
|
return check;
|
||||||
|
@ -1064,22 +1067,31 @@ void R_DrawHeightPlanes(fixed_t height)
|
||||||
|
|
||||||
ds_color = 3;
|
ds_color = 3;
|
||||||
|
|
||||||
|
fixed_t oViewX = viewx, oViewY = viewy, oViewZ = viewz;
|
||||||
|
angle_t oViewAngle = viewangle;
|
||||||
|
|
||||||
for (i = 0; i < MAXVISPLANES; i++)
|
for (i = 0; i < MAXVISPLANES; i++)
|
||||||
{
|
{
|
||||||
for (pl = visplanes[i]; pl; pl = pl->next)
|
for (pl = visplanes[i]; pl; pl = pl->next)
|
||||||
{
|
{
|
||||||
// kg3D - draw only correct planes
|
// kg3D - draw only correct planes
|
||||||
if(pl->CurrentSkybox != CurrentSkybox)
|
if(pl->CurrentSkybox != CurrentSkybox || pl->CurrentPortalUniq != CurrentPortalUniq)
|
||||||
continue;
|
continue;
|
||||||
if(pl->sky < 0 && pl->height.Zat0() == height) {
|
if(pl->sky < 0 && pl->height.Zat0() == height) {
|
||||||
viewx = pl->viewx;
|
viewx = pl->viewx;
|
||||||
viewy = pl->viewy;
|
viewy = pl->viewy;
|
||||||
|
viewz = pl->viewz;
|
||||||
viewangle = pl->viewangle;
|
viewangle = pl->viewangle;
|
||||||
MirrorFlags = pl->MirrorFlags;
|
MirrorFlags = pl->MirrorFlags;
|
||||||
R_DrawSinglePlane (pl, pl->sky & 0x7FFFFFFF, pl->Additive, true);
|
R_DrawSinglePlane (pl, pl->sky & 0x7FFFFFFF, pl->Additive, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viewx = oViewX;
|
||||||
|
viewy = oViewY;
|
||||||
|
viewz = oViewZ;
|
||||||
|
viewangle = oViewAngle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2591,10 +2591,24 @@ void R_StoreWallRange (int start, int stop)
|
||||||
pds.dst = curline->linedef->portal_dst;
|
pds.dst = curline->linedef->portal_dst;
|
||||||
pds.x1 = ds_p->x1;
|
pds.x1 = ds_p->x1;
|
||||||
pds.x2 = ds_p->x2;
|
pds.x2 = ds_p->x2;
|
||||||
pds.ceilingclip.Resize((pds.x2-pds.x1)+1);
|
pds.len = (pds.x2 - pds.x1) + 1;
|
||||||
memcpy(&pds.ceilingclip[0], openings + ds_p->sprtopclip, pds.ceilingclip.Size()*sizeof(*openings));
|
pds.ceilingclip.Resize(pds.len);
|
||||||
pds.floorclip.Resize((pds.x2-pds.x1)+1);
|
memcpy(&pds.ceilingclip[0], openings + ds_p->sprtopclip, pds.len*sizeof(*openings));
|
||||||
memcpy(&pds.floorclip[0], openings + ds_p->sprbottomclip, pds.floorclip.Size()*sizeof(*openings));
|
pds.floorclip.Resize(pds.len);
|
||||||
|
memcpy(&pds.floorclip[0], openings + ds_p->sprbottomclip, pds.len*sizeof(*openings));
|
||||||
|
|
||||||
|
for (int i = 0; i < (pds.x2-pds.x1)+1; i++)
|
||||||
|
{
|
||||||
|
if (pds.ceilingclip[i] < 0)
|
||||||
|
pds.ceilingclip[i] = 0;
|
||||||
|
if (pds.ceilingclip[i] >= RenderTarget->GetHeight())
|
||||||
|
pds.ceilingclip[i] = RenderTarget->GetHeight()-1;
|
||||||
|
if (pds.floorclip[i] < 0)
|
||||||
|
pds.floorclip[i] = 0;
|
||||||
|
if (pds.floorclip[i] >= RenderTarget->GetHeight())
|
||||||
|
pds.floorclip[i] = RenderTarget->GetHeight()-1;
|
||||||
|
}
|
||||||
|
|
||||||
pds.mirror = curline->linedef->portal_mirror;
|
pds.mirror = curline->linedef->portal_mirror;
|
||||||
WallPortals.Push(pds);
|
WallPortals.Push(pds);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2121,8 +2121,10 @@ void R_DrawSprite (vissprite_t *spr)
|
||||||
for (ds = ds_p; ds-- > firstdrawseg; ) // new -- killough
|
for (ds = ds_p; ds-- > firstdrawseg; ) // new -- killough
|
||||||
{
|
{
|
||||||
// [ZZ] portal handling here
|
// [ZZ] portal handling here
|
||||||
if (ds->CurrentPortalUniq != spr->CurrentPortalUniq)
|
//if (ds->CurrentPortalUniq != spr->CurrentPortalUniq)
|
||||||
continue;
|
// continue;
|
||||||
|
// [ZZ] WARNING: uncommenting the two above lines, totally breaks sprite clipping
|
||||||
|
|
||||||
// kg3D - no clipping on fake segs
|
// kg3D - no clipping on fake segs
|
||||||
if (ds->fake) continue;
|
if (ds->fake) continue;
|
||||||
// determine if the drawseg obscures the sprite
|
// determine if the drawseg obscures the sprite
|
||||||
|
|
Loading…
Reference in a new issue