- SW's line to sprite portals are working now.

Also fixed a clipper issue with Blood's line to line portals.
This commit is contained in:
Christoph Oelckers 2021-03-24 10:33:50 +01:00
parent 9903b39cf5
commit 1297e4ed02
4 changed files with 85 additions and 7 deletions

View file

@ -388,7 +388,7 @@ void FSkyVertexBuffer::RenderRow(FRenderState& state, EDrawType prim, int row, b
void FSkyVertexBuffer::RenderDome(FRenderState& state, FGameTexture* tex, int mode)
{
if (tex)
if (tex && tex->isValid())
{
state.SetMaterial(tex, UF_Texture, 0, CLAMP_NONE, 0, -1);
state.EnableModelMatrix(true);

View file

@ -640,7 +640,58 @@ bool HWLineToLinePortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *cl
vp.Pos.X = npos.X;
vp.Pos.Y = npos.Y;
vp.Pos.Z -= (sector[line->sector].floorz - sector[origin->sector].floorz) / 256.f; // for testing only. Blood does not do it.
di->SetClipLine(line);
di->SetupView(rstate, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(state->MirrorFlag & 1), !!(state->PlaneMirrorFlag & 1));
clipper->Clear();
angle_t af = di->FrustumAngle();
if (af < ANGLE_180) clipper->SafeAddClipRange(bamang(vp.RotAngle + af), bamang(vp.RotAngle - af));
auto startan = gethiq16angle(origin->x - origx, origin->y - origy);
auto endan = gethiq16angle(wall[origin->point2].x - origx, wall[origin->point2].y - origy);
clipper->SafeAddClipRange(q16ang(endan), q16ang(startan));
return true;
}
const char *HWLineToLinePortal::GetName() { return "LineToLine"; }
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//
//
// Line to sprite Portal
//
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//
// only used by SW.
//
//-----------------------------------------------------------------------------
bool HWLineToSpritePortal::Setup(HWDrawInfo* di, FRenderState& rstate, Clipper* clipper)
{
// TODO: Handle recursion more intelligently
auto& state = mState;
if (state->renderdepth > r_mirror_recursions)
{
return false;
}
auto& vp = di->Viewpoint;
di->mClipPortal = this;
auto srccenter = (WallStart(origin) + WallEnd(origin)) / 2;
DVector2 destcenter ={ camera->x / 16.f, camera->y / -16.f };
DVector2 npos = vp.Pos - srccenter + destcenter;
int origx = vp.Pos.X * 16;
int origy = vp.Pos.Y * -16;
vp.SectNum = camera->sectnum;
vp.Pos.X = npos.X;
vp.Pos.Y = npos.Y;
di->SetClipLine(line);
di->SetupView(rstate, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(state->MirrorFlag & 1), !!(state->PlaneMirrorFlag & 1));
@ -649,13 +700,13 @@ bool HWLineToLinePortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *cl
angle_t af = di->FrustumAngle();
if (af < ANGLE_180) clipper->SafeAddClipRange(bamang(vp.RotAngle + af), bamang(vp.RotAngle - af));
auto startan = gethiq16angle(line->x - origx, line->y - origy);
auto endan = gethiq16angle(wall[line->point2].x - origx, wall[line->point2].y - origy);
clipper->SafeAddClipRange(q16ang(startan), q16ang(endan)); // we check the line from the backside so angles are reversed.
auto startan = gethiq16angle(origin->x - origx, origin->y - origy);
auto endan = gethiq16angle(wall[origin->point2].x - origx, wall[origin->point2].y - origy);
clipper->SafeAddClipRange(q16ang(endan), q16ang(startan));
return true;
}
const char *HWLineToLinePortal::GetName() { return "LineToLine"; }
const char* HWLineToSpritePortal::GetName() { return "LineToSprite"; }
#if 0 // currently none of the games has any support for this. Maybe later.

View file

@ -287,7 +287,7 @@ struct HWLineToLinePortal : public HWLinePortal
walltype* origin;
protected:
bool Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *clipper) override;
virtual void * GetSource() const override { return line; }
virtual void * GetSource() const override { return origin; }
virtual const char *GetName() override;
virtual walltype *ClipLine() override { return line; }
@ -299,6 +299,26 @@ public:
}
};
struct HWLineToSpritePortal : public HWLinePortal
{
walltype* origin;
spritetype* camera;
protected:
bool Setup(HWDrawInfo* di, FRenderState& rstate, Clipper* clipper) override;
virtual void* GetSource() const override { return origin; }
virtual const char* GetName() override;
virtual walltype* ClipLine() override { return line; }
public:
HWLineToSpritePortal(FPortalSceneState* state, walltype* from, spritetype* to)
: HWLinePortal(state, &wall[numwalls]), origin(from), camera(to)
{
// todo: set up two fake walls at the end of the walls array to be used for backside clipping.
// Not really needed for vanilla support but maybe later for feature enhancement.
}
};
#if 0
struct HWSkyboxPortal : public HWScenePortalBase

View file

@ -516,6 +516,13 @@ void HWWall::PutPortal(HWDrawInfo *di, int ptype, int plane)
portal->AddLine(this);
break;
case PORTALTYPE_LINETOSPRITE:
// These are also unique.
portal = new HWLineToSpritePortal(&portalState, seg, &sprite[seg->portalnum]);
di->Portals.Push(portal);
portal->AddLine(this);
break;
case PORTALTYPE_SKY:
sky = portalState.UniqueSkies.Get(sky);
portal = di->FindPortal(sky);