diff --git a/src/r_poly_wall.cpp b/src/r_poly_wall.cpp index 815230052..77742a8f8 100644 --- a/src/r_poly_wall.cpp +++ b/src/r_poly_wall.cpp @@ -117,6 +117,16 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, seg_t *line, secto return false; } +void RenderPolyWall::SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2) +{ + this->v1 = v1; + this->v2 = v2; + this->ceil1 = ceil1; + this->floor1 = floor1; + this->ceil2 = ceil2; + this->floor2 = floor2; +} + void RenderPolyWall::Render(const TriMatrix &worldToClip) { FTexture *tex = GetTexture(); @@ -157,6 +167,13 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip) vertices[3].varying[0] = (float)texcoords.u1; vertices[3].varying[1] = (float)texcoords.v2; + // Masked walls clamp to the 0-1 range (no texture repeat) + if (Masked) + { + ClampHeight(vertices[0], vertices[3]); + ClampHeight(vertices[1], vertices[2]); + } + TriUniforms uniforms; uniforms.objectToClip = worldToClip; uniforms.light = (uint32_t)(GetLightLevel() / 255.0f * 256.0f); @@ -188,6 +205,26 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip) } } +void RenderPolyWall::ClampHeight(TriVertex &v1, TriVertex &v2) +{ + float top = v1.z; + float bottom = v2.z; + float texv1 = v1.varying[1]; + float texv2 = v2.varying[1]; + float delta = (texv2 - texv1); + + float t1 = texv1 < 0.0f ? -texv1 / delta : 0.0f; + float t2 = texv2 > 1.0f ? (1.0f - texv1) / delta : 1.0f; + float inv_t1 = 1.0f - t1; + float inv_t2 = 1.0f - t2; + + v1.z = top * inv_t1 + bottom * t1; + v1.varying[1] = texv1 * inv_t1 + texv2 * t1; + + v2.z = top * inv_t2 + bottom * t2; + v2.varying[1] = texv1 * inv_t2 + texv2 * t2; +} + FTexture *RenderPolyWall::GetTexture() { FTexture *tex = TexMan(Line->sidedef->GetTexture(Texpart), true); @@ -296,21 +333,14 @@ void PolyWallTextureCoords::CalcVMidPart(FTexture *tex, const seg_t *line, doubl bool pegged = (line->linedef->flags & ML_DONTPEGBOTTOM) == 0; if (pegged) // top to bottom { - v1 = yoffset; - v2 = v1 + (topz - bottomz); - v1 *= vscale; - v2 *= vscale; + v1 = yoffset * vscale; + v2 = (yoffset + (topz - bottomz)) * vscale; } else // bottom to top { int texHeight = tex->GetHeight(); - v1 = yoffset; - v2 = v1 + (topz - bottomz); - v1 *= vscale; - v2 *= vscale; - v1 = texHeight - v1; - v2 = texHeight - v2; - std::swap(v1, v2); + v1 = texHeight - (-yoffset + (topz - bottomz)) * vscale; + v2 = texHeight + yoffset * vscale; } } @@ -326,7 +356,7 @@ void PolyWallTextureCoords::CalcVBottomPart(FTexture *tex, const seg_t *line, do } else { - v1 = yoffset + (unpeggedceil - topz); + v1 = -yoffset + (unpeggedceil - topz); v2 = v1 + (topz - bottomz); v1 *= vscale; v2 *= vscale; diff --git a/src/r_poly_wall.h b/src/r_poly_wall.h index c215bb611..2de1f1c09 100644 --- a/src/r_poly_wall.h +++ b/src/r_poly_wall.h @@ -31,18 +31,9 @@ class RenderPolyWall public: static bool RenderLine(const TriMatrix &worldToClip, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, std::vector &translucentWallsOutput); + void SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2); void Render(const TriMatrix &worldToClip); - void SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2) - { - this->v1 = v1; - this->v2 = v2; - this->ceil1 = ceil1; - this->floor1 = floor1; - this->ceil2 = ceil2; - this->floor2 = floor2; - } - DVector2 v1; DVector2 v2; double ceil1 = 0.0; @@ -60,6 +51,7 @@ public: uint32_t SubsectorDepth = 0; private: + void ClampHeight(TriVertex &v1, TriVertex &v2); FTexture *GetTexture(); int GetLightLevel(); };