mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 21:11:39 +00:00
- initialize clipper with the view frustum for better performance
- change translucent objects to be pointers for faster sorting
This commit is contained in:
parent
6760e01a0d
commit
321e2da979
6 changed files with 53 additions and 18 deletions
|
@ -287,6 +287,23 @@ bool PolyCull::GetAnglesForLine(double x1, double y1, double x2, double y2, angl
|
|||
return !IsSegmentCulled(angle1, angle2);
|
||||
}
|
||||
|
||||
void PolyCull::MarkViewFrustum()
|
||||
{
|
||||
// Clips things outside the viewing frustum.
|
||||
auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
|
||||
auto &viewwindow = PolyRenderer::Instance()->Viewwindow;
|
||||
double tilt = fabs(viewpoint.Angles.Pitch.Degrees);
|
||||
if (tilt > 46.0) // If the pitch is larger than this you can look all around
|
||||
return;
|
||||
|
||||
double floatangle = 2.0 + (45.0 + ((tilt / 1.9)))*viewpoint.FieldOfView.Degrees*48.0 / AspectMultiplier(viewwindow.WidescreenRatio) / 90.0;
|
||||
angle_t a1 = DAngle(floatangle).BAMs();
|
||||
if (a1 < ANGLE_180)
|
||||
{
|
||||
MarkSegmentCulled(AngleToPseudo(viewpoint.Angles.Yaw.BAMs() + a1), AngleToPseudo(viewpoint.Angles.Yaw.BAMs() - a1));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// ! Returns the pseudoangle between the line p1 to (infinity, p1.y) and the
|
||||
|
@ -320,3 +337,16 @@ angle_t PolyCull::PointToPseudoAngle(double x, double y)
|
|||
return xs_Fix<30>::ToFix(result);
|
||||
}
|
||||
}
|
||||
|
||||
angle_t PolyCull::AngleToPseudo(angle_t ang)
|
||||
{
|
||||
double vecx = cos(ang * M_PI / ANGLE_180);
|
||||
double vecy = sin(ang * M_PI / ANGLE_180);
|
||||
|
||||
double result = vecy / (fabs(vecx) + fabs(vecy));
|
||||
if (vecx < 0)
|
||||
{
|
||||
result = 2.f - result;
|
||||
}
|
||||
return xs_Fix<30>::ToFix(result);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ public:
|
|||
void MarkSegmentCulled(angle_t angle1, angle_t angle2);
|
||||
bool IsSegmentCulled(angle_t angle1, angle_t angle2) const;
|
||||
void InvertSegments();
|
||||
void MarkViewFrustum();
|
||||
|
||||
std::vector<subsector_t *> PvsSectors;
|
||||
double MaxCeilingHeight = 0.0;
|
||||
|
@ -64,4 +65,5 @@ private:
|
|||
Vec4f PortalClipPlane;
|
||||
|
||||
static angle_t PointToPseudoAngle(double x, double y);
|
||||
static angle_t AngleToPseudo(angle_t ang);
|
||||
};
|
||||
|
|
|
@ -73,6 +73,7 @@ void RenderPolyScene::Render(int portalDepth)
|
|||
ClearBuffers();
|
||||
if (!PortalSegmentsAdded)
|
||||
Cull.ClearSolidSegments();
|
||||
Cull.MarkViewFrustum();
|
||||
Cull.CullScene(WorldToClip, PortalPlane);
|
||||
Cull.ClearSolidSegments();
|
||||
RenderSectors();
|
||||
|
@ -124,6 +125,8 @@ void RenderPolyScene::RenderSubsector(subsector_t *sub)
|
|||
}
|
||||
}
|
||||
|
||||
RenderMemory &memory = PolyRenderer::Instance()->FrameMemory;
|
||||
|
||||
bool mainBSP = ((unsigned int)(sub->Index()) < level.subsectors.Size());
|
||||
if (mainBSP)
|
||||
{
|
||||
|
@ -131,7 +134,7 @@ void RenderPolyScene::RenderSubsector(subsector_t *sub)
|
|||
for (int i = ParticlesInSubsec[subsectorIndex]; i != NO_PARTICLE; i = Particles[i].snext)
|
||||
{
|
||||
particle_t *particle = Particles + i;
|
||||
TranslucentObjects.push_back({ particle, sub, subsectorDepth });
|
||||
TranslucentObjects.push_back(memory.NewObject<PolyTranslucentObject>(particle, sub, subsectorDepth));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,7 +149,7 @@ void RenderPolyScene::RenderSprite(AActor *thing, double sortDistance, const DVe
|
|||
subsector_t *sub = &level.subsectors[0];
|
||||
auto it = SubsectorDepths.find(sub);
|
||||
if (it != SubsectorDepths.end())
|
||||
TranslucentObjects.push_back({ thing, sub, it->second, sortDistance, 0.0f, 1.0f });
|
||||
TranslucentObjects.push_back(PolyRenderer::Instance()->FrameMemory.NewObject<PolyTranslucentObject>(thing, sub, it->second, sortDistance, 0.0f, 1.0f));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -187,7 +190,7 @@ void RenderPolyScene::RenderSprite(AActor *thing, double sortDistance, DVector2
|
|||
|
||||
auto it = SubsectorDepths.find(sub);
|
||||
if (it != SubsectorDepths.end())
|
||||
TranslucentObjects.push_back({ thing, sub, it->second, sortDistance, (float)t1, (float)t2 });
|
||||
TranslucentObjects.push_back(PolyRenderer::Instance()->FrameMemory.NewObject<PolyTranslucentObject>(thing, sub, it->second, sortDistance, (float)t1, (float)t2));
|
||||
}
|
||||
|
||||
void RenderPolyScene::RenderLine(subsector_t *sub, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth)
|
||||
|
@ -347,29 +350,29 @@ void RenderPolyScene::RenderTranslucent(int portalDepth)
|
|||
}
|
||||
}
|
||||
|
||||
std::stable_sort(TranslucentObjects.begin(), TranslucentObjects.end());
|
||||
std::stable_sort(TranslucentObjects.begin(), TranslucentObjects.end(), [](auto a, auto b) { return *a < *b; });
|
||||
|
||||
for (auto it = TranslucentObjects.rbegin(); it != TranslucentObjects.rend(); ++it)
|
||||
{
|
||||
auto &obj = *it;
|
||||
if (obj.particle)
|
||||
PolyTranslucentObject *obj = *it;
|
||||
if (obj->particle)
|
||||
{
|
||||
RenderPolyParticle spr;
|
||||
spr.Render(WorldToClip, PortalPlane, obj.particle, obj.sub, obj.subsectorDepth, StencilValue + 1);
|
||||
spr.Render(WorldToClip, PortalPlane, obj->particle, obj->sub, obj->subsectorDepth, StencilValue + 1);
|
||||
}
|
||||
else if (!obj.thing)
|
||||
else if (!obj->thing)
|
||||
{
|
||||
obj.wall.Render(WorldToClip, PortalPlane, Cull);
|
||||
obj->wall.Render(WorldToClip, PortalPlane, Cull);
|
||||
}
|
||||
else if ((obj.thing->renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE)
|
||||
else if ((obj->thing->renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE)
|
||||
{
|
||||
RenderPolyWallSprite wallspr;
|
||||
wallspr.Render(WorldToClip, PortalPlane, obj.thing, obj.sub, obj.subsectorDepth, StencilValue + 1);
|
||||
wallspr.Render(WorldToClip, PortalPlane, obj->thing, obj->sub, obj->subsectorDepth, StencilValue + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderPolySprite spr;
|
||||
spr.Render(WorldToClip, PortalPlane, obj.thing, obj.sub, obj.subsectorDepth, StencilValue + 1, obj.SpriteLeft, obj.SpriteRight);
|
||||
spr.Render(WorldToClip, PortalPlane, obj->thing, obj->sub, obj->subsectorDepth, StencilValue + 1, obj->SpriteLeft, obj->SpriteRight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ private:
|
|||
uint32_t NextSubsectorDepth = 0;
|
||||
std::set<sector_t *> SeenSectors;
|
||||
std::unordered_map<subsector_t *, uint32_t> SubsectorDepths;
|
||||
std::vector<PolyTranslucentObject> TranslucentObjects;
|
||||
std::vector<PolyTranslucentObject *> TranslucentObjects;
|
||||
|
||||
std::vector<std::unique_ptr<PolyDrawSectorPortal>> SectorPortals;
|
||||
std::vector<std::unique_ptr<PolyDrawLinePortal>> LinePortals;
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
EXTERN_CVAR(Bool, r_drawmirrors)
|
||||
|
||||
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)
|
||||
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;
|
||||
if (line->backsector == nullptr && line->linedef && line->sidedef == line->linedef->sidedef[0] && (line->linedef->special == Line_Mirror && r_drawmirrors))
|
||||
|
@ -153,7 +153,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const Vec4f &clipP
|
|||
|
||||
FTexture *midtex = TexMan(line->sidedef->GetTexture(side_t::mid), true);
|
||||
if (midtex && midtex->UseType != FTexture::TEX_Null)
|
||||
translucentWallsOutput.push_back({ wall });
|
||||
translucentWallsOutput.push_back(PolyRenderer::Instance()->FrameMemory.NewObject<PolyTranslucentObject>(wall));
|
||||
|
||||
if (polyportal)
|
||||
{
|
||||
|
@ -165,7 +165,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const Vec4f &clipP
|
|||
return polyportal != nullptr;
|
||||
}
|
||||
|
||||
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)
|
||||
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 frontfloorz1 = fakeFloor->bottom.plane->ZatPoint(line->v1);
|
||||
|
|
|
@ -32,8 +32,8 @@ class Vec4f;
|
|||
class RenderPolyWall
|
||||
{
|
||||
public:
|
||||
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, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject> &translucentWallsOutput);
|
||||
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, 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 Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull);
|
||||
|
|
Loading…
Reference in a new issue