mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 20:21:26 +00:00
- fixed rendering of one-sided line portals in the hardware renderer
# draw upper and lower textures when the back sector does not properly match # do not draw middle textures on portal lines # minor optimization to 'is***Portal' functions to avoid memory access in the most common case of no portal being present.
This commit is contained in:
parent
16b0dd2fe8
commit
a15216c90f
3 changed files with 27 additions and 17 deletions
|
@ -801,19 +801,19 @@ inline FLevelLocals *line_t::GetLevel() const
|
|||
}
|
||||
inline FLinePortal *line_t::getPortal() const
|
||||
{
|
||||
return portalindex >= GetLevel()->linePortals.Size() ? (FLinePortal*)nullptr : &GetLevel()->linePortals[portalindex];
|
||||
return portalindex == UINT_MAX && portalindex >= GetLevel()->linePortals.Size() ? (FLinePortal*)nullptr : &GetLevel()->linePortals[portalindex];
|
||||
}
|
||||
|
||||
// returns true if the portal is crossable by actors
|
||||
inline bool line_t::isLinePortal() const
|
||||
{
|
||||
return portalindex >= GetLevel()->linePortals.Size() ? false : !!(GetLevel()->linePortals[portalindex].mFlags & PORTF_PASSABLE);
|
||||
return portalindex == UINT_MAX && portalindex >= GetLevel()->linePortals.Size() ? false : !!(GetLevel()->linePortals[portalindex].mFlags & PORTF_PASSABLE);
|
||||
}
|
||||
|
||||
// returns true if the portal needs to be handled by the renderer
|
||||
inline bool line_t::isVisualPortal() const
|
||||
{
|
||||
return portalindex >= GetLevel()->linePortals.Size() ? false : !!(GetLevel()->linePortals[portalindex].mFlags & PORTF_VISIBLE);
|
||||
return portalindex == UINT_MAX && portalindex >= GetLevel()->linePortals.Size() ? false : !!(GetLevel()->linePortals[portalindex].mFlags & PORTF_VISIBLE);
|
||||
}
|
||||
|
||||
inline line_t *line_t::getPortalDestination() const
|
||||
|
|
|
@ -142,15 +142,21 @@ void HWDrawInfo::WorkerThread()
|
|||
|
||||
front = hw_FakeFlat(job->sub->sector, in_area, false);
|
||||
auto seg = job->seg;
|
||||
if (seg->backsector)
|
||||
auto backsector = seg->backsector;
|
||||
if (!backsector && seg->linedef->isVisualPortal() && seg->sidedef == seg->linedef->sidedef[0]) // For one-sided portals use the portal's destination sector as backsector.
|
||||
{
|
||||
if (front->sectornum == seg->backsector->sectornum || (seg->sidedef->Flags & WALLF_POLYOBJ))
|
||||
auto portal = seg->linedef->getPortal();
|
||||
backsector = portal->mDestination->frontsector;
|
||||
}
|
||||
if (backsector)
|
||||
{
|
||||
if (front->sectornum == backsector->sectornum || ((seg->sidedef->Flags & WALLF_POLYOBJ) && !seg->linedef->isVisualPortal()))
|
||||
{
|
||||
back = front;
|
||||
}
|
||||
else
|
||||
{
|
||||
back = hw_FakeFlat(seg->backsector, in_area, true);
|
||||
back = hw_FakeFlat(backsector, in_area, true);
|
||||
}
|
||||
}
|
||||
else back = nullptr;
|
||||
|
|
|
@ -2046,14 +2046,16 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
|
|||
return;
|
||||
}
|
||||
|
||||
bool isportal = seg->linedef->isVisualPortal() && seg->sidedef == seg->linedef->sidedef[0];
|
||||
|
||||
//return;
|
||||
// [GZ] 3D middle textures are necessarily two-sided, even if they lack the explicit two-sided flag
|
||||
if (!backsector || !(seg->linedef->flags&(ML_TWOSIDED | ML_3DMIDTEX))) // one sided
|
||||
if (!backsector || (!(seg->linedef->flags&(ML_TWOSIDED | ML_3DMIDTEX)) && !isportal)) // one sided
|
||||
{
|
||||
// sector's sky
|
||||
SkyNormal(di, frontsector, v1, v2);
|
||||
|
||||
if (seg->linedef->isVisualPortal())
|
||||
if (isportal)
|
||||
{
|
||||
lineportal = seg->linedef->getPortal()->mGroup;
|
||||
ztop[0] = zceil[0];
|
||||
|
@ -2139,7 +2141,6 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
|
|||
|
||||
|
||||
/* mid texture */
|
||||
bool isportal = seg->linedef->isVisualPortal() && seg->sidedef == seg->linedef->sidedef[0];
|
||||
sector_t *backsec = isportal? seg->linedef->getPortalDestination()->frontsector : backsector;
|
||||
|
||||
bool drawfogboundary = !di->isFullbrightScene() && di->CheckFog(frontsector, backsec);
|
||||
|
@ -2156,12 +2157,6 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
|
|||
}
|
||||
else texture = nullptr;
|
||||
|
||||
if (texture || drawfogboundary)
|
||||
{
|
||||
DoMidTexture(di, seg, drawfogboundary, frontsector, backsector, realfront, realback,
|
||||
fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2);
|
||||
}
|
||||
|
||||
if (isportal)
|
||||
{
|
||||
lineportal = seg->linedef->getPortal()->mGroup;
|
||||
|
@ -2171,10 +2166,19 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
|
|||
zbottom[1] = bfh2;
|
||||
PutPortal(di, PORTALTYPE_LINETOLINE, -1);
|
||||
}
|
||||
else if (backsector->e->XFloor.ffloors.Size() || frontsector->e->XFloor.ffloors.Size())
|
||||
else
|
||||
{
|
||||
if (texture || drawfogboundary)
|
||||
{
|
||||
DoMidTexture(di, seg, drawfogboundary, frontsector, backsector, realfront, realback,
|
||||
fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2);
|
||||
}
|
||||
|
||||
if (backsector->e->XFloor.ffloors.Size() || frontsector->e->XFloor.ffloors.Size())
|
||||
{
|
||||
DoFFloorBlocks(di, seg, frontsector, backsector, fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2);
|
||||
}
|
||||
}
|
||||
|
||||
/* bottom texture */
|
||||
// the back sector's ceiling obstructs part of this wall (specially important for sky sectors)
|
||||
|
|
Loading…
Reference in a new issue