From 70bf6493645b622c7994c83c743769ff4e09a0bf Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 29 Apr 2016 12:26:57 +0200 Subject: [PATCH] - added clip planes for line portals and mirrors. This should eliminate the remaining problems with some visible geometry in front of the portal, it is also necessary to handle sprite splitting across line portals properly. --- src/gl/scene/gl_portal.cpp | 27 +++++++++++++++++++++++++++ src/gl/scene/gl_portal.h | 2 ++ wadsrc/static/shaders/glsl/main.vp | 8 ++++++-- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index f165de630..be25409e2 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -825,7 +825,28 @@ void GLPlaneMirrorPortal::PopState() // //----------------------------------------------------------------------------- +void GLLinePortal::PushState() +{ + FStateVec4 &v = gl_RenderState.GetClipLine(); + planestack.Push(v.vec[0]); + planestack.Push(v.vec[1]); + planestack.Push(v.vec[2]); + planestack.Push(v.vec[3]); + planestack.Push(gl_RenderState.GetClipLineState()); + gl_RenderState.EnableClipLine(false); +} +void GLLinePortal::PopState() +{ + FStateVec4 &v = gl_RenderState.GetClipLine(); + float e; + planestack.Pop(e); + planestack.Pop(v.vec[3]); + planestack.Pop(v.vec[2]); + planestack.Pop(v.vec[1]); + planestack.Pop(v.vec[0]); + gl_RenderState.EnableClipLine(e != 0); +} int GLLinePortal::ClipSeg(seg_t *seg) { @@ -948,7 +969,10 @@ void GLMirrorPortal::DrawContents() angle_t a1 = linedef->v2->GetClipAngle(); clipper.SafeAddClipRange(a1,a2); + gl_RenderState.SetClipLine(linedef); + gl_RenderState.EnableClipLine(true); GLRenderer->DrawScene(); + gl_RenderState.EnableClipLine(false); MirrorFlag--; } @@ -1018,7 +1042,10 @@ void GLLineToLinePortal::DrawContents() GLRenderer->SetupView(ViewPos.X, ViewPos.Y, ViewPos.Z, ViewAngle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); ClearClipper(); + gl_RenderState.SetClipLine(glport->reference->mDestination); + gl_RenderState.EnableClipLine(true); GLRenderer->DrawScene(); + gl_RenderState.EnableClipLine(false); RestoreMapSection(); } diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index 870009845..2962a4be1 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -225,6 +225,8 @@ struct GLLinePortal : public GLPortal virtual int ClipSubsector(subsector_t *sub); virtual int ClipPoint(const DVector2 &pos); virtual bool NeedCap() { return false; } + virtual void PushState(); + virtual void PopState(); }; diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index 44aec6199..7cc4d4d83 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -55,11 +55,15 @@ void main() #endif - // clip planes used for reflective flats - if (uClipHeightDirection != 0.0) + + if (uClipHeightDirection != 0.0) // clip planes used for reflective flats { gl_ClipDistance[0] = (worldcoord.y - uClipHeight) * uClipHeightDirection; } + else if (uClipLine.x > -1000000.0) // and for line portals - this will never be active at the same time as the reflective planes clipping so it can use the same hardware clip plane. + { + gl_ClipDistance[0] = -( (worldcoord.z - uClipLine.y) * uClipLine.z + (uClipLine.x - worldcoord.x) * uClipLine.w ) + 1.0/32768.0; // allow a tiny bit of imprecisions for colinear linedefs. + } // clip planes used for translucency splitting gl_ClipDistance[1] = worldcoord.y - uClipSplit.x;