From cead0194bd88759e00f6ff13a56d83ae49ceb27e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 25 Oct 2018 00:49:39 +0200 Subject: [PATCH] - safety commit. To finalize we need a better vertex buffer interface. --- src/gl/models/gl_models.cpp | 4 +- src/gl/renderer/gl_renderer.h | 2 - src/gl/scene/gl_drawinfo.cpp | 2 +- src/gl/scene/gl_scene.cpp | 8 +- src/gl/scene/gl_walls_draw.cpp | 111 ------------------------ src/hwrenderer/scene/hw_renderstate.cpp | 3 +- src/hwrenderer/scene/hw_walls.cpp | 108 ++++++++++++++++++++++- src/v_framebuffer.cpp | 7 ++ src/v_video.h | 10 ++- 9 files changed, 129 insertions(+), 126 deletions(-) diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 1e793c706..3dbf9eff0 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -64,7 +64,7 @@ void FGLModelRenderer::BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, con if (!(actor->RenderStyle == LegacyRenderStyles[STYLE_Normal]) && !(smf->flags & MDL_DONTCULLBACKFACES)) { glEnable(GL_CULL_FACE); - glFrontFace((mirrored ^ GLRenderer->mPortalState.isMirrored()) ? GL_CCW : GL_CW); + glFrontFace((mirrored ^ screen->mPortalState->isMirrored()) ? GL_CCW : GL_CW); } gl_RenderState.mModelMatrix = objectToWorldMatrix; @@ -90,7 +90,7 @@ void FGLModelRenderer::BeginDrawHUDModel(AActor *actor, const VSMatrix &objectTo if (!(actor->RenderStyle == LegacyRenderStyles[STYLE_Normal])) { glEnable(GL_CULL_FACE); - glFrontFace((mirrored ^ GLRenderer->mPortalState.isMirrored()) ? GL_CW : GL_CCW); + glFrontFace((mirrored ^ screen->mPortalState->isMirrored()) ? GL_CW : GL_CCW); } gl_RenderState.mModelMatrix = objectToWorldMatrix; diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index 3be5e97ad..66da27cd7 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -75,8 +75,6 @@ public: GLViewpointBuffer *mViewpoints = nullptr; SWSceneDrawer *swdrawer = nullptr; - FPortalSceneState mPortalState; - float mSceneClearColor[3]; FGLRenderer(OpenGLFrameBuffer *fb); diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 88f57ef4b..fc3bc8e49 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -242,7 +242,7 @@ void FDrawInfo::AddSubsectorToPortal(FSectorPortalGroup *ptg, subsector_t *sub) auto portal = FindPortal(ptg); if (!portal) { - portal = new HWScenePortal(&GLRenderer->mPortalState, new HWSectorStackPortal(ptg)); + portal = new HWScenePortal(screen->mPortalState, new HWSectorStackPortal(ptg)); Portals.Push(portal); } auto ptl = static_cast(static_cast(portal)->mScene); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 942f8a4a1..e52c66cdd 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -95,7 +95,7 @@ void FDrawInfo::CreateScene() mClipper->SafeAddClipRangeRealAngles(vp.Angles.Yaw.BAMs() + a1, vp.Angles.Yaw.BAMs() - a1); // reset the portal manager - GLRenderer->mPortalState.StartFrame(); + screen->mPortalState->StartFrame(); PO_LinkToSubsectors(); ProcessAll.Clock(); @@ -149,7 +149,7 @@ void FDrawInfo::RenderScene(int recursion) RenderAll.Clock(); glDepthMask(true); - if (!gl_no_skyclear) GLRenderer->mPortalState.RenderFirstSkyPortal(recursion, this); + if (!gl_no_skyclear) screen->mPortalState->RenderFirstSkyPortal(recursion, this); gl_RenderState.EnableFog(true); gl_RenderState.SetRenderStyle(STYLE_Source); @@ -284,7 +284,7 @@ void FDrawInfo::DrawScene(int drawmode) // Handle all portals after rendering the opaque objects but before // doing all translucent stuff recursion++; - GLRenderer->mPortalState.EndFrame(this); + screen->mPortalState->EndFrame(this); recursion--; RenderTranslucent(); } @@ -352,7 +352,7 @@ void FDrawInfo::DrawEndScene2D(sector_t * viewsector) void FDrawInfo::ProcessScene(bool toscreen) { iter_dlightf = iter_dlight = draw_dlight = draw_dlightf = 0; - GLRenderer->mPortalState.BeginScene(); + screen->mPortalState->BeginScene(); int mapsection = R_PointInSubsector(Viewpoint.Pos)->mapsection; CurrentMapSections.Set(mapsection); diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 757a8fd95..aa9d745c1 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -91,114 +91,3 @@ void FDrawInfo::AddMirrorSurface(GLWall *w) newwall->ProcessDecals(this); } -//========================================================================== -// -// -// -//========================================================================== - -void FDrawInfo::AddPortal(GLWall *wall, int ptype) -{ - auto &pstate = GLRenderer->mPortalState; - HWPortal * portal; - - wall->MakeVertices(this, false); - switch (ptype) - { - // portals don't go into the draw list. - // Instead they are added to the portal manager - case PORTALTYPE_HORIZON: - wall->horizon = pstate.UniqueHorizons.Get(wall->horizon); - portal = FindPortal(wall->horizon); - if (!portal) - { - portal = new HWHorizonPortal(&pstate, wall->horizon, Viewpoint, this); - Portals.Push(portal); - } - portal->AddLine(wall); - break; - - case PORTALTYPE_SKYBOX: - portal = FindPortal(wall->secportal); - if (!portal) - { - // either a regular skybox or an Eternity-style horizon - if (wall->secportal->mType != PORTS_SKYVIEWPOINT) portal = new HWEEHorizonPortal(&pstate, wall->secportal, this); - else - { - portal = new HWScenePortal(&pstate, new HWSkyboxPortal(wall->secportal)); - Portals.Push(portal); - } - } - portal->AddLine(wall); - break; - - case PORTALTYPE_SECTORSTACK: - portal = FindPortal(wall->portal); - if (!portal) - { - portal = new HWScenePortal(&pstate, new HWSectorStackPortal(wall->portal)); - Portals.Push(portal); - } - portal->AddLine(wall); - break; - - case PORTALTYPE_PLANEMIRROR: - if (pstate.PlaneMirrorMode * wall->planemirror->fC() <= 0) - { - //@sync-portal - wall->planemirror = pstate.UniquePlaneMirrors.Get(wall->planemirror); - portal = FindPortal(wall->planemirror); - if (!portal) - { - portal = new HWScenePortal(&pstate, new HWPlaneMirrorPortal(wall->planemirror)); - Portals.Push(portal); - } - portal->AddLine(wall); - } - break; - - case PORTALTYPE_MIRROR: - portal = FindPortal(wall->seg->linedef); - if (!portal) - { - portal = new HWScenePortal(&pstate, new HWMirrorPortal(wall->seg->linedef)); - Portals.Push(portal); - } - portal->AddLine(wall); - if (gl_mirror_envmap) - { - // draw a reflective layer over the mirror - AddMirrorSurface(wall); - } - break; - - case PORTALTYPE_LINETOLINE: - portal = FindPortal(wall->lineportal); - if (!portal) - { - line_t *otherside = wall->lineportal->lines[0]->mDestination; - if (otherside != nullptr && otherside->portalindex < level.linePortals.Size()) - { - ProcessActorsInPortal(otherside->getPortal()->mGroup, in_area); - } - portal = new HWScenePortal(&pstate, new HWLineToLinePortal(wall->lineportal)); - Portals.Push(portal); - } - portal->AddLine(wall); - break; - - case PORTALTYPE_SKY: - wall->sky = pstate.UniqueSkies.Get(wall->sky); - portal = FindPortal(wall->sky); - if (!portal) - { - portal = new HWSkyPortal(GLRenderer->mSkyVBO, &pstate, wall->sky); - Portals.Push(portal); - } - portal->AddLine(wall); - break; - } - wall->vertcount = 0; -} - diff --git a/src/hwrenderer/scene/hw_renderstate.cpp b/src/hwrenderer/scene/hw_renderstate.cpp index cc3df3180..5aa8d9c3c 100644 --- a/src/hwrenderer/scene/hw_renderstate.cpp +++ b/src/hwrenderer/scene/hw_renderstate.cpp @@ -27,6 +27,7 @@ #include "hw_renderstate.h" #include "hw_drawstructs.h" +#include "hw_portal.h" #include "hwrenderer/utility/hw_lighting.h" #include "hwrenderer/utility/hw_cvars.h" @@ -115,7 +116,7 @@ void FRenderState::SetFog(int lightlevel, int rellight, bool fullbright, const F } // Make fog a little denser when inside a skybox - //if (GLRenderer->mPortalState.inskybox) fogdensity += fogdensity / 2; + if (screen->mPortalState->inskybox) fogdensity += fogdensity / 2; // no fog in enhanced vision modes! diff --git a/src/hwrenderer/scene/hw_walls.cpp b/src/hwrenderer/scene/hw_walls.cpp index 96fe46d2d..8c6939411 100644 --- a/src/hwrenderer/scene/hw_walls.cpp +++ b/src/hwrenderer/scene/hw_walls.cpp @@ -427,9 +427,115 @@ void GLWall::PutWall(HWDrawInfo *di, bool translucent) flags &= ~GLWF_TRANSLUCENT; } +//========================================================================== +// +// +// +//========================================================================== + void GLWall::PutPortal(HWDrawInfo *di, int ptype) { - di->AddPortal(this, ptype); + auto pstate = screen->mPortalState; + HWPortal * portal; + + MakeVertices(di, false); + switch (ptype) + { + // portals don't go into the draw list. + // Instead they are added to the portal manager + case PORTALTYPE_HORIZON: + horizon = pstate->UniqueHorizons.Get(horizon); + portal = di->FindPortal(horizon); + if (!portal) + { + portal = new HWHorizonPortal(pstate, horizon, di->Viewpoint, di); + di->Portals.Push(portal); + } + portal->AddLine(this); + break; + + case PORTALTYPE_SKYBOX: + portal = di->FindPortal(secportal); + if (!portal) + { + // either a regular skybox or an Eternity-style horizon + if (secportal->mType != PORTS_SKYVIEWPOINT) portal = new HWEEHorizonPortal(pstate, secportal, di); + else + { + portal = new HWScenePortal(pstate, new HWSkyboxPortal(secportal)); + di->Portals.Push(portal); + } + } + portal->AddLine(this); + break; + + case PORTALTYPE_SECTORSTACK: + portal = di->FindPortal(portal); + if (!portal) + { + portal = new HWScenePortal(pstate, new HWSectorStackPortal(this->portal)); + di->Portals.Push(portal); + } + portal->AddLine(this); + break; + + case PORTALTYPE_PLANEMIRROR: + if (pstate->PlaneMirrorMode * planemirror->fC() <= 0) + { + //@sync-portal + planemirror = pstate->UniquePlaneMirrors.Get(planemirror); + portal = di->FindPortal(planemirror); + if (!portal) + { + portal = new HWScenePortal(pstate, new HWPlaneMirrorPortal(planemirror)); + di->Portals.Push(portal); + } + portal->AddLine(this); + } + break; + + case PORTALTYPE_MIRROR: + portal = di->FindPortal(seg->linedef); + if (!portal) + { + portal = new HWScenePortal(pstate, new HWMirrorPortal(seg->linedef)); + di->Portals.Push(portal); + } + portal->AddLine(this); + if (gl_mirror_envmap) + { + // draw a reflective layer over the mirror + di->AddMirrorSurface(this); + } + break; + + case PORTALTYPE_LINETOLINE: + portal = di->FindPortal(lineportal); + if (!portal) + { + line_t *otherside = lineportal->lines[0]->mDestination; + if (otherside != nullptr && otherside->portalindex < level.linePortals.Size()) + { + di->ProcessActorsInPortal(otherside->getPortal()->mGroup, di->in_area); + } + portal = new HWScenePortal(pstate, new HWLineToLinePortal(lineportal)); + di->Portals.Push(portal); + } + portal->AddLine(this); + break; + + case PORTALTYPE_SKY: + sky = pstate->UniqueSkies.Get(sky); + portal = di->FindPortal(sky); + if (!portal) + { + portal = new HWSkyPortal(GLRenderer->mSkyVBO, &pstate, sky); + di->Portals.Push(portal); + } + portal->AddLine(this); + break; + } + vertcount = 0; } //========================================================================== diff --git a/src/v_framebuffer.cpp b/src/v_framebuffer.cpp index b4a5807f9..9ba80956f 100644 --- a/src/v_framebuffer.cpp +++ b/src/v_framebuffer.cpp @@ -48,6 +48,7 @@ #include "vm.h" #include "r_videoscale.h" #include "i_time.h" +#include "hwrenderer/scene/hw_portal.h" CVAR(Bool, gl_scale_viewport, true, CVAR_ARCHIVE); @@ -172,6 +173,12 @@ DSimpleCanvas::~DSimpleCanvas () DFrameBuffer::DFrameBuffer (int width, int height) { SetSize(width, height); + mPortalState = new FPortalSceneState; +} + +DFrameBuffer::~DFrameBuffer() +{ + delete mPortalState; } void DFrameBuffer::SetSize(int width, int height) diff --git a/src/v_video.h b/src/v_video.h index e9655a007..6b81e7315 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -48,6 +48,7 @@ struct sector_t; class IShaderProgram; class FTexture; +struct FPortalSceneState; enum EHWCaps { @@ -362,10 +363,11 @@ protected: public: int hwcaps = 0; - float glslversion = 0; // This is here so that the differences between old OpenGL and new OpenGL/Vulkan can be handled by platform independent code. - int instack[2] = { 0,0 }; // this is globally maintained state for portal recursion avoidance. - int stencilValue = 0; // Global stencil test value + float glslversion = 0; // This is here so that the differences between old OpenGL and new OpenGL/Vulkan can be handled by platform independent code. + int instack[2] = { 0,0 }; // this is globally maintained state for portal recursion avoidance. + int stencilValue = 0; // Global stencil test value bool enable_quadbuffered = false; + FPortalSceneState *mPortalState; // global portal state. IntRect mScreenViewport; IntRect mSceneViewport; @@ -373,7 +375,7 @@ public: public: DFrameBuffer (int width=1, int height=1); - virtual ~DFrameBuffer() {} + virtual ~DFrameBuffer(); virtual void InitializeState() = 0; // For stuff that needs 'screen' set. void SetSize(int width, int height);