mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 14:01:45 +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
|
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
|
// returns true if the portal is crossable by actors
|
||||||
inline bool line_t::isLinePortal() const
|
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
|
// returns true if the portal needs to be handled by the renderer
|
||||||
inline bool line_t::isVisualPortal() const
|
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
|
inline line_t *line_t::getPortalDestination() const
|
||||||
|
|
|
@ -142,15 +142,21 @@ void HWDrawInfo::WorkerThread()
|
||||||
|
|
||||||
front = hw_FakeFlat(job->sub->sector, in_area, false);
|
front = hw_FakeFlat(job->sub->sector, in_area, false);
|
||||||
auto seg = job->seg;
|
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;
|
back = front;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
back = hw_FakeFlat(seg->backsector, in_area, true);
|
back = hw_FakeFlat(backsector, in_area, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else back = nullptr;
|
else back = nullptr;
|
||||||
|
|
|
@ -2046,14 +2046,16 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isportal = seg->linedef->isVisualPortal() && seg->sidedef == seg->linedef->sidedef[0];
|
||||||
|
|
||||||
//return;
|
//return;
|
||||||
// [GZ] 3D middle textures are necessarily two-sided, even if they lack the explicit two-sided flag
|
// [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
|
// sector's sky
|
||||||
SkyNormal(di, frontsector, v1, v2);
|
SkyNormal(di, frontsector, v1, v2);
|
||||||
|
|
||||||
if (seg->linedef->isVisualPortal())
|
if (isportal)
|
||||||
{
|
{
|
||||||
lineportal = seg->linedef->getPortal()->mGroup;
|
lineportal = seg->linedef->getPortal()->mGroup;
|
||||||
ztop[0] = zceil[0];
|
ztop[0] = zceil[0];
|
||||||
|
@ -2139,7 +2141,6 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
|
||||||
|
|
||||||
|
|
||||||
/* mid texture */
|
/* mid texture */
|
||||||
bool isportal = seg->linedef->isVisualPortal() && seg->sidedef == seg->linedef->sidedef[0];
|
|
||||||
sector_t *backsec = isportal? seg->linedef->getPortalDestination()->frontsector : backsector;
|
sector_t *backsec = isportal? seg->linedef->getPortalDestination()->frontsector : backsector;
|
||||||
|
|
||||||
bool drawfogboundary = !di->isFullbrightScene() && di->CheckFog(frontsector, backsec);
|
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;
|
else texture = nullptr;
|
||||||
|
|
||||||
if (texture || drawfogboundary)
|
|
||||||
{
|
|
||||||
DoMidTexture(di, seg, drawfogboundary, frontsector, backsector, realfront, realback,
|
|
||||||
fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isportal)
|
if (isportal)
|
||||||
{
|
{
|
||||||
lineportal = seg->linedef->getPortal()->mGroup;
|
lineportal = seg->linedef->getPortal()->mGroup;
|
||||||
|
@ -2171,9 +2166,18 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
|
||||||
zbottom[1] = bfh2;
|
zbottom[1] = bfh2;
|
||||||
PutPortal(di, PORTALTYPE_LINETOLINE, -1);
|
PutPortal(di, PORTALTYPE_LINETOLINE, -1);
|
||||||
}
|
}
|
||||||
else if (backsector->e->XFloor.ffloors.Size() || frontsector->e->XFloor.ffloors.Size())
|
else
|
||||||
{
|
{
|
||||||
DoFFloorBlocks(di, seg, frontsector, backsector, fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2);
|
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 */
|
/* bottom texture */
|
||||||
|
|
Loading…
Reference in a new issue