mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-02-18 01:21:32 +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);
|
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
|
// ! 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);
|
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);
|
void MarkSegmentCulled(angle_t angle1, angle_t angle2);
|
||||||
bool IsSegmentCulled(angle_t angle1, angle_t angle2) const;
|
bool IsSegmentCulled(angle_t angle1, angle_t angle2) const;
|
||||||
void InvertSegments();
|
void InvertSegments();
|
||||||
|
void MarkViewFrustum();
|
||||||
|
|
||||||
std::vector<subsector_t *> PvsSectors;
|
std::vector<subsector_t *> PvsSectors;
|
||||||
double MaxCeilingHeight = 0.0;
|
double MaxCeilingHeight = 0.0;
|
||||||
|
@ -64,4 +65,5 @@ private:
|
||||||
Vec4f PortalClipPlane;
|
Vec4f PortalClipPlane;
|
||||||
|
|
||||||
static angle_t PointToPseudoAngle(double x, double y);
|
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();
|
ClearBuffers();
|
||||||
if (!PortalSegmentsAdded)
|
if (!PortalSegmentsAdded)
|
||||||
Cull.ClearSolidSegments();
|
Cull.ClearSolidSegments();
|
||||||
|
Cull.MarkViewFrustum();
|
||||||
Cull.CullScene(WorldToClip, PortalPlane);
|
Cull.CullScene(WorldToClip, PortalPlane);
|
||||||
Cull.ClearSolidSegments();
|
Cull.ClearSolidSegments();
|
||||||
RenderSectors();
|
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());
|
bool mainBSP = ((unsigned int)(sub->Index()) < level.subsectors.Size());
|
||||||
if (mainBSP)
|
if (mainBSP)
|
||||||
{
|
{
|
||||||
|
@ -131,7 +134,7 @@ void RenderPolyScene::RenderSubsector(subsector_t *sub)
|
||||||
for (int i = ParticlesInSubsec[subsectorIndex]; i != NO_PARTICLE; i = Particles[i].snext)
|
for (int i = ParticlesInSubsec[subsectorIndex]; i != NO_PARTICLE; i = Particles[i].snext)
|
||||||
{
|
{
|
||||||
particle_t *particle = Particles + i;
|
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];
|
subsector_t *sub = &level.subsectors[0];
|
||||||
auto it = SubsectorDepths.find(sub);
|
auto it = SubsectorDepths.find(sub);
|
||||||
if (it != SubsectorDepths.end())
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -187,7 +190,7 @@ void RenderPolyScene::RenderSprite(AActor *thing, double sortDistance, DVector2
|
||||||
|
|
||||||
auto it = SubsectorDepths.find(sub);
|
auto it = SubsectorDepths.find(sub);
|
||||||
if (it != SubsectorDepths.end())
|
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)
|
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)
|
for (auto it = TranslucentObjects.rbegin(); it != TranslucentObjects.rend(); ++it)
|
||||||
{
|
{
|
||||||
auto &obj = *it;
|
PolyTranslucentObject *obj = *it;
|
||||||
if (obj.particle)
|
if (obj->particle)
|
||||||
{
|
{
|
||||||
RenderPolyParticle spr;
|
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;
|
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
|
else
|
||||||
{
|
{
|
||||||
RenderPolySprite spr;
|
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;
|
uint32_t NextSubsectorDepth = 0;
|
||||||
std::set<sector_t *> SeenSectors;
|
std::set<sector_t *> SeenSectors;
|
||||||
std::unordered_map<subsector_t *, uint32_t> SubsectorDepths;
|
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<PolyDrawSectorPortal>> SectorPortals;
|
||||||
std::vector<std::unique_ptr<PolyDrawLinePortal>> LinePortals;
|
std::vector<std::unique_ptr<PolyDrawLinePortal>> LinePortals;
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
EXTERN_CVAR(Bool, r_drawmirrors)
|
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;
|
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))
|
||||||
|
@ -153,7 +153,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const Vec4f &clipP
|
||||||
|
|
||||||
FTexture *midtex = TexMan(line->sidedef->GetTexture(side_t::mid), true);
|
FTexture *midtex = TexMan(line->sidedef->GetTexture(side_t::mid), true);
|
||||||
if (midtex && midtex->UseType != FTexture::TEX_Null)
|
if (midtex && midtex->UseType != FTexture::TEX_Null)
|
||||||
translucentWallsOutput.push_back({ wall });
|
translucentWallsOutput.push_back(PolyRenderer::Instance()->FrameMemory.NewObject<PolyTranslucentObject>(wall));
|
||||||
|
|
||||||
if (polyportal)
|
if (polyportal)
|
||||||
{
|
{
|
||||||
|
@ -165,7 +165,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const Vec4f &clipP
|
||||||
return polyportal != nullptr;
|
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 frontceilz1 = fakeFloor->top.plane->ZatPoint(line->v1);
|
||||||
double frontfloorz1 = fakeFloor->bottom.plane->ZatPoint(line->v1);
|
double frontfloorz1 = fakeFloor->bottom.plane->ZatPoint(line->v1);
|
||||||
|
|
|
@ -32,8 +32,8 @@ class Vec4f;
|
||||||
class RenderPolyWall
|
class RenderPolyWall
|
||||||
{
|
{
|
||||||
public:
|
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 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 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, PolyCull &cull);
|
void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull);
|
||||||
|
|
Loading…
Reference in a new issue