From 748ff08ca1126cdad75d389b86d243cbe16e55f9 Mon Sep 17 00:00:00 2001
From: chromaticpipe <chromaticpipe@gmail.com>
Date: Fri, 28 Feb 2025 18:37:52 -0600
Subject: [PATCH 1/2] Mostly fix OpenGL floor-clipping sprites

---
 src/hardware/hw_main.c | 42 ++++++++++++++++++++++--------------------
 1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index d84322dfda..31e4af267b 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -3065,19 +3065,19 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
 		baseWallVerts[0].t = baseWallVerts[1].t = ((GLPatch_t *)gpatch->hardware)->max_t;
 	}
 
-	// if it has a dispoffset, push it a little towards the camera
-	if (spr->dispoffset) {
-		float co = -gl_viewcos*(0.05f*spr->dispoffset);
-		float si = -gl_viewsin*(0.05f*spr->dispoffset);
-		baseWallVerts[0].z = baseWallVerts[3].z = baseWallVerts[0].z+si;
-		baseWallVerts[1].z = baseWallVerts[2].z = baseWallVerts[1].z+si;
-		baseWallVerts[0].x = baseWallVerts[3].x = baseWallVerts[0].x+co;
-		baseWallVerts[1].x = baseWallVerts[2].x = baseWallVerts[1].x+co;
-	}
-
 	// Let dispoffset work first since this adjust each vertex
 	HWR_RotateSpritePolyToAim(spr, baseWallVerts, false);
 
+	// push it toward the camera to mitigate floor-clipping sprites
+	float sprdist = sqrtf((spr->x1 - gl_viewx)*(spr->x1 - gl_viewx) + (spr->z1 - gl_viewy)*(spr->z1 - gl_viewy) + (spr->gzt - gl_viewz)*(spr->gzt - gl_viewz));
+	float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist;
+	for (i = 0; i < 4; i++)
+	{
+		baseWallVerts[i].x += (gl_viewx - baseWallVerts[i].x)*distfact;
+		baseWallVerts[i].z += (gl_viewy - baseWallVerts[i].z)*distfact;
+		baseWallVerts[i].y += (gl_viewz - baseWallVerts[i].y)*distfact;
+	}
+
 	realtop = top = baseWallVerts[3].y;
 	realbot = bot = baseWallVerts[0].y;
 	ttop = baseWallVerts[3].t;
@@ -3528,18 +3528,20 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
 
 	if (!splat)
 	{
-		// if it has a dispoffset, push it a little towards the camera
-		if (spr->dispoffset) {
-			float co = -gl_viewcos*(0.05f*spr->dispoffset);
-			float si = -gl_viewsin*(0.05f*spr->dispoffset);
-			wallVerts[0].z = wallVerts[3].z = wallVerts[0].z+si;
-			wallVerts[1].z = wallVerts[2].z = wallVerts[1].z+si;
-			wallVerts[0].x = wallVerts[3].x = wallVerts[0].x+co;
-			wallVerts[1].x = wallVerts[2].x = wallVerts[1].x+co;
-		}
-
 		// Let dispoffset work first since this adjust each vertex
+		// ...nah
 		HWR_RotateSpritePolyToAim(spr, wallVerts, false);
+		
+		// push it toward the camera to mitigate floor-clipping sprites
+		float sprdist = sqrtf((spr->x1 - gl_viewx)*(spr->x1 - gl_viewx) + (spr->z1 - gl_viewy)*(spr->z1 - gl_viewy) + (spr->gzt - gl_viewz)*(spr->gzt - gl_viewz));
+		float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist;
+		size_t i;
+		for (i = 0; i < 4; i++)
+		{
+		wallVerts[i].x += (gl_viewx - wallVerts[i].x)*distfact;
+		wallVerts[i].z += (gl_viewy - wallVerts[i].z)*distfact;
+		wallVerts[i].y += (gl_viewz - wallVerts[i].y)*distfact;
+		}
 	}
 
 	// This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black.
-- 
GitLab


From b1e31d03daed7f34448f142c566b68e78d065e77 Mon Sep 17 00:00:00 2001
From: chromaticpipe <chromaticpipe@gmail.com>
Date: Sat, 29 Mar 2025 09:09:33 -0500
Subject: [PATCH 2/2] Port improved sprite clipping fix from blankart

---
 src/hardware/hw_main.c | 58 +++++++++++++++++++++++++++++-------------
 1 file changed, 41 insertions(+), 17 deletions(-)

diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index 466efe01ba..1ec605a4c3 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -3129,19 +3129,26 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
 		baseWallVerts[0].t = baseWallVerts[1].t = ((GLPatch_t *)gpatch->hardware)->max_t;
 	}
 
-	// Let dispoffset work first since this adjust each vertex
-	HWR_RotateSpritePolyToAim(spr, baseWallVerts, false);
+
 
 	// push it toward the camera to mitigate floor-clipping sprites
-	float sprdist = sqrtf((spr->x1 - gl_viewx)*(spr->x1 - gl_viewx) + (spr->z1 - gl_viewy)*(spr->z1 - gl_viewy) + (spr->gzt - gl_viewz)*(spr->gzt - gl_viewz));
-	float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist;
-	for (i = 0; i < 4; i++)
+	if (!R_ThingIsPaperSprite(spr->mobj)) // but not for papersprites
 	{
-		baseWallVerts[i].x += (gl_viewx - baseWallVerts[i].x)*distfact;
-		baseWallVerts[i].z += (gl_viewy - baseWallVerts[i].z)*distfact;
-		baseWallVerts[i].y += (gl_viewz - baseWallVerts[i].y)*distfact;
+		// Let dispoffset work first since this adjust each vertex
+		HWR_RotateSpritePolyToAim(spr, baseWallVerts, false);
+
+		// push it toward the camera to mitigate floor-clipping sprites
+		float sprdist = sqrtf((spr->x1 - gl_viewx)*(spr->x1 - gl_viewx) + (spr->z1 - gl_viewy)*(spr->z1 - gl_viewy) + (spr->gzt - gl_viewz)*(spr->gzt - gl_viewz));
+		float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist;
+		for (i = 0; i < 4; i++)
+		{
+			baseWallVerts[i].x += (gl_viewx - baseWallVerts[i].x)*distfact;
+			baseWallVerts[i].z += (gl_viewy - baseWallVerts[i].z)*distfact;
+			baseWallVerts[i].y += (gl_viewz - baseWallVerts[i].y)*distfact;
+		}
 	}
 
+
 	realtop = top = baseWallVerts[3].y;
 	realbot = bot = baseWallVerts[0].y;
 	ttop = baseWallVerts[3].t;
@@ -3596,23 +3603,40 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
 		wallVerts[0].t = wallVerts[1].t = ((GLPatch_t *)gpatch->hardware)->max_t;
 	}
 
-	if (!splat)
+	float sprdist = 0.0f, distfact = 0.0f;
+	size_t i;
+
+	if (!splat && !R_ThingIsPaperSprite(spr->mobj))
 	{
 		// Let dispoffset work first since this adjust each vertex
-		// ...nah
 		HWR_RotateSpritePolyToAim(spr, wallVerts, false);
-		
+
 		// push it toward the camera to mitigate floor-clipping sprites
-		float sprdist = sqrtf((spr->x1 - gl_viewx)*(spr->x1 - gl_viewx) + (spr->z1 - gl_viewy)*(spr->z1 - gl_viewy) + (spr->gzt - gl_viewz)*(spr->gzt - gl_viewz));
-		float distfact = ((2.0f*spr->dispoffset) + 20.0f) / sprdist;
-		size_t i;
+		sprdist = sqrtf((spr->x1 - gl_viewx)*(spr->x1 - gl_viewx) + (spr->z1 - gl_viewy)*(spr->z1 -gl_viewy)+ (spr->gzt - gl_viewz)*(spr->gzt - gl_viewz));
+		distfact = ((2.0f* spr->dispoffset) + 20.0f) / sprdist;
 		for (i = 0; i < 4; i++)
 		{
-		wallVerts[i].x += (gl_viewx - wallVerts[i].x)*distfact;
-		wallVerts[i].z += (gl_viewy - wallVerts[i].z)*distfact;
-		wallVerts[i].y += (gl_viewz - wallVerts[i].y)*distfact;
+			wallVerts[i].x += (gl_viewx - wallVerts[i].x)*distfact;
+			wallVerts[i].z += (gl_viewy - wallVerts[i].z)*distfact;
+			wallVerts[i].y += (gl_viewz - wallVerts[i].y)*distfact;
 		}
 	}
+	else if (R_ThingIsFloorSprite(spr->mobj))
+	{
+		sprdist = sqrtf((spr->x1 - gl_viewx)*(spr->x1 - gl_viewx) + (spr->z1 - gl_viewy)*(spr->z1 - gl_viewy));
+		distfact = (2.0f + 20.0f) / sprdist;
+
+		// pull splats out of the floor
+		for (i = 0; i < 4; i++)
+		{
+			wallVerts[i].x += (gl_viewx - wallVerts[i].x)*distfact;
+			wallVerts[i].z += (gl_viewy - wallVerts[i].z)*distfact;
+			wallVerts[i].y += (gl_viewz - wallVerts[i].y)*distfact;
+		}
+	}
+
+
+
 
 	// This needs to be AFTER the shadows so that the regular sprites aren't drawn completely black.
 	// sprite lighting by modulating the RGB components
-- 
GitLab