mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-12-01 16:41:22 +00:00
Fix up/down culling issue
This commit is contained in:
parent
ce6e1e1e47
commit
04e981dba0
3 changed files with 29 additions and 11 deletions
|
@ -93,7 +93,7 @@ void PolyCull::CullSubsector(subsector_t *sub)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int sx1, sx2;
|
int sx1, sx2;
|
||||||
if (GetSegmentRangeForLine(line->v1->fX(), line->v1->fY(), line->v2->fX(), line->v2->fY(), sx1, sx2))
|
if (GetSegmentRangeForLine(line->v1->fX(), line->v1->fY(), line->v2->fX(), line->v2->fY(), sx1, sx2) == LineSegmentRange::HasSegment)
|
||||||
{
|
{
|
||||||
MarkSegmentCulled(sx1, sx2);
|
MarkSegmentCulled(sx1, sx2);
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,8 @@ bool PolyCull::CheckBBox(float *bspcoord)
|
||||||
float x2 = bspcoord[lines[i][2]];
|
float x2 = bspcoord[lines[i][2]];
|
||||||
float y2 = bspcoord[lines[i][3]];
|
float y2 = bspcoord[lines[i][3]];
|
||||||
int sx1, sx2;
|
int sx1, sx2;
|
||||||
if (GetSegmentRangeForLine(x1, y1, x2, y2, sx1, sx2))
|
LineSegmentRange result = GetSegmentRangeForLine(x1, y1, x2, y2, sx1, sx2);
|
||||||
|
if (result == LineSegmentRange::HasSegment)
|
||||||
{
|
{
|
||||||
if (foundline)
|
if (foundline)
|
||||||
{
|
{
|
||||||
|
@ -214,6 +215,10 @@ bool PolyCull::CheckBBox(float *bspcoord)
|
||||||
foundline = true;
|
foundline = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (result == LineSegmentRange::AlwaysVisible)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!foundline)
|
if (!foundline)
|
||||||
return false;
|
return false;
|
||||||
|
@ -221,13 +226,14 @@ bool PolyCull::CheckBBox(float *bspcoord)
|
||||||
return !IsSegmentCulled(minsx1, maxsx2);
|
return !IsSegmentCulled(minsx1, maxsx2);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PolyCull::GetSegmentRangeForLine(double x1, double y1, double x2, double y2, int &sx1, int &sx2) const
|
LineSegmentRange PolyCull::GetSegmentRangeForLine(double x1, double y1, double x2, double y2, int &sx1, int &sx2) const
|
||||||
{
|
{
|
||||||
double znear = 5.0;
|
double znear = 5.0;
|
||||||
|
double updownnear = -400.0;
|
||||||
|
|
||||||
// Cull if entirely behind the portal clip plane (tbd: should we clip the segment?)
|
// Cull if entirely behind the portal clip plane (tbd: should we clip the segment?)
|
||||||
if (Vec4f::dot(PortalClipPlane, Vec4f((float)x1, (float)y1, 0.0f, 1.0f)) < 0.0f && Vec4f::dot(PortalClipPlane, Vec4f((float)x2, (float)y2, 0.0f, 1.0f)) < 0.0f)
|
if (Vec4f::dot(PortalClipPlane, Vec4f((float)x1, (float)y1, 0.0f, 1.0f)) < 0.0f && Vec4f::dot(PortalClipPlane, Vec4f((float)x2, (float)y2, 0.0f, 1.0f)) < 0.0f)
|
||||||
return false;
|
return LineSegmentRange::NotVisible;
|
||||||
|
|
||||||
// Transform to 2D view space:
|
// Transform to 2D view space:
|
||||||
x1 = x1 - ViewPos.X;
|
x1 = x1 - ViewPos.X;
|
||||||
|
@ -239,8 +245,13 @@ bool PolyCull::GetSegmentRangeForLine(double x1, double y1, double x2, double y2
|
||||||
double ry1 = x1 * ViewCos + y1 * ViewSin;
|
double ry1 = x1 * ViewCos + y1 * ViewSin;
|
||||||
double ry2 = x2 * ViewCos + y2 * ViewSin;
|
double ry2 = x2 * ViewCos + y2 * ViewSin;
|
||||||
|
|
||||||
|
// Is it potentially visible when looking straight up or down?
|
||||||
|
if (!(ry1 < updownnear && ry2 < updownnear) && !(ry1 > znear && ry2 > znear))
|
||||||
|
return LineSegmentRange::AlwaysVisible;
|
||||||
|
|
||||||
// Cull if line is entirely behind view
|
// Cull if line is entirely behind view
|
||||||
if (ry1 < znear && ry2 < znear) return false;
|
if (ry1 < znear && ry2 < znear)
|
||||||
|
return LineSegmentRange::NotVisible;
|
||||||
|
|
||||||
// Clip line, if needed
|
// Clip line, if needed
|
||||||
double t1 = 0.0f, t2 = 1.0f;
|
double t1 = 0.0f, t2 = 1.0f;
|
||||||
|
@ -265,5 +276,5 @@ bool PolyCull::GetSegmentRangeForLine(double x1, double y1, double x2, double y2
|
||||||
|
|
||||||
if (sx1 > sx2)
|
if (sx1 > sx2)
|
||||||
std::swap(sx1, sx2);
|
std::swap(sx1, sx2);
|
||||||
return sx1 != sx2;
|
return (sx1 != sx2) ? LineSegmentRange::HasSegment : LineSegmentRange::AlwaysVisible;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,12 +25,19 @@
|
||||||
#include "r_poly_triangle.h"
|
#include "r_poly_triangle.h"
|
||||||
#include "r_poly_intersection.h"
|
#include "r_poly_intersection.h"
|
||||||
|
|
||||||
|
enum class LineSegmentRange
|
||||||
|
{
|
||||||
|
NotVisible,
|
||||||
|
HasSegment,
|
||||||
|
AlwaysVisible
|
||||||
|
};
|
||||||
|
|
||||||
class PolyCull
|
class PolyCull
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void CullScene(const TriMatrix &worldToClip, const Vec4f &portalClipPlane);
|
void CullScene(const TriMatrix &worldToClip, const Vec4f &portalClipPlane);
|
||||||
|
|
||||||
bool 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;
|
||||||
|
|
||||||
|
|
|
@ -174,12 +174,12 @@ void RenderPolyPortal::RenderLine(subsector_t *sub, seg_t *line, sector_t *front
|
||||||
|
|
||||||
// Cull wall if not visible
|
// Cull wall if not visible
|
||||||
int sx1, sx2;
|
int sx1, sx2;
|
||||||
bool hasSegmentRange = Cull.GetSegmentRangeForLine(line->v1->fX(), line->v1->fY(), line->v2->fX(), line->v2->fY(), sx1, sx2);
|
LineSegmentRange segmentRange = Cull.GetSegmentRangeForLine(line->v1->fX(), line->v1->fY(), line->v2->fX(), line->v2->fY(), sx1, sx2);
|
||||||
if (!hasSegmentRange || Cull.IsSegmentCulled(sx1, sx2))
|
if (segmentRange == LineSegmentRange::NotVisible || (segmentRange == LineSegmentRange::HasSegment && Cull.IsSegmentCulled(sx1, sx2)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Tell automap we saw this
|
// Tell automap we saw this
|
||||||
if (!swrenderer::r_dontmaplines && line->linedef)
|
if (!swrenderer::r_dontmaplines && line->linedef && segmentRange != LineSegmentRange::AlwaysVisible)
|
||||||
{
|
{
|
||||||
line->linedef->flags |= ML_MAPPED;
|
line->linedef->flags |= ML_MAPPED;
|
||||||
sub->flags |= SSECF_DRAWN;
|
sub->flags |= SSECF_DRAWN;
|
||||||
|
@ -201,7 +201,7 @@ void RenderPolyPortal::RenderLine(subsector_t *sub, seg_t *line, sector_t *front
|
||||||
// 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, line, frontsector, subsectorDepth, StencilValue, TranslucentObjects, LinePortals))
|
||||||
{
|
{
|
||||||
if (hasSegmentRange)
|
if (segmentRange == LineSegmentRange::HasSegment)
|
||||||
Cull.MarkSegmentCulled(sx1, sx2);
|
Cull.MarkSegmentCulled(sx1, sx2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue