From 24b828b362f5f364c26b9ac94bfd0c03cb99d1d6 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Sat, 25 Jul 2020 21:50:24 +0300 Subject: [PATCH] Use 64-bit R_PointToAngle in OpenGL culling to fix some big room issues --- src/hardware/hw_main.c | 8 ++++---- src/r_main.c | 18 ++++++++++++++++++ src/r_main.h | 1 + 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 0d7404c77..48123d4f0 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -2280,8 +2280,8 @@ static void HWR_AddLine(seg_t * line) v2y = FLOAT_TO_FIXED(((polyvertex_t *)gl_curline->pv2)->y); // OPTIMIZE: quickly reject orthogonal back sides. - angle1 = R_PointToAngle(v1x, v1y); - angle2 = R_PointToAngle(v2x, v2y); + angle1 = R_PointToAngle64(v1x, v1y); + angle2 = R_PointToAngle64(v2x, v2y); #ifdef NEWCLIP // PrBoom: Back side, i.e. backface culling - read: endAngle >= startAngle! @@ -2574,8 +2574,8 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord) py2 = bspcoord[checkcoord[boxpos][3]]; #ifdef NEWCLIP - angle1 = R_PointToAngle(px1, py1); - angle2 = R_PointToAngle(px2, py2); + angle1 = R_PointToAngle64(px1, py1); + angle2 = R_PointToAngle64(px2, py2); return gld_clipper_SafeCheckRange(angle2, angle1); #else // check clip list for an open space diff --git a/src/r_main.c b/src/r_main.c index ead1403be..4f79dd8db 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -318,6 +318,24 @@ angle_t R_PointToAngle(fixed_t x, fixed_t y) 0; } +// This version uses 64-bit variables to avoid overflows with large values. +// Currently used only by OpenGL rendering. +angle_t R_PointToAngle64(INT64 x, INT64 y) +{ + return (y -= viewy, (x -= viewx) || y) ? + x >= 0 ? + y >= 0 ? + (x > y) ? tantoangle[SlopeDivEx(y,x)] : // octant 0 + ANGLE_90-tantoangle[SlopeDivEx(x,y)] : // octant 1 + x > (y = -y) ? 0-tantoangle[SlopeDivEx(y,x)] : // octant 8 + ANGLE_270+tantoangle[SlopeDivEx(x,y)] : // octant 7 + y >= 0 ? (x = -x) > y ? ANGLE_180-tantoangle[SlopeDivEx(y,x)] : // octant 3 + ANGLE_90 + tantoangle[SlopeDivEx(x,y)] : // octant 2 + (x = -x) > (y = -y) ? ANGLE_180+tantoangle[SlopeDivEx(y,x)] : // octant 4 + ANGLE_270-tantoangle[SlopeDivEx(x,y)] : // octant 5 + 0; +} + angle_t R_PointToAngle2(fixed_t pviewx, fixed_t pviewy, fixed_t x, fixed_t y) { return (y -= pviewy, (x -= pviewx) || y) ? diff --git a/src/r_main.h b/src/r_main.h index 99a25d86e..729ec6973 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -63,6 +63,7 @@ extern lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ]; INT32 R_PointOnSide(fixed_t x, fixed_t y, node_t *node); INT32 R_PointOnSegSide(fixed_t x, fixed_t y, seg_t *line); angle_t R_PointToAngle(fixed_t x, fixed_t y); +angle_t R_PointToAngle64(INT64 x, INT64 y); angle_t R_PointToAngle2(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1); angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1); fixed_t R_PointToDist(fixed_t x, fixed_t y);