Added visual rendering for LinePortals and SkyPortals for OoB viewpoints. SkyPortals will be stenciled, and will always use perspective projection. Disabled interpolation when portalgroup changes (portal transition occurs) if viewpoint is OoB (was necessary for fog of war when r_radarclipper is set to true). Tightened up radar clipper by making it more aggressive. Voided walls wont' get filled in by a floor or ceiling sky (because of the stencil). Ceiling sky will be half-infinitely tall upwards, and floor sky will be half-infinitely tall downwards. Use only floor skies and a good GLSKYBOX for top-down/isometric cameras. Level.ReplaceTextures("F_SKY1", "SKY1", TexMan.NOT_FLOOR); (zscript) is a nice trick for WorldLoaded().

This commit is contained in:
Dileep V. Reddy 2025-02-11 19:51:21 -07:00 committed by Ricardo Luís Vaz Silva
commit 8a66eff437
11 changed files with 118 additions and 111 deletions

View file

@ -287,15 +287,16 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip)
auto &clipperr = *rClipper;
angle_t startAngleR = clipperr.PointToPseudoAngle(seg->v2->fX(), seg->v2->fY());
angle_t endAngleR = clipperr.PointToPseudoAngle(seg->v1->fX(), seg->v1->fY());
angle_t paddingR = 0x00200000; // Make radar clipping more aggressive (reveal less)
if(Viewpoint.IsAllowedOoB() && r_radarclipper && !(Level->flags3 & LEVEL3_NOFOGOFWAR) && (startAngleR - endAngleR >= ANGLE_180))
{
if (!seg->backsector) clipperr.SafeAddClipRange(startAngleR, endAngleR);
if (!seg->backsector) clipperr.SafeAddClipRange(startAngleR - paddingR, endAngleR + paddingR);
else if((seg->sidedef != nullptr) && !uint8_t(seg->sidedef->Flags & WALLF_POLYOBJ) && (currentsector->sectornum != seg->backsector->sectornum))
{
if (in_area == area_default) in_area = hw_CheckViewArea(seg->v1, seg->v2, seg->frontsector, seg->backsector);
backsector = hw_FakeFlat(seg->backsector, in_area, true);
if (hw_CheckClip(seg->sidedef, currentsector, backsector)) clipperr.SafeAddClipRange(startAngleR, endAngleR);
if (hw_CheckClip(seg->sidedef, currentsector, backsector)) clipperr.SafeAddClipRange(startAngleR - paddingR, endAngleR + paddingR);
}
}
@ -313,7 +314,7 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip)
{
currentsubsector->flags |= SSECMF_DRAWN;
}
if ((r_radarclipper || !(Level->flags3 & LEVEL3_NOFOGOFWAR)) && clipperr.SafeCheckRange(startAngleR, endAngleR))
if (Viewpoint.IsAllowedOoB() && (r_radarclipper && !(Level->flags3 & LEVEL3_NOFOGOFWAR)) && clipperr.SafeCheckRange(startAngleR, endAngleR))
{
currentsubsector->flags |= SSECMF_DRAWN;
}
@ -326,31 +327,7 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip)
return;
}
if (Viewpoint.IsAllowedOoB()) // No need for vertical clipping if viewpoint not allowed out of bounds
{
auto &clipperv = *vClipper;
angle_t startPitch = clipperv.PointToPseudoPitch(seg->v1->fX(), seg->v1->fY(), currentsector->floorplane.ZatPoint(seg->v1));
angle_t endPitch = clipperv.PointToPseudoPitch(seg->v1->fX(), seg->v1->fY(), currentsector->ceilingplane.ZatPoint(seg->v1));
angle_t startPitch2 = clipperv.PointToPseudoPitch(seg->v2->fX(), seg->v2->fY(), currentsector->floorplane.ZatPoint(seg->v2));
angle_t endPitch2 = clipperv.PointToPseudoPitch(seg->v2->fX(), seg->v2->fY(), currentsector->ceilingplane.ZatPoint(seg->v2));
angle_t temp;
// Wall can be tilted from viewpoint perspective. Find vertical extent on screen in psuedopitch units (0 to 2, bottom to top)
if(int(startPitch) > int(startPitch2)) // Handle zero crossing
{
temp = startPitch; startPitch = startPitch2; startPitch2 = temp; // exchange
}
if(int(endPitch) > int(endPitch2)) // Handle zero crossing
{
temp = endPitch; endPitch = endPitch2; endPitch2 = temp; // exchange
}
if (!clipperv.SafeCheckRange(startPitch, endPitch2))
{
return;
}
}
if (!r_radarclipper || (Level->flags3 & LEVEL3_NOFOGOFWAR) || clipperr.SafeCheckRange(startAngleR, endAngleR))
if (Viewpoint.IsAllowedOoB() && (!r_radarclipper || (Level->flags3 & LEVEL3_NOFOGOFWAR) || clipperr.SafeCheckRange(startAngleR, endAngleR)))
currentsubsector->flags |= SSECMF_DRAWN;
uint8_t ispoly = uint8_t(seg->sidedef->Flags & WALLF_POLYOBJ);
@ -729,8 +706,8 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
if(Viewpoint.IsAllowedOoB() && sector->isSecret() && sector->wasSecret() && !r_radarclipper) return;
// cull everything if subsector outside vertical clipper
if ((sub->polys == nullptr) && (!Viewpoint.IsOrtho() || !((Level->flags3 & LEVEL3_NOFOGOFWAR) || !r_radarclipper)))
// cull everything if subsector outside all relevant clippers
if ((sub->polys == nullptr))
{
auto &clipper = *mClipper;
auto &clipperv = *vClipper;
@ -739,7 +716,7 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
seg_t * seg = sub->firstline;
bool anglevisible = false;
bool pitchvisible = !(Viewpoint.IsAllowedOoB()); // No vertical clipping if viewpoint is not allowed out of bounds
bool radarvisible = false;
bool radarvisible = !(Viewpoint.IsAllowedOoB()) || !r_radarclipper || (Level->flags3 & LEVEL3_NOFOGOFWAR) || ((sub->flags & SSECMF_DRAWN) && !deathmatch);
angle_t pitchtemp;
angle_t pitchmin = ANGLE_90;
angle_t pitchmax = 0;
@ -748,13 +725,19 @@ void HWDrawInfo::DoSubsector(subsector_t * sub)
{
if((seg->v1 != nullptr) && (seg->v2 != nullptr))
{
angle_t startAngle = clipper.GetClipAngle(seg->v2);
angle_t endAngle = clipper.GetClipAngle(seg->v1);
if (startAngle-endAngle >= ANGLE_180) anglevisible |= clipper.SafeCheckRange(startAngle, endAngle);
angle_t startAngleR = clipperr.PointToPseudoAngle(seg->v2->fX(), seg->v2->fY());
angle_t endAngleR = clipperr.PointToPseudoAngle(seg->v1->fX(), seg->v1->fY());
if (startAngleR-endAngleR >= ANGLE_180)
radarvisible |= (clipperr.SafeCheckRange(startAngleR, endAngleR) || (Level->flags3 & LEVEL3_NOFOGOFWAR) || ((sub->flags & SSECMF_DRAWN) && !deathmatch));
if (!anglevisible)
{
angle_t startAngle = clipper.GetClipAngle(seg->v2);
angle_t endAngle = clipper.GetClipAngle(seg->v1);
if (startAngle-endAngle >= ANGLE_180) anglevisible |= clipper.SafeCheckRange(startAngle, endAngle);
}
if (!radarvisible)
{
angle_t startAngleR = clipperr.PointToPseudoAngle(seg->v2->fX(), seg->v2->fY());
angle_t endAngleR = clipperr.PointToPseudoAngle(seg->v1->fX(), seg->v1->fY());
if (startAngleR-endAngleR >= ANGLE_180) radarvisible |= clipperr.SafeCheckRange(startAngleR, endAngleR);
}
if (!pitchvisible)
{
pitchmin = clipperv.PointToPseudoPitch(seg->v1->fX(), seg->v1->fY(), sector->floorplane.ZatPoint(seg->v1));
@ -988,8 +971,8 @@ void HWDrawInfo::RenderOrthoNoFog()
{
if (Viewpoint.IsOrtho() && ((Level->flags3 & LEVEL3_NOFOGOFWAR) || !r_radarclipper))
{
double vxdbl = Viewpoint.camera->X();
double vydbl = Viewpoint.camera->Y();
double vxdbl = Viewpoint.OffPos.X;
double vydbl = Viewpoint.OffPos.Y;
double ext = Viewpoint.camera->ViewPos->Offset.Length() ?
3.0 * Viewpoint.camera->ViewPos->Offset.Length() * tan (Viewpoint.FieldOfView.Radians()*0.5) : 100.0;
FBoundingBox viewbox(vxdbl, vydbl, ext);
@ -1014,16 +997,8 @@ void HWDrawInfo::RenderBSP(void *node, bool drawpsprites)
viewy = FLOAT2FIXED(Viewpoint.Pos.Y);
if (r_radarclipper && !(Level->flags3 & LEVEL3_NOFOGOFWAR) && Viewpoint.IsAllowedOoB())
{
if (Viewpoint.camera->tracer != NULL)
{
viewx = FLOAT2FIXED(Viewpoint.camera->tracer->X());
viewy = FLOAT2FIXED(Viewpoint.camera->tracer->Y());
}
else
{
viewx = FLOAT2FIXED(Viewpoint.camera->X());
viewy = FLOAT2FIXED(Viewpoint.camera->Y());
}
viewx = FLOAT2FIXED(Viewpoint.OffPos.X);
viewy = FLOAT2FIXED(Viewpoint.OffPos.Y);
}
validcount++; // used for processing sidedefs only once by the renderer.