More portal handling stuff

This commit is contained in:
Magnus Norddahl 2016-11-25 01:08:25 +01:00
parent 558a4bcdca
commit 1def7b3eae
4 changed files with 118 additions and 33 deletions

View file

@ -149,9 +149,22 @@ void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, subsector_t *s
void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals) void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> &sectorPortals)
{ {
FSectorPortal *portal = sub->sector->ValidatePortal(ceiling ? sector_t::ceiling : sector_t::floor); FSectorPortal *portal = sub->sector->ValidatePortal(ceiling ? sector_t::ceiling : sector_t::floor);
if (portal && sectorPortals.empty()) PolyDrawSectorPortal *polyportal = nullptr;
if (portal)
{ {
sectorPortals.push_back(std::make_unique<PolyDrawSectorPortal>(portal, ceiling)); for (auto &p : sectorPortals)
{
if (p->Portal == portal) // To do: what other criterias do we need to check for?
{
polyportal = p.get();
break;
}
}
if (!portal)
{
sectorPortals.push_back(std::make_unique<PolyDrawSectorPortal>(portal, ceiling));
polyportal = sectorPortals.back().get();
}
} }
sector_t *fakesector = sub->sector->heightsec; sector_t *fakesector = sub->sector->heightsec;
@ -253,6 +266,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uin
{ {
args.stencilwritevalue = 252; args.stencilwritevalue = 252;
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy); PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw });
} }
} }
else else
@ -260,6 +274,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uin
if (portal) if (portal)
{ {
args.stencilwritevalue = 252; args.stencilwritevalue = 252;
polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw });
} }
else else
{ {
@ -335,6 +350,9 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uin
args.vinput = wallvert; args.vinput = wallvert;
args.vcount = 4; args.vcount = 4;
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy); PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
if (portal)
polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw });
} }
} }
} }

View file

@ -128,7 +128,7 @@ void RenderPolyPortal::RenderSubsector(subsector_t *sub)
SpriteRange RenderPolyPortal::GetSpritesForSector(sector_t *sector) SpriteRange RenderPolyPortal::GetSpritesForSector(sector_t *sector)
{ {
if (SectorSpriteRanges.size() < sector->sectornum || sector->sectornum < 0) if ((int)SectorSpriteRanges.size() < sector->sectornum || sector->sectornum < 0)
return SpriteRange(); return SpriteRange();
auto &range = SectorSpriteRanges[sector->sectornum]; auto &range = SectorSpriteRanges[sector->sectornum];
@ -191,11 +191,39 @@ void RenderPolyPortal::RenderLine(subsector_t *sub, seg_t *line, sector_t *front
void RenderPolyPortal::RenderTranslucent() void RenderPolyPortal::RenderTranslucent()
{ {
for (auto it = SectorPortals.rbegin(); it != SectorPortals.rend(); ++it) for (auto it = SectorPortals.rbegin(); it != SectorPortals.rend(); ++it)
{
(*it)->RenderTranslucent(); (*it)->RenderTranslucent();
PolyDrawArgs args;
args.objectToClip = &WorldToClip;
args.stenciltestvalue = 253;
args.stencilwritevalue = 1;
for (const auto &verts : (*it)->Shape)
{
args.vinput = verts.Vertices;
args.vcount = verts.Count;
args.ccw = verts.Ccw;
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
}
}
for (auto it = LinePortals.rbegin(); it != LinePortals.rend(); ++it) for (auto it = LinePortals.rbegin(); it != LinePortals.rend(); ++it)
{
(*it)->RenderTranslucent(); (*it)->RenderTranslucent();
PolyDrawArgs args;
args.objectToClip = &WorldToClip;
args.stenciltestvalue = 253;
args.stencilwritevalue = 1;
for (const auto &verts : (*it)->Shape)
{
args.vinput = verts.Vertices;
args.vcount = verts.Count;
args.ccw = verts.Ccw;
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
}
}
for (auto it = TranslucentObjects.rbegin(); it != TranslucentObjects.rend(); ++it) for (auto it = TranslucentObjects.rbegin(); it != TranslucentObjects.rend(); ++it)
{ {
auto &obj = *it; auto &obj = *it;
@ -237,23 +265,7 @@ void PolyDrawSectorPortal::Render()
return; return;
recursion++; recursion++;
int savedextralight = extralight; SaveGlobals();
DVector3 savedpos = ViewPos;
DAngle savedangle = ViewAngle;
double savedvisibility = R_GetVisibility();
AActor *savedcamera = camera;
sector_t *savedsector = viewsector;
// Don't let gun flashes brighten the sky box
ASkyViewpoint *sky = barrier_cast<ASkyViewpoint*>(Portal->mSkybox);
extralight = 0;
R_SetVisibility(sky->args[0] * 0.25f);
ViewPos = sky->InterpolatedPosition(r_TicFracF);
ViewAngle = savedangle + (sky->PrevAngles.Yaw + deltaangle(sky->PrevAngles.Yaw, sky->Angles.Yaw) * r_TicFracF);
camera = nullptr;
viewsector = Portal->mDestination;
R_SetViewAngle();
// To do: get this information from RenderPolyScene instead of duplicating the code.. // To do: get this information from RenderPolyScene instead of duplicating the code..
double radPitch = ViewPitch.Normalized180().Radians(); double radPitch = ViewPitch.Normalized180().Radians();
@ -276,6 +288,49 @@ void PolyDrawSectorPortal::Render()
RenderPortal.SetViewpoint(worldToClip, 252); RenderPortal.SetViewpoint(worldToClip, 252);
RenderPortal.Render(); RenderPortal.Render();
RestoreGlobals();
recursion--;
}
void PolyDrawSectorPortal::RenderTranslucent()
{
if (Portal->mType != PORTS_SKYVIEWPOINT)
return;
static int recursion = 0;
if (recursion >= 1/*r_portal_recursions*/)
return;
recursion++;
RenderPortal.RenderTranslucent();
recursion--;
}
void PolyDrawSectorPortal::SaveGlobals()
{
int savedextralight = extralight;
DVector3 savedpos = ViewPos;
DAngle savedangle = ViewAngle;
double savedvisibility = R_GetVisibility();
AActor *savedcamera = camera;
sector_t *savedsector = viewsector;
// Don't let gun flashes brighten the sky box
ASkyViewpoint *sky = barrier_cast<ASkyViewpoint*>(Portal->mSkybox);
extralight = 0;
R_SetVisibility(sky->args[0] * 0.25f);
ViewPos = sky->InterpolatedPosition(r_TicFracF);
ViewAngle = savedangle + (sky->PrevAngles.Yaw + deltaangle(sky->PrevAngles.Yaw, sky->Angles.Yaw) * r_TicFracF);
camera = nullptr;
viewsector = Portal->mDestination;
R_SetViewAngle();
}
void PolyDrawSectorPortal::RestoreGlobals()
{
camera = savedcamera; camera = savedcamera;
viewsector = savedsector; viewsector = savedsector;
ViewPos = savedpos; ViewPos = savedpos;
@ -283,16 +338,6 @@ void PolyDrawSectorPortal::Render()
extralight = savedextralight; extralight = savedextralight;
ViewAngle = savedangle; ViewAngle = savedangle;
R_SetViewAngle(); R_SetViewAngle();
recursion--;
}
void PolyDrawSectorPortal::RenderTranslucent()
{
/*if (Portal->mType != PORTS_SKYVIEWPOINT)
return;
RenderPortal.RenderTranslucent();*/
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View file

@ -110,6 +110,14 @@ private:
std::vector<std::unique_ptr<PolyDrawLinePortal>> LinePortals; std::vector<std::unique_ptr<PolyDrawLinePortal>> LinePortals;
}; };
struct PolyPortalVertexRange
{
PolyPortalVertexRange(const TriVertex *vertices, int count, bool ccw) : Vertices(vertices), Count(count), Ccw(ccw) { }
const TriVertex *Vertices;
int Count;
bool Ccw;
};
class PolyDrawSectorPortal class PolyDrawSectorPortal
{ {
public: public:
@ -118,10 +126,22 @@ public:
void Render(); void Render();
void RenderTranslucent(); void RenderTranslucent();
private:
FSectorPortal *Portal; FSectorPortal *Portal;
std::vector<PolyPortalVertexRange> Shape;
private:
void SaveGlobals();
void RestoreGlobals();
bool Ceiling; bool Ceiling;
RenderPolyPortal RenderPortal; RenderPolyPortal RenderPortal;
int savedextralight;
DVector3 savedpos;
DAngle savedangle;
double savedvisibility;
AActor *savedcamera;
sector_t *savedsector;
}; };
class PolyDrawLinePortal class PolyDrawLinePortal
@ -132,6 +152,8 @@ public:
void Render(); void Render();
void RenderTranslucent(); void RenderTranslucent();
std::vector<PolyPortalVertexRange> Shape;
private: private:
line_t *Src; line_t *Src;
line_t *Dest; line_t *Dest;

View file

@ -312,7 +312,7 @@ void PolyWallTextureCoords::CalcU(FTexture *tex, const seg_t *lineseg, const lin
double lineLength = side->TexelLength; double lineLength = side->TexelLength;
double lineStart = 0.0; double lineStart = 0.0;
bool entireSegment = ((lineseg->v1 == line->v1) && (lineseg->v2 == line->v2) || (lineseg->v2 == line->v1) && (lineseg->v1 == line->v2)); bool entireSegment = ((lineseg->v1 == line->v1) && (lineseg->v2 == line->v2)) || ((lineseg->v2 == line->v1) && (lineseg->v1 == line->v2));
if (!entireSegment) if (!entireSegment)
{ {
lineLength = (lineseg->v2->fPos() - lineseg->v1->fPos()).Length(); lineLength = (lineseg->v2->fPos() - lineseg->v1->fPos()).Length();