- sector portals in Blood are working.

This commit is contained in:
Christoph Oelckers 2021-03-24 23:11:06 +01:00
parent 368b2319f2
commit dbbdfaa4ba
9 changed files with 32 additions and 20 deletions

View file

@ -171,11 +171,12 @@ void RenderViewpoint(FRenderViewpoint& mainvp, IntRect* bounds, float fov, float
//
//===========================================================================
FRenderViewpoint SetupView(spritetype* cam, const vec3_t& position, int sectnum, fixed_t q16angle, fixed_t q16horizon, float rollang)
FRenderViewpoint SetupViewpoint(spritetype* cam, const vec3_t& position, int sectnum, fixed_t q16angle, fixed_t q16horizon, float rollang)
{
FRenderViewpoint r_viewpoint{};
r_viewpoint.CameraSprite = cam;
r_viewpoint.SectNum = sectnum;
r_viewpoint.SectNums = nullptr;
r_viewpoint.SectCount = sectnum;
r_viewpoint.Pos = { position.x / 16.f, position.y / -16.f, position.z / -256.f };
r_viewpoint.HWAngles.Yaw = -90.f + q16ang(q16angle).asdeg();
r_viewpoint.HWAngles.Pitch = -HorizToPitch(q16horizon);
@ -278,7 +279,7 @@ void render_drawrooms(spritetype* playersprite, const vec3_t& position, int sect
RenderState->SetVertexBuffer(screen->mVertexData);
screen->mVertexData->Reset();
FRenderViewpoint r_viewpoint = SetupView(playersprite, position, sectnum, q16angle, q16horizon, rollang);
FRenderViewpoint r_viewpoint = SetupViewpoint(playersprite, position, sectnum, q16angle, q16horizon, rollang);
iter_dlightf = iter_dlight = draw_dlight = draw_dlightf = 0;
checkBenchActive();

View file

@ -50,7 +50,7 @@ inline void mergePortals()
{
auto& pt2 = allPortals[j];
if (pt1.type != pt2.type || pt1.dx != pt2.dx || pt1.dy != pt2.dy || pt1.dz != pt2.dz) continue;
for (unsigned s = 0; s < pt1.targets.Size(); s++)
for (unsigned s = 0; s < pt1.targets.Size() && pt2.targets.Size(); s++)
{
for (unsigned t = 0; t < pt2.targets.Size(); t++)
{
@ -63,6 +63,7 @@ inline void mergePortals()
{
//Printf("Merged %d and %d\n", i, j);
if (sector[n].portalnum == j) sector[n].portalnum = i;
}
didsomething = true;
break;
}
@ -72,5 +73,4 @@ inline void mergePortals()
}
}
}
}
}

View file

@ -491,9 +491,10 @@ void BunchDrawer::ProcessSector(int sectnum)
//
//==========================================================================
void BunchDrawer::RenderScene(int viewsector)
void BunchDrawer::RenderScene(const int* viewsectors, unsigned sectcount)
{
ProcessSector(viewsector);
for(unsigned i=0;i<sectcount;i++)
ProcessSector(viewsectors[i]);
while (Bunches.Size() > 0)
{
int closest = FindClosestBunch();

View file

@ -50,5 +50,5 @@ private:
public:
void Init(HWDrawInfo* _di, Clipper* c, vec2_t& view);
void RenderScene(int viewsector);
void RenderScene(const int* viewsectors, unsigned sectcount);
};

View file

@ -308,7 +308,10 @@ void HWDrawInfo::CreateScene()
vec2_t view = { int(vp.Pos.X * 16), int(vp.Pos.Y * -16) };
mDrawer.Init(this, mClipper, view);
mDrawer.RenderScene(vp.SectNum);
if (vp.SectNums)
mDrawer.RenderScene(vp.SectNums, vp.SectCount);
else
mDrawer.RenderScene(&vp.SectCount, 1);
screen->mLights->Unmap();
screen->mVertexData->Unmap();

View file

@ -40,7 +40,8 @@ struct FRenderViewpoint
FRotator HWAngles;
FAngle FieldOfView;
angle_t RotAngle;
int SectNum;
int* SectNums;
int SectCount;
double TicFrac;
};
//==========================================================================

View file

@ -398,6 +398,7 @@ void HWPortal::RemoveStencil(HWDrawInfo *di, FRenderState &state, bool usestenci
void HWScenePortalBase::ClearClipper(HWDrawInfo *di, Clipper *clipper)
{
auto outer_di = di->outer;
#if 0 // todo: fixme or remove - Unlike for Doom this won't be of great benefit with Build's rendering approach.
// This requires maximum precision, so convert everything to double.
DAngle angleOffset = deltaangle(DAngle(outer_di->Viewpoint.HWAngles.Yaw.Degrees), DAngle(di->Viewpoint.HWAngles.Yaw.Degrees));
@ -418,6 +419,7 @@ void HWScenePortalBase::ClearClipper(HWDrawInfo *di, Clipper *clipper)
clipper->SafeRemoveClipRange(startang, endang);
}
}
#endif
// and finally clip it to the visible area
angle_t a1 = di->FrustumAngle();
@ -554,7 +556,9 @@ bool HWMirrorPortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *clippe
int newy = int((y << 1) + Scale(dy, i, j) - view.y);
int newan = ((gethiq16angle(dx, dy) << 1) - bamang(vp.RotAngle).asq16()) & 0x7FFFFFF;
vp.RotAngle = q16ang(newan).asbam();
vp.SectNum = line->sector;
vp.SectNums = nullptr;
vp.SectCount = line->sector;
vp.Pos.X = newx / 16.f;
vp.Pos.Y = newy / -16.f;
@ -636,7 +640,8 @@ bool HWLineToLinePortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *cl
int origx = vp.Pos.X * 16;
int origy = vp.Pos.Y * -16;
vp.SectNum = line->sector;
vp.SectNums = nullptr;
vp.SectCount = line->sector;
vp.Pos.X = npos.X;
vp.Pos.Y = npos.Y;
@ -689,7 +694,8 @@ bool HWLineToSpritePortal::Setup(HWDrawInfo* di, FRenderState& rstate, Clipper*
int origx = vp.Pos.X * 16;
int origy = vp.Pos.Y * -16;
vp.SectNum = camera->sectnum;
vp.SectNums = nullptr;
vp.SectCount = camera->sectnum;
vp.Pos.X = npos.X;
vp.Pos.Y = npos.Y;
@ -803,8 +809,8 @@ bool HWSectorStackPortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *c
auto &vp = di->Viewpoint;
vp.Pos += DVector3(portal->dx / 16., portal->dy / -16., portal->dz / -256.);
//vp.ActorPos += origin->mDisplacement;
//vp.ViewActor = nullptr;
vp.SectNums = portal->targets.Data();
vp.SectCount = portal->targets.Size();
// avoid recursions!
screen->instack[origin->type == PORTAL_SECTOR_CEILING ? 1 : 0]++;
@ -829,7 +835,7 @@ const char *HWSectorStackPortal::GetName() { return "Sectorstack"; }
//-----------------------------------------------------------------------------
//
//
// Plane Mirror Portal
// Plane Mirror Portal (currently not needed, Witchaven 2 is the only Build game using such a feature)
//
//
//-----------------------------------------------------------------------------

View file

@ -115,7 +115,7 @@ void HWWall::SkyPlane(HWDrawInfo *di, sectortype *sector, int plane, bool allowr
void HWWall::SkyNormal(HWDrawInfo* di, sectortype* fs, FVector2& v1, FVector2& v2, float fch1, float fch2, float ffh1, float ffh2)
{
if (fs->ceilingstat & CSTAT_SECTOR_SKY)
if ((fs->ceilingstat & CSTAT_SECTOR_SKY) || fs->portalflags == PORTAL_SECTOR_CEILING || fs->portalflags == PORTAL_SECTOR_CEILING_REFLECT)
{
ztop[0] = ztop[1] = 32768.0f;
zbottom[0] = fch1;
@ -123,7 +123,7 @@ void HWWall::SkyNormal(HWDrawInfo* di, sectortype* fs, FVector2& v1, FVector2& v
SkyPlane(di, fs, plane_ceiling, true);
}
if (fs->floorstat & CSTAT_SECTOR_SKY)
if ((fs->floorstat & CSTAT_SECTOR_SKY) || fs->portalflags == PORTAL_SECTOR_FLOOR || fs->portalflags == PORTAL_SECTOR_FLOOR_REFLECT)
{
ztop[0] = ffh1;
ztop[1] = ffh2;

View file

@ -136,7 +136,7 @@ void InitMirrors(void)
mirror[mirrorcnt].link = i;
sector[j].ceilingpicnum = 4080+mirrorcnt;
sector[j].portalflags = PORTAL_SECTOR_CEILING;
sector[i].portalnum = portalAdd(PORTAL_SECTOR_CEILING, j, mirror[mirrorcnt].dx, mirror[mirrorcnt].dy, mirror[mirrorcnt].dz);
sector[j].portalnum = portalAdd(PORTAL_SECTOR_CEILING, i, mirror[mirrorcnt].dx, mirror[mirrorcnt].dy, mirror[mirrorcnt].dz);
mirrorcnt++;
}
}