Skip to content

Commit

Permalink
- fixed rendering of one-sided line portals in the hardware renderer
Browse files Browse the repository at this point in the history
# 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.
  • Loading branch information
Ursus-maritimus210 authored and coelckers committed Mar 5, 2021
1 parent 16b0dd2 commit a15216c
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 17 deletions.
6 changes: 3 additions & 3 deletions src/g_levellocals.h
Expand Up @@ -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
Expand Down
12 changes: 9 additions & 3 deletions src/rendering/hwrenderer/scene/hw_bsp.cpp
Expand Up @@ -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;
Expand Down
26 changes: 15 additions & 11 deletions src/rendering/hwrenderer/scene/hw_walls.cpp
Expand Up @@ -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];
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -2171,9 +2166,18 @@ 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
{
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 */
Expand Down

0 comments on commit a15216c

Please sign in to comment.