diff --git a/source/common/rendering/hwrenderer/data/hw_skydome.cpp b/source/common/rendering/hwrenderer/data/hw_skydome.cpp index af346b364..c4a831f5a 100644 --- a/source/common/rendering/hwrenderer/data/hw_skydome.cpp +++ b/source/common/rendering/hwrenderer/data/hw_skydome.cpp @@ -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); diff --git a/source/core/rendering/scene/hw_portal.cpp b/source/core/rendering/scene/hw_portal.cpp index a7608b301..93537581c 100644 --- a/source/core/rendering/scene/hw_portal.cpp +++ b/source/core/rendering/scene/hw_portal.cpp @@ -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. diff --git a/source/core/rendering/scene/hw_portal.h b/source/core/rendering/scene/hw_portal.h index 6e163c94d..6b41fdeb3 100644 --- a/source/core/rendering/scene/hw_portal.h +++ b/source/core/rendering/scene/hw_portal.h @@ -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 diff --git a/source/core/rendering/scene/hw_walls.cpp b/source/core/rendering/scene/hw_walls.cpp index d9bf8faf9..b54846262 100644 --- a/source/core/rendering/scene/hw_walls.cpp +++ b/source/core/rendering/scene/hw_walls.cpp @@ -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);