From 322488d1d10676455157127749f965a91f401c30 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 17 Jun 2018 18:33:59 +0200 Subject: [PATCH] - fixed: Horizon portals must be drawn in the context of their containing drawinfo. This data, however, was not passed along to the portal processor and resulted in null pointers when trying to access it. --- src/gl/scene/gl_portal.cpp | 12 +++++++----- src/gl/scene/gl_portal.h | 10 +++++----- src/gl/scene/gl_scene.cpp | 4 ++-- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 8c82e387b..d59cb92e4 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -159,7 +159,7 @@ void GLPortal::DrawPortalStencil() // //----------------------------------------------------------------------------- -bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo **pDi) +bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo *outer_di, FDrawInfo **pDi) { *pDi = nullptr; rendered_portals++; @@ -246,6 +246,7 @@ bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo **pDi) gl_RenderState.SetEffect(EFF_NONE); glDisable(GL_DEPTH_TEST); glDepthMask(false); // don't write to Z-buffer! + *pDi = outer_di; } } recursion++; @@ -262,6 +263,7 @@ bool GLPortal::Start(bool usestencil, bool doquery, FDrawInfo **pDi) { glDepthMask(false); glDisable(GL_DEPTH_TEST); + *pDi = outer_di; } } @@ -458,7 +460,7 @@ static FString indent; // //----------------------------------------------------------------------------- -void GLPortal::EndFrame() +void GLPortal::EndFrame(FDrawInfo *outer_di) { GLPortal * p; @@ -481,7 +483,7 @@ void GLPortal::EndFrame() } if (p->lines.Size() > 0) { - p->RenderPortal(true, usequery); + p->RenderPortal(true, usequery, outer_di); } delete p; } @@ -503,7 +505,7 @@ void GLPortal::EndFrame() // the GPU and there's rarely more than one sky visible at a time. // //----------------------------------------------------------------------------- -bool GLPortal::RenderFirstSkyPortal(int recursion) +bool GLPortal::RenderFirstSkyPortal(int recursion, FDrawInfo *outer_di) { GLPortal * p; GLPortal * best = NULL; @@ -531,7 +533,7 @@ bool GLPortal::RenderFirstSkyPortal(int recursion) if (best) { portals.Delete(bestindex); - best->RenderPortal(false, false); + best->RenderPortal(false, false, outer_di); delete best; return true; } diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index 5f646f41c..a5946c654 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -86,7 +86,7 @@ protected: GLPortal(bool local = false) { if (!local) portals.Push(this); } virtual ~GLPortal() { } - bool Start(bool usestencil, bool doquery, FDrawInfo **pDi); + bool Start(bool usestencil, bool doquery, FDrawInfo *outer_di, FDrawInfo **pDi); void End(bool usestencil); virtual void DrawContents(FDrawInfo *di)=0; virtual void * GetSource() const =0; // GetSource MUST be implemented! @@ -101,13 +101,13 @@ protected: public: - void RenderPortal(bool usestencil, bool doquery) + void RenderPortal(bool usestencil, bool doquery, FDrawInfo *outer_di) { // Start may perform an occlusion query. If that returns 0 there // is no need to draw the stencil's contents and there's also no // need to restore the affected area becasue there is none! FDrawInfo *di; - if (Start(usestencil, doquery, &di)) + if (Start(usestencil, doquery, outer_di, &di)) { DrawContents(di); End(usestencil); @@ -130,8 +130,8 @@ public: static void BeginScene(); static void StartFrame(); - static bool RenderFirstSkyPortal(int recursion); - static void EndFrame(); + static bool RenderFirstSkyPortal(int recursion, FDrawInfo *outer_di); + static void EndFrame(FDrawInfo *outer_di); static GLPortal * FindPortal(const void * src); static void Initialize(); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index fa54cd4b3..47ea1bccd 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -273,7 +273,7 @@ void GLSceneDrawer::RenderScene(FDrawInfo *di, int recursion) RenderAll.Clock(); glDepthMask(true); - if (!gl_no_skyclear) GLPortal::RenderFirstSkyPortal(recursion); + if (!gl_no_skyclear) GLPortal::RenderFirstSkyPortal(recursion, di); gl_RenderState.SetCameraPos(r_viewpoint.Pos.X, r_viewpoint.Pos.Y, r_viewpoint.Pos.Z); @@ -458,7 +458,7 @@ void GLSceneDrawer::DrawScene(FDrawInfo *di, int drawmode) // Handle all portals after rendering the opaque objects but before // doing all translucent stuff recursion++; - GLPortal::EndFrame(); + GLPortal::EndFrame(di); recursion--; RenderTranslucent(di); }