mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 23:12:24 +00:00
Add some portal segment culling and disable sector portals for now
This commit is contained in:
parent
dc07c2075f
commit
f1df400cc7
10 changed files with 129 additions and 29 deletions
|
@ -30,7 +30,6 @@
|
||||||
|
|
||||||
void PolyCull::CullScene(const TriMatrix &worldToClip, const Vec4f &portalClipPlane)
|
void PolyCull::CullScene(const TriMatrix &worldToClip, const Vec4f &portalClipPlane)
|
||||||
{
|
{
|
||||||
ClearSolidSegments();
|
|
||||||
PvsSectors.clear();
|
PvsSectors.clear();
|
||||||
frustumPlanes = FrustumPlanes(worldToClip);
|
frustumPlanes = FrustumPlanes(worldToClip);
|
||||||
PortalClipPlane = portalClipPlane;
|
PortalClipPlane = portalClipPlane;
|
||||||
|
@ -42,8 +41,6 @@ void PolyCull::CullScene(const TriMatrix &worldToClip, const Vec4f &portalClipPl
|
||||||
CullSubsector(subsectors);
|
CullSubsector(subsectors);
|
||||||
else
|
else
|
||||||
CullNode(nodes + numnodes - 1); // The head node is the last node output.
|
CullNode(nodes + numnodes - 1); // The head node is the last node output.
|
||||||
|
|
||||||
ClearSolidSegments();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PolyCull::CullNode(void *node)
|
void PolyCull::CullNode(void *node)
|
||||||
|
@ -109,6 +106,18 @@ void PolyCull::ClearSolidSegments()
|
||||||
SolidSegments.push_back({ SolidCullScale , 0x7fff });
|
SolidSegments.push_back({ SolidCullScale , 0x7fff });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PolyCull::InvertSegments()
|
||||||
|
{
|
||||||
|
TempInvertSolidSegments.swap(SolidSegments);
|
||||||
|
ClearSolidSegments();
|
||||||
|
int x = -0x7fff;
|
||||||
|
for (const auto &segment : TempInvertSolidSegments)
|
||||||
|
{
|
||||||
|
MarkSegmentCulled(x, segment.X1 - 1);
|
||||||
|
x = segment.X2 + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool PolyCull::IsSegmentCulled(int x1, int x2) const
|
bool PolyCull::IsSegmentCulled(int x1, int x2) const
|
||||||
{
|
{
|
||||||
x1 = clamp(x1, -0x7ffe, 0x7ffd);
|
x1 = clamp(x1, -0x7ffe, 0x7ffd);
|
||||||
|
|
|
@ -35,11 +35,13 @@ enum class LineSegmentRange
|
||||||
class PolyCull
|
class PolyCull
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
void ClearSolidSegments();
|
||||||
void CullScene(const TriMatrix &worldToClip, const Vec4f &portalClipPlane);
|
void CullScene(const TriMatrix &worldToClip, const Vec4f &portalClipPlane);
|
||||||
|
|
||||||
LineSegmentRange GetSegmentRangeForLine(double x1, double y1, double x2, double y2, int &sx1, int &sx2) const;
|
LineSegmentRange GetSegmentRangeForLine(double x1, double y1, double x2, double y2, int &sx1, int &sx2) const;
|
||||||
void MarkSegmentCulled(int x1, int x2);
|
void MarkSegmentCulled(int x1, int x2);
|
||||||
bool IsSegmentCulled(int x1, int x2) const;
|
bool IsSegmentCulled(int x1, int x2) const;
|
||||||
|
void InvertSegments();
|
||||||
|
|
||||||
std::vector<subsector_t *> PvsSectors;
|
std::vector<subsector_t *> PvsSectors;
|
||||||
double MaxCeilingHeight = 0.0;
|
double MaxCeilingHeight = 0.0;
|
||||||
|
@ -60,9 +62,8 @@ private:
|
||||||
// Returns true if some part of the bbox might be visible.
|
// Returns true if some part of the bbox might be visible.
|
||||||
bool CheckBBox(float *bspcoord);
|
bool CheckBBox(float *bspcoord);
|
||||||
|
|
||||||
void ClearSolidSegments();
|
|
||||||
|
|
||||||
std::vector<SolidSegment> SolidSegments;
|
std::vector<SolidSegment> SolidSegments;
|
||||||
|
std::vector<SolidSegment> TempInvertSolidSegments;
|
||||||
const int SolidCullScale = 3000;
|
const int SolidCullScale = 3000;
|
||||||
|
|
||||||
FrustumPlanes frustumPlanes;
|
FrustumPlanes frustumPlanes;
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
EXTERN_CVAR(Int, r_3dfloors)
|
EXTERN_CVAR(Int, r_3dfloors)
|
||||||
|
|
||||||
void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const Vec4f &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals)
|
void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals)
|
||||||
{
|
{
|
||||||
RenderPolyPlane plane;
|
RenderPolyPlane plane;
|
||||||
|
|
||||||
|
@ -84,8 +84,8 @@ void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const Vec4f &cl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
plane.Render(worldToClip, clipPlane, sub, subsectorDepth, stencilValue, true, skyCeilingHeight, sectorPortals);
|
plane.Render(worldToClip, clipPlane, cull, sub, subsectorDepth, stencilValue, true, skyCeilingHeight, sectorPortals);
|
||||||
plane.Render(worldToClip, clipPlane, sub, subsectorDepth, stencilValue, false, skyFloorHeight, sectorPortals);
|
plane.Render(worldToClip, clipPlane, cull, sub, subsectorDepth, stencilValue, false, skyFloorHeight, sectorPortals);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const Vec4f &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakeFloor)
|
void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const Vec4f &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakeFloor)
|
||||||
|
@ -147,9 +147,10 @@ void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const Vec4f &c
|
||||||
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
|
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderPolyPlane::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals)
|
void RenderPolyPlane::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals)
|
||||||
{
|
{
|
||||||
FSectorPortal *portal = sub->sector->ValidatePortal(ceiling ? sector_t::ceiling : sector_t::floor);
|
std::vector<PolyPortalSegment> portalSegments;
|
||||||
|
FSectorPortal *portal = nullptr;// sub->sector->ValidatePortal(ceiling ? sector_t::ceiling : sector_t::floor);
|
||||||
PolyDrawSectorPortal *polyportal = nullptr;
|
PolyDrawSectorPortal *polyportal = nullptr;
|
||||||
if (portal && (portal->mFlags & PORTSF_INSKYBOX) == PORTSF_INSKYBOX) // Do not recurse into portals we already recursed into
|
if (portal && (portal->mFlags & PORTSF_INSKYBOX) == PORTSF_INSKYBOX) // Do not recurse into portals we already recursed into
|
||||||
portal = nullptr;
|
portal = nullptr;
|
||||||
|
@ -157,7 +158,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const Vec4f &clipPlan
|
||||||
{
|
{
|
||||||
for (auto &p : sectorPortals)
|
for (auto &p : sectorPortals)
|
||||||
{
|
{
|
||||||
if (p->Portal == portal) // To do: what other criterias do we need to check for?
|
if (p->Portal == portal) // To do: what other criteria do we need to check for?
|
||||||
{
|
{
|
||||||
polyportal = p.get();
|
polyportal = p.get();
|
||||||
break;
|
break;
|
||||||
|
@ -168,6 +169,54 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const Vec4f &clipPlan
|
||||||
sectorPortals.push_back(std::make_unique<PolyDrawSectorPortal>(portal, ceiling));
|
sectorPortals.push_back(std::make_unique<PolyDrawSectorPortal>(portal, ceiling));
|
||||||
polyportal = sectorPortals.back().get();
|
polyportal = sectorPortals.back().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate portal clipping
|
||||||
|
|
||||||
|
DVector2 v;
|
||||||
|
bool inside = true;
|
||||||
|
double vdist = 1.0e10;
|
||||||
|
|
||||||
|
portalSegments.reserve(sub->numlines);
|
||||||
|
for (uint32_t i = 0; i < sub->numlines; i++)
|
||||||
|
{
|
||||||
|
seg_t *line = &sub->firstline[i];
|
||||||
|
|
||||||
|
DVector2 pt1 = line->v1->fPos() - ViewPos;
|
||||||
|
DVector2 pt2 = line->v2->fPos() - ViewPos;
|
||||||
|
if (pt1.Y * (pt1.X - pt2.X) + pt1.X * (pt2.Y - pt1.Y) >= 0)
|
||||||
|
inside = false;
|
||||||
|
|
||||||
|
double dist = pt1.LengthSquared();
|
||||||
|
if (dist < vdist)
|
||||||
|
{
|
||||||
|
v = line->v1->fPos();
|
||||||
|
vdist = dist;
|
||||||
|
}
|
||||||
|
dist = pt2.LengthSquared();
|
||||||
|
if (dist < vdist)
|
||||||
|
{
|
||||||
|
v = line->v2->fPos();
|
||||||
|
vdist = dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sx1, sx2;
|
||||||
|
LineSegmentRange range = cull.GetSegmentRangeForLine(line->v1->fX(), line->v1->fY(), line->v2->fX(), line->v2->fY(), sx1, sx2);
|
||||||
|
if (range == LineSegmentRange::HasSegment)
|
||||||
|
portalSegments.push_back({ sx1, sx2 });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inside)
|
||||||
|
{
|
||||||
|
polyportal->PortalPlane = Vec4f(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
else if(polyportal->PortalPlane == Vec4f(0.0f) || Vec4f::dot(polyportal->PortalPlane, Vec4f((float)v.X, (float)v.Y, 0.0f, 1.0f)) > 0.0f)
|
||||||
|
{
|
||||||
|
DVector2 planePos = v;
|
||||||
|
DVector2 planeNormal = v - ViewPos;
|
||||||
|
planeNormal.MakeUnit();
|
||||||
|
double planeD = -(planeNormal | (planePos + planeNormal * 0.001));
|
||||||
|
polyportal->PortalPlane = Vec4f((float)planeNormal.X, (float)planeNormal.Y, 0.0f, (float)planeD);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sector_t *fakesector = sub->sector->heightsec;
|
sector_t *fakesector = sub->sector->heightsec;
|
||||||
|
@ -300,6 +349,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const Vec4f &clipPlan
|
||||||
args.stencilwritevalue = polyportal->StencilValue;
|
args.stencilwritevalue = polyportal->StencilValue;
|
||||||
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
|
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
|
||||||
polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw, subsectorDepth });
|
polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw, subsectorDepth });
|
||||||
|
polyportal->Segments.insert(polyportal->Segments.end(), portalSegments.begin(), portalSegments.end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -308,6 +358,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const Vec4f &clipPlan
|
||||||
{
|
{
|
||||||
args.stencilwritevalue = polyportal->StencilValue;
|
args.stencilwritevalue = polyportal->StencilValue;
|
||||||
polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw, subsectorDepth });
|
polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw, subsectorDepth });
|
||||||
|
polyportal->Segments.insert(polyportal->Segments.end(), portalSegments.begin(), portalSegments.end());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -385,7 +436,10 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const Vec4f &clipPlan
|
||||||
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
|
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
|
||||||
|
|
||||||
if (portal)
|
if (portal)
|
||||||
|
{
|
||||||
polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw, subsectorDepth });
|
polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw, subsectorDepth });
|
||||||
|
polyportal->Segments.insert(polyportal->Segments.end(), portalSegments.begin(), portalSegments.end());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,12 +25,13 @@
|
||||||
#include "r_poly_triangle.h"
|
#include "r_poly_triangle.h"
|
||||||
|
|
||||||
class PolyDrawSectorPortal;
|
class PolyDrawSectorPortal;
|
||||||
|
class PolyCull;
|
||||||
class Vec4f;
|
class Vec4f;
|
||||||
|
|
||||||
class RenderPolyPlane
|
class RenderPolyPlane
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void RenderPlanes(const TriMatrix &worldToClip, const Vec4f &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals);
|
static void RenderPlanes(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct UVTransform
|
struct UVTransform
|
||||||
|
@ -48,6 +49,6 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
void Render3DFloor(const TriMatrix &worldToClip, const Vec4f &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakefloor);
|
void Render3DFloor(const TriMatrix &worldToClip, const Vec4f &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakefloor);
|
||||||
void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals);
|
void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals);
|
||||||
TriVertex PlaneVertex(vertex_t *v1, double height, const UVTransform &transform);
|
TriVertex PlaneVertex(vertex_t *v1, double height, const UVTransform &transform);
|
||||||
};
|
};
|
||||||
|
|
|
@ -64,7 +64,8 @@ void PolyDrawSectorPortal::Render(int portalDepth)
|
||||||
TriMatrix::translate((float)-ViewPos.X, (float)-ViewPos.Y, (float)-ViewPos.Z);
|
TriMatrix::translate((float)-ViewPos.X, (float)-ViewPos.Y, (float)-ViewPos.Z);
|
||||||
TriMatrix worldToClip = TriMatrix::perspective(fovy, ratio, 5.0f, 65535.0f) * worldToView;
|
TriMatrix worldToClip = TriMatrix::perspective(fovy, ratio, 5.0f, 65535.0f) * worldToView;
|
||||||
|
|
||||||
RenderPortal.SetViewpoint(worldToClip, Vec4f(0.0f, 0.0f, 0.0f, 1.0f), StencilValue);
|
RenderPortal.SetViewpoint(worldToClip, PortalPlane, StencilValue);
|
||||||
|
RenderPortal.SetPortalSegments(Segments);
|
||||||
RenderPortal.Render(portalDepth);
|
RenderPortal.Render(portalDepth);
|
||||||
|
|
||||||
RestoreGlobals();
|
RestoreGlobals();
|
||||||
|
@ -175,6 +176,7 @@ void PolyDrawLinePortal::Render(int portalDepth)
|
||||||
Vec4f portalPlane((float)planeNormal.X, (float)planeNormal.Y, 0.0f, (float)planeD);
|
Vec4f portalPlane((float)planeNormal.X, (float)planeNormal.Y, 0.0f, (float)planeD);
|
||||||
|
|
||||||
RenderPortal.SetViewpoint(worldToClip, portalPlane, StencilValue);
|
RenderPortal.SetViewpoint(worldToClip, portalPlane, StencilValue);
|
||||||
|
RenderPortal.SetPortalSegments(Segments);
|
||||||
RenderPortal.Render(portalDepth);
|
RenderPortal.Render(portalDepth);
|
||||||
|
|
||||||
RestoreGlobals();
|
RestoreGlobals();
|
||||||
|
|
|
@ -33,6 +33,13 @@ struct PolyPortalVertexRange
|
||||||
uint32_t SubsectorDepth;
|
uint32_t SubsectorDepth;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PolyPortalSegment
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PolyPortalSegment(int x1, int x2) : X1(x1), X2(x2) { }
|
||||||
|
int X1, X2;
|
||||||
|
};
|
||||||
|
|
||||||
class PolyDrawSectorPortal
|
class PolyDrawSectorPortal
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -44,6 +51,8 @@ public:
|
||||||
FSectorPortal *Portal = nullptr;
|
FSectorPortal *Portal = nullptr;
|
||||||
uint32_t StencilValue = 0;
|
uint32_t StencilValue = 0;
|
||||||
std::vector<PolyPortalVertexRange> Shape;
|
std::vector<PolyPortalVertexRange> Shape;
|
||||||
|
std::vector<PolyPortalSegment> Segments;
|
||||||
|
Vec4f PortalPlane = Vec4f(0.0f);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SaveGlobals();
|
void SaveGlobals();
|
||||||
|
@ -73,6 +82,7 @@ public:
|
||||||
line_t *Mirror = nullptr;
|
line_t *Mirror = nullptr;
|
||||||
uint32_t StencilValue = 0;
|
uint32_t StencilValue = 0;
|
||||||
std::vector<PolyPortalVertexRange> Shape;
|
std::vector<PolyPortalVertexRange> Shape;
|
||||||
|
std::vector<PolyPortalSegment> Segments;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SaveGlobals();
|
void SaveGlobals();
|
||||||
|
|
|
@ -50,10 +50,24 @@ void RenderPolyScene::SetViewpoint(const TriMatrix &worldToClip, const Vec4f &po
|
||||||
PortalPlane = portalPlane;
|
PortalPlane = portalPlane;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderPolyScene::SetPortalSegments(const std::vector<PolyPortalSegment> &segments)
|
||||||
|
{
|
||||||
|
Cull.ClearSolidSegments();
|
||||||
|
for (const auto &segment : segments)
|
||||||
|
{
|
||||||
|
Cull.MarkSegmentCulled(segment.X1, segment.X2);
|
||||||
|
}
|
||||||
|
Cull.InvertSegments();
|
||||||
|
PortalSegmentsAdded = true;
|
||||||
|
}
|
||||||
|
|
||||||
void RenderPolyScene::Render(int portalDepth)
|
void RenderPolyScene::Render(int portalDepth)
|
||||||
{
|
{
|
||||||
ClearBuffers();
|
ClearBuffers();
|
||||||
|
if (!PortalSegmentsAdded)
|
||||||
|
Cull.ClearSolidSegments();
|
||||||
Cull.CullScene(WorldToClip, PortalPlane);
|
Cull.CullScene(WorldToClip, PortalPlane);
|
||||||
|
Cull.ClearSolidSegments();
|
||||||
RenderSectors();
|
RenderSectors();
|
||||||
RenderPortals(portalDepth);
|
RenderPortals(portalDepth);
|
||||||
}
|
}
|
||||||
|
@ -91,7 +105,7 @@ void RenderPolyScene::RenderSubsector(subsector_t *sub)
|
||||||
|
|
||||||
if (sub->sector->CenterFloor() != sub->sector->CenterCeiling())
|
if (sub->sector->CenterFloor() != sub->sector->CenterCeiling())
|
||||||
{
|
{
|
||||||
RenderPolyPlane::RenderPlanes(WorldToClip, PortalPlane, sub, subsectorDepth, StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, SectorPortals);
|
RenderPolyPlane::RenderPlanes(WorldToClip, PortalPlane, Cull, sub, subsectorDepth, StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, SectorPortals);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < sub->numlines; i++)
|
for (uint32_t i = 0; i < sub->numlines; i++)
|
||||||
|
@ -199,12 +213,12 @@ void RenderPolyScene::RenderLine(subsector_t *sub, seg_t *line, sector_t *fronts
|
||||||
if (!(fakeFloor->flags & FF_EXISTS)) continue;
|
if (!(fakeFloor->flags & FF_EXISTS)) continue;
|
||||||
if (!(fakeFloor->flags & FF_RENDERPLANES)) continue;
|
if (!(fakeFloor->flags & FF_RENDERPLANES)) continue;
|
||||||
if (!fakeFloor->model) continue;
|
if (!fakeFloor->model) continue;
|
||||||
RenderPolyWall::Render3DFloorLine(WorldToClip, PortalPlane, line, frontsector, subsectorDepth, StencilValue, fakeFloor, TranslucentObjects);
|
RenderPolyWall::Render3DFloorLine(WorldToClip, PortalPlane, Cull, line, frontsector, subsectorDepth, StencilValue, fakeFloor, TranslucentObjects);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render wall, and update culling info if its an occlusion blocker
|
// Render wall, and update culling info if its an occlusion blocker
|
||||||
if (RenderPolyWall::RenderLine(WorldToClip, PortalPlane, line, frontsector, subsectorDepth, StencilValue, TranslucentObjects, LinePortals))
|
if (RenderPolyWall::RenderLine(WorldToClip, PortalPlane, Cull, line, frontsector, subsectorDepth, StencilValue, TranslucentObjects, LinePortals))
|
||||||
{
|
{
|
||||||
if (segmentRange == LineSegmentRange::HasSegment)
|
if (segmentRange == LineSegmentRange::HasSegment)
|
||||||
Cull.MarkSegmentCulled(sx1, sx2);
|
Cull.MarkSegmentCulled(sx1, sx2);
|
||||||
|
@ -332,7 +346,7 @@ void RenderPolyScene::RenderTranslucent(int portalDepth)
|
||||||
}
|
}
|
||||||
else if (!obj.thing)
|
else if (!obj.thing)
|
||||||
{
|
{
|
||||||
obj.wall.Render(WorldToClip, PortalPlane);
|
obj.wall.Render(WorldToClip, PortalPlane, Cull);
|
||||||
}
|
}
|
||||||
else if ((obj.thing->renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE)
|
else if ((obj.thing->renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE)
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,6 +67,7 @@ public:
|
||||||
|
|
||||||
class PolyDrawSectorPortal;
|
class PolyDrawSectorPortal;
|
||||||
class PolyDrawLinePortal;
|
class PolyDrawLinePortal;
|
||||||
|
class PolyPortalSegment;
|
||||||
|
|
||||||
// Renders everything from a specific viewpoint
|
// Renders everything from a specific viewpoint
|
||||||
class RenderPolyScene
|
class RenderPolyScene
|
||||||
|
@ -75,6 +76,7 @@ public:
|
||||||
RenderPolyScene();
|
RenderPolyScene();
|
||||||
~RenderPolyScene();
|
~RenderPolyScene();
|
||||||
void SetViewpoint(const TriMatrix &worldToClip, const Vec4f &portalPlane, uint32_t stencilValue);
|
void SetViewpoint(const TriMatrix &worldToClip, const Vec4f &portalPlane, uint32_t stencilValue);
|
||||||
|
void SetPortalSegments(const std::vector<PolyPortalSegment> &segments);
|
||||||
void Render(int portalDepth);
|
void Render(int portalDepth);
|
||||||
void RenderTranslucent(int portalDepth);
|
void RenderTranslucent(int portalDepth);
|
||||||
|
|
||||||
|
@ -100,4 +102,5 @@ private:
|
||||||
|
|
||||||
std::vector<std::unique_ptr<PolyDrawSectorPortal>> SectorPortals;
|
std::vector<std::unique_ptr<PolyDrawSectorPortal>> SectorPortals;
|
||||||
std::vector<std::unique_ptr<PolyDrawLinePortal>> LinePortals;
|
std::vector<std::unique_ptr<PolyDrawLinePortal>> LinePortals;
|
||||||
|
bool PortalSegmentsAdded = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
|
|
||||||
EXTERN_CVAR(Bool, r_drawmirrors)
|
EXTERN_CVAR(Bool, r_drawmirrors)
|
||||||
|
|
||||||
bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals)
|
bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals)
|
||||||
{
|
{
|
||||||
PolyDrawLinePortal *polyportal = nullptr;
|
PolyDrawLinePortal *polyportal = nullptr;
|
||||||
if (line->backsector == nullptr && line->linedef && line->sidedef == line->linedef->sidedef[0] && (line->linedef->special == Line_Mirror && r_drawmirrors))
|
if (line->backsector == nullptr && line->linedef && line->sidedef == line->linedef->sidedef[0] && (line->linedef->special == Line_Mirror && r_drawmirrors))
|
||||||
|
@ -91,7 +91,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const Vec4f &clipP
|
||||||
wall.UnpeggedCeil = frontceilz1;
|
wall.UnpeggedCeil = frontceilz1;
|
||||||
wall.Texpart = side_t::mid;
|
wall.Texpart = side_t::mid;
|
||||||
wall.Polyportal = polyportal;
|
wall.Polyportal = polyportal;
|
||||||
wall.Render(worldToClip, clipPlane);
|
wall.Render(worldToClip, clipPlane, cull);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const Vec4f &clipP
|
||||||
wall.BottomZ = topfloorz1;
|
wall.BottomZ = topfloorz1;
|
||||||
wall.UnpeggedCeil = topceilz1;
|
wall.UnpeggedCeil = topceilz1;
|
||||||
wall.Texpart = side_t::top;
|
wall.Texpart = side_t::top;
|
||||||
wall.Render(worldToClip, clipPlane);
|
wall.Render(worldToClip, clipPlane, cull);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((bottomfloorz1 < bottomceilz1 || bottomfloorz2 < bottomceilz2) && line->sidedef)
|
if ((bottomfloorz1 < bottomceilz1 || bottomfloorz2 < bottomceilz2) && line->sidedef)
|
||||||
|
@ -136,7 +136,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const Vec4f &clipP
|
||||||
wall.BottomZ = bottomfloorz2;
|
wall.BottomZ = bottomfloorz2;
|
||||||
wall.UnpeggedCeil = topceilz1;
|
wall.UnpeggedCeil = topceilz1;
|
||||||
wall.Texpart = side_t::bottom;
|
wall.Texpart = side_t::bottom;
|
||||||
wall.Render(worldToClip, clipPlane);
|
wall.Render(worldToClip, clipPlane, cull);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line->sidedef)
|
if (line->sidedef)
|
||||||
|
@ -155,14 +155,14 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const Vec4f &clipP
|
||||||
if (polyportal)
|
if (polyportal)
|
||||||
{
|
{
|
||||||
wall.Polyportal = polyportal;
|
wall.Polyportal = polyportal;
|
||||||
wall.Render(worldToClip, clipPlane);
|
wall.Render(worldToClip, clipPlane, cull);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return polyportal != nullptr;
|
return polyportal != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderPolyWall::Render3DFloorLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject> &translucentWallsOutput)
|
void RenderPolyWall::Render3DFloorLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject> &translucentWallsOutput)
|
||||||
{
|
{
|
||||||
double frontceilz1 = fakeFloor->top.plane->ZatPoint(line->v1);
|
double frontceilz1 = fakeFloor->top.plane->ZatPoint(line->v1);
|
||||||
double frontfloorz1 = fakeFloor->bottom.plane->ZatPoint(line->v1);
|
double frontfloorz1 = fakeFloor->bottom.plane->ZatPoint(line->v1);
|
||||||
|
@ -182,7 +182,7 @@ void RenderPolyWall::Render3DFloorLine(const TriMatrix &worldToClip, const Vec4f
|
||||||
wall.BottomZ = frontfloorz1;
|
wall.BottomZ = frontfloorz1;
|
||||||
wall.UnpeggedCeil = frontceilz1;
|
wall.UnpeggedCeil = frontceilz1;
|
||||||
wall.Texpart = side_t::mid;
|
wall.Texpart = side_t::mid;
|
||||||
wall.Render(worldToClip, clipPlane);
|
wall.Render(worldToClip, clipPlane, cull);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderPolyWall::SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2)
|
void RenderPolyWall::SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2)
|
||||||
|
@ -195,7 +195,7 @@ void RenderPolyWall::SetCoords(const DVector2 &v1, const DVector2 &v2, double ce
|
||||||
this->floor2 = floor2;
|
this->floor2 = floor2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderPolyWall::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane)
|
void RenderPolyWall::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull)
|
||||||
{
|
{
|
||||||
FTexture *tex = GetTexture();
|
FTexture *tex = GetTexture();
|
||||||
if (!tex && !Polyportal)
|
if (!tex && !Polyportal)
|
||||||
|
@ -266,6 +266,11 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane
|
||||||
args.stencilwritevalue = Polyportal->StencilValue;
|
args.stencilwritevalue = Polyportal->StencilValue;
|
||||||
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
|
PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy);
|
||||||
Polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw, args.uniforms.subsectorDepth });
|
Polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw, args.uniforms.subsectorDepth });
|
||||||
|
|
||||||
|
int sx1, sx2;
|
||||||
|
LineSegmentRange range = cull.GetSegmentRangeForLine(v1.X, v1.Y, v2.X, v2.Y, sx1, sx2);
|
||||||
|
if (range == LineSegmentRange::HasSegment)
|
||||||
|
Polyportal->Segments.push_back({ sx1, sx2 });
|
||||||
}
|
}
|
||||||
else if (!Masked)
|
else if (!Masked)
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,16 +26,17 @@
|
||||||
|
|
||||||
class PolyTranslucentObject;
|
class PolyTranslucentObject;
|
||||||
class PolyDrawLinePortal;
|
class PolyDrawLinePortal;
|
||||||
|
class PolyCull;
|
||||||
class Vec4f;
|
class Vec4f;
|
||||||
|
|
||||||
class RenderPolyWall
|
class RenderPolyWall
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static bool RenderLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals);
|
static bool RenderLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals);
|
||||||
static void Render3DFloorLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject> &translucentWallsOutput);
|
static void Render3DFloorLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject> &translucentWallsOutput);
|
||||||
|
|
||||||
void SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2);
|
void SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2);
|
||||||
void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane);
|
void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull);
|
||||||
|
|
||||||
DVector2 v1;
|
DVector2 v1;
|
||||||
DVector2 v2;
|
DVector2 v2;
|
||||||
|
|
Loading…
Reference in a new issue