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;