diff --git a/src/g_levellocals.h b/src/g_levellocals.h index 3fcea30f9..53fea8f97 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -89,6 +89,8 @@ struct FLevelLocals FDisplacementTable Displacements; FPortalBlockmap PortalBlockmap; TArray linkedPortals; // only the linked portals, this is used to speed up looking for them in P_CollectConnectedGroups. + TArray portalGroups; + TArray linePortalSpans; TArray Zones; diff --git a/src/gl/data/gl_data.h b/src/gl/data/gl_data.h index 75f248b07..bd68bf591 100644 --- a/src/gl/data/gl_data.h +++ b/src/gl/data/gl_data.h @@ -20,29 +20,6 @@ inline int getExtraLight() struct GLSectorStackPortal; -struct FPortal -{ - DVector2 mDisplacement; - int plane; - GLSectorStackPortal *glportal; // for quick access to the render data. This is only valid during BSP traversal! - - GLSectorStackPortal *GetRenderState(); -}; - -struct FGLLinePortal -{ - // defines the complete span of this portal, if this is of type PORTT_LINKED. - vertex_t *v1 = nullptr, *v2 = nullptr; // vertices, from v1 to v2 - TArray lines; - int validcount = 0; -}; - -extern TArray glSectorPortals; -extern TArray linePortalToGL; - extern TArray currentmapsection; -void gl_InitPortals(); -void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, const DVector2 &displacement); - #endif diff --git a/src/gl/data/gl_portaldata.cpp b/src/gl/data/gl_portaldata.cpp index eeff9082c..d4af49ad5 100644 --- a/src/gl/data/gl_portaldata.cpp +++ b/src/gl/data/gl_portaldata.cpp @@ -48,7 +48,12 @@ #include "gl/dynlights/gl_dynlight.h" #include "gl/dynlights/gl_glow.h" #include "gl/utility/gl_clock.h" -#include "gl/gl_functions.h" + +//========================================================================== +// +// Helper types for portal grouping +// +//========================================================================== struct FPortalID { @@ -69,25 +74,8 @@ struct FPortalSector }; typedef TArray FPortalSectors; - typedef TMap FPortalMap; -TArray glSectorPortals; -TArray linePortalToGL; -TArray glLinePortals; - -//========================================================================== -// -// -// -//========================================================================== - -GLSectorStackPortal *FPortal::GetRenderState() -{ - if (glportal == NULL) glportal = new GLSectorStackPortal(this); - return glportal; -} - //========================================================================== // // this is left as fixed_t because the nodes also are, it makes no sense @@ -119,7 +107,6 @@ struct FCoverageBuilder //========================================================================== // // - // //========================================================================== FCoverageBuilder(subsector_t *sub) @@ -305,10 +292,16 @@ struct FCoverageBuilder //========================================================================== // // Calculate portal coverage for a single subsector +// This data is used by the clipper to free up the ranges covered by a portal. +// +// This also gets called by the render hack code because ZDoom was really lax +// with its stacked sector things and allowed partial tagging of affected sectors +// Any such sector will only be found during rendering and must create its +// coverage info then. // //========================================================================== -void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, const DVector2 &displacement) +void BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, const DVector2 &displacement) { TArray shape; double centerx=0, centery=0; @@ -332,7 +325,7 @@ void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, c //========================================================================== // -// portal initialization +// // //========================================================================== @@ -355,15 +348,20 @@ static void CollectPortalSectors(FPortalMap &collection) } } -void gl_InitPortals() +//========================================================================== +// +// group sector portals by displacement +// The renderer can handle such a group in one go to avoid multiple +// BSP traversals +// +//========================================================================== + +static void GroupSectorPortals() { FPortalMap collection; - if (level.nodes.Size() == 0) return; - - CollectPortalSectors(collection); - glSectorPortals.Clear(); + level.portalGroups.Clear(); FPortalMap::Iterator it(collection); FPortalMap::Pair *pair; @@ -371,31 +369,31 @@ void gl_InitPortals() int planeflags = 0; while (it.NextPair(pair)) { - for(unsigned i=0;iValue.Size(); i++) + for (unsigned i = 0; i < pair->Value.Size(); i++) { if (pair->Value[i].mPlane == sector_t::floor) planeflags |= 1; else if (pair->Value[i].mPlane == sector_t::ceiling) planeflags |= 2; } - for (int i=1;i<=2;i<<=1) + for (int i = 1; i <= 2; i <<= 1) { - // add separate glSectorPortals for floor and ceiling. + // add separate portals for floor and ceiling. if (planeflags & i) { - FPortal *portal = new FPortal; + FSectorPortalGroup *portal = new FSectorPortalGroup; portal->mDisplacement = pair->Key.mDisplacement; - portal->plane = (i==1? sector_t::floor : sector_t::ceiling); /**/ + portal->plane = (i == 1 ? sector_t::floor : sector_t::ceiling); /**/ portal->glportal = NULL; - glSectorPortals.Push(portal); - for(unsigned j=0;jValue.Size(); j++) + level.portalGroups.Push(portal); + for (unsigned j = 0; j < pair->Value.Size(); j++) { sector_t *sec = pair->Value[j].mSub; int plane = pair->Value[j].mPlane; if (portal->plane == plane) { - for(int k=0;ksubsectorcount; k++) + for (int k = 0; k < sec->subsectorcount; k++) { subsector_t *sub = sec->subsectors[k]; - gl_BuildPortalCoverage(&sub->portalcoverage[plane], sub, pair->Key.mDisplacement); + BuildPortalCoverage(&sub->portalcoverage[plane], sub, pair->Key.mDisplacement); } sec->portals[plane] = portal; } @@ -403,10 +401,18 @@ void gl_InitPortals() } } } +} - // Now group the line glSectorPortals (each group must be a continuous set of colinear linedefs with no gaps) - glLinePortals.Clear(); - linePortalToGL.Clear(); +//========================================================================== +// +// Group the line portals +// Each group must be a continuous set of colinear linedefs with no gaps +// +//========================================================================== + +static void GroupLinePortals() +{ + level.linePortalSpans.Clear(); TArray tempindex; tempindex.Reserve(level.linePortals.Size()); @@ -419,13 +425,13 @@ void gl_InitPortals() if (tempindex[i] == -1) { - tempindex[i] = glLinePortals.Size(); + tempindex[i] = level.linePortalSpans.Size(); line_t *pSrcLine = level.linePortals[i].mOrigin; line_t *pLine = level.linePortals[i].mDestination; - FGLLinePortal &glport = glLinePortals[glLinePortals.Reserve(1)]; + FLinePortalSpan &glport = level.linePortalSpans[level.linePortalSpans.Reserve(1)]; glport.lines.Push(&level.linePortals[i]); - // We cannot do this grouping for non-linked glSectorPortals because they can be changed at run time. + // We cannot do this grouping for non-linked portals because they can be changed at run time. if (level.linePortals[i].mType == PORTT_LINKED && pLine != nullptr) { glport.v1 = pLine->v1; @@ -440,7 +446,7 @@ void gl_InitPortals() { line_t *pSrcLine2 = level.linePortals[j].mOrigin; line_t *pLine2 = level.linePortals[j].mDestination; - // angular precision is intentionally reduced to 32 bit BAM to account for precision problems (otherwise many not perfectly horizontal or vertical glSectorPortals aren't found here.) + // angular precision is intentionally reduced to 32 bit BAM to account for precision problems (otherwise many not perfectly horizontal or vertical portals aren't found here.) unsigned srcang = pSrcLine->Delta().Angle().BAMs(); unsigned dstang = pLine->Delta().Angle().BAMs(); if ((pSrcLine->v2 == pSrcLine2->v1 && pLine->v1 == pLine2->v2) || @@ -465,30 +471,37 @@ void gl_InitPortals() } } } - linePortalToGL.Resize(level.linePortals.Size()); + + // Final assignment can only be done when all allocations are finished. Otherwise the array may be moved. for (unsigned i = 0; i < level.linePortals.Size(); i++) { - linePortalToGL[i] = &glLinePortals[tempindex[i]]; - /* - Printf("portal at line %d translates to GL portal %d, range = %f,%f to %f,%f\n", - int(level.linePortals[i].mOrigin - lines), tempindex[i], linePortalToGL[i]->v1->fixX() / 65536., linePortalToGL[i]->v1->fixY() / 65536., linePortalToGL[i]->v2->fixX() / 65536., linePortalToGL[i]->v2->fixY() / 65536.); - */ + level.linePortals[i].mGroup = &level.linePortalSpans[tempindex[i]]; } + +} + +void InitPortalGroups() +{ + if (level.nodes.Size() == 0) return; + + GroupSectorPortals(); + GroupLinePortals(); } CCMD(dumpportals) { - for(unsigned i=0;imDisplacement.X; - double ydisp = glSectorPortals[i]->mDisplacement.Y; - Printf(PRINT_LOG, "Portal #%d, %s, displacement = (%f,%f)\n", i, glSectorPortals[i]->plane==0? "floor":"ceiling", + auto p = level.portalGroups[i]; + double xdisp = p->mDisplacement.X; + double ydisp = p->mDisplacement.Y; + Printf(PRINT_LOG, "Portal #%d, %s, displacement = (%f,%f)\n", i, p->plane==0? "floor":"ceiling", xdisp, ydisp); Printf(PRINT_LOG, "Coverage:\n"); for(auto &sub : level.subsectors) { - FPortal *port = sub.render_sector->GetGLPortal(glSectorPortals[i]->plane); - if (port == glSectorPortals[i]) + auto port = sub.render_sector->GetPortalGroup(p->plane); + if (port == p) { Printf(PRINT_LOG, "\tSubsector %d (%d):\n\t\t", sub.Index(), sub.render_sector->sectornum); for(unsigned k = 0;k< sub.numlines; k++) @@ -496,7 +509,7 @@ CCMD(dumpportals) Printf(PRINT_LOG, "(%.3f,%.3f), ", sub.firstline[k].v1->fX() + xdisp, sub.firstline[k].v1->fY() + ydisp); } Printf(PRINT_LOG, "\n\t\tCovered by subsectors:\n"); - FPortalCoverage *cov = &sub.portalcoverage[glSectorPortals[i]->plane]; + FPortalCoverage *cov = &sub.portalcoverage[p->plane]; for(int l = 0;l< cov->sscount; l++) { subsector_t *csub = &level.subsectors[cov->subsectors[l]]; diff --git a/src/gl/data/gl_setup.cpp b/src/gl/data/gl_setup.cpp index 6c1299126..ebb671c63 100644 --- a/src/gl/data/gl_setup.cpp +++ b/src/gl/data/gl_setup.cpp @@ -48,7 +48,6 @@ #include "gl/dynlights/gl_dynlight.h" #include "gl/dynlights/gl_glow.h" #include "gl/utility/gl_clock.h" -#include "gl/gl_functions.h" //========================================================================== // @@ -568,8 +567,6 @@ void gl_PreprocessLevel() } delete[] checkmap; - gl_InitPortals(); - if (GLRenderer != NULL) { GLRenderer->SetupLevel(); @@ -582,53 +579,6 @@ void gl_PreprocessLevel() -//========================================================================== -// -// Cleans up all the GL data for the last level -// -//========================================================================== - -void gl_CleanLevelData() -{ - // Dynamic lights must be destroyed before the sector information here is deleted. - TThinkerIterator it(STAT_DLIGHT); - AActor * mo=it.Next(); - while (mo) - { - AActor * next = it.Next(); - mo->Destroy(); - mo=next; - } - - if (level.sides.Size() > 0 && level.sides[0].segs) - { - delete [] level.sides[0].segs; - level.sides[0].segs = NULL; - } - if (level.sectors.Size() > 0 && level.sectors[0].subsectors) - { - delete [] level.sectors[0].subsectors; - level.sectors[0].subsectors = nullptr; - } - for (auto &sub : level.subsectors) - { - for(int j=0;j<2;j++) - { - if (sub.portalcoverage[j].subsectors != NULL) - { - delete [] sub.portalcoverage[j].subsectors; - sub.portalcoverage[j].subsectors = NULL; - } - } - } - for(unsigned i=0;inumlines > 2) ? SSRF_PROCESSED|SSRF_RENDERALL : SSRF_PROCESSED; if (sub->hacked & 1) gl_drawinfo->AddHackedSubsector(sub); - FPortal *portal; + FSectorPortalGroup *portal; - portal = fakesector->GetGLPortal(sector_t::ceiling); + portal = fakesector->GetPortalGroup(sector_t::ceiling); if (portal != NULL) { GLSectorStackPortal *glportal = portal->GetRenderState(); glportal->AddSubsector(sub); } - portal = fakesector->GetGLPortal(sector_t::floor); + portal = fakesector->GetPortalGroup(sector_t::floor); if (portal != NULL) { GLSectorStackPortal *glportal = portal->GetRenderState(); diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index d2d0a8b6e..e8a4b73cf 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -87,7 +87,7 @@ bool GLPortal::inskybox; UniqueList UniqueSkies; UniqueList UniqueHorizons; UniqueList UniquePlaneMirrors; -UniqueList UniqueLineToLines; +UniqueList UniqueLineToLines; //========================================================================== // @@ -673,6 +673,22 @@ void GLSkyboxPortal::DrawContents() // //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- + + +//========================================================================== +// +// Fixme: This needs abstraction. +// +//========================================================================== + +GLSectorStackPortal *FSectorPortalGroup::GetRenderState() +{ + if (glportal == NULL) glportal = new GLSectorStackPortal(this); + return glportal; +} + + + GLSectorStackPortal::~GLSectorStackPortal() { if (origin != NULL && origin->glportal == this) @@ -730,7 +746,7 @@ void GLSectorStackPortal::SetupCoverage() //----------------------------------------------------------------------------- void GLSectorStackPortal::DrawContents() { - FPortal *portal = origin; + FSectorPortalGroup *portal = origin; r_viewpoint.Pos += origin->mDisplacement; r_viewpoint.ActorPos += origin->mDisplacement; diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index 6b6f96668..6c3f024f8 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -74,7 +74,7 @@ struct GLSkyInfo extern UniqueList UniqueSkies; extern UniqueList UniqueHorizons; extern UniqueList UniquePlaneMirrors; -extern UniqueList UniqueLineToLines; +extern UniqueList UniqueLineToLines; struct GLEEHorizonPortal; class GLSceneDrawer; @@ -198,7 +198,7 @@ struct GLLinePortal : public GLPortal CalcDelta(); } - GLLinePortal(FGLLinePortal *line) + GLLinePortal(FLinePortalSpan *line) { if (line->lines[0]->mType != PORTT_LINKED || line->v1 == nullptr) { @@ -258,7 +258,7 @@ public: struct GLLineToLinePortal : public GLLinePortal { - FGLLinePortal *glport; + FLinePortalSpan *glport; protected: virtual void DrawContents(); virtual void * GetSource() const { return glport; } @@ -268,7 +268,7 @@ protected: public: - GLLineToLinePortal(FGLLinePortal *ll) + GLLineToLinePortal(FLinePortalSpan *ll) : GLLinePortal(ll) { glport = ll; @@ -331,11 +331,11 @@ protected: virtual void * GetSource() const { return origin; } virtual bool IsSky() { return true; } // although this isn't a real sky it can be handled as one. virtual const char *GetName(); - FPortal *origin; + FSectorPortalGroup *origin; public: - GLSectorStackPortal(FPortal *pt) + GLSectorStackPortal(FSectorPortalGroup *pt) { origin=pt; } diff --git a/src/gl/scene/gl_renderhacks.cpp b/src/gl/scene/gl_renderhacks.cpp index f121a2605..45cc254e4 100644 --- a/src/gl/scene/gl_renderhacks.cpp +++ b/src/gl/scene/gl_renderhacks.cpp @@ -1034,7 +1034,7 @@ void FDrawInfo::CollectSectorStacksCeiling(subsector_t * sub, sector_t * anchor) sub->validcount=validcount; // Has a sector stack or skybox itself! - if (sub->render_sector->GetGLPortal(sector_t::ceiling) != nullptr) return; + if (sub->render_sector->GetPortalGroup(sector_t::ceiling) != nullptr) return; // Don't bother processing unrendered subsectors if (sub->numlines>2 && !(ss_renderflags[sub->Index()]&SSRF_PROCESSED)) return; @@ -1078,7 +1078,7 @@ void FDrawInfo::CollectSectorStacksFloor(subsector_t * sub, sector_t * anchor) sub->validcount=validcount; // Has a sector stack or skybox itself! - if (sub->render_sector->GetGLPortal(sector_t::floor) != nullptr) return; + if (sub->render_sector->GetPortalGroup(sector_t::floor) != nullptr) return; // Don't bother processing unrendered subsectors if (sub->numlines>2 && !(ss_renderflags[sub->Index()]&SSRF_PROCESSED)) return; @@ -1125,7 +1125,7 @@ void FDrawInfo::ProcessSectorStacks() for (i=0;iin_area, false); - FPortal *portal = sec->GetGLPortal(sector_t::ceiling); + auto portal = sec->GetPortalGroup(sector_t::ceiling); if (portal != NULL) for(int k=0;ksubsectorcount;k++) { subsector_t * sub = sec->subsectors[k]; @@ -1149,7 +1149,7 @@ void FDrawInfo::ProcessSectorStacks() if (sub->portalcoverage[sector_t::ceiling].subsectors == NULL) { - gl_BuildPortalCoverage(&sub->portalcoverage[sector_t::ceiling], sub, portal->mDisplacement); + BuildPortalCoverage(&sub->portalcoverage[sector_t::ceiling], sub, portal->mDisplacement); } portal->GetRenderState()->AddSubsector(sub); @@ -1169,7 +1169,7 @@ void FDrawInfo::ProcessSectorStacks() for (i=0;iin_area, false); - FPortal *portal = sec->GetGLPortal(sector_t::floor); + auto portal = sec->GetPortalGroup(sector_t::floor); if (portal != NULL) for(int k=0;ksubsectorcount;k++) { subsector_t * sub = sec->subsectors[k]; @@ -1194,7 +1194,7 @@ void FDrawInfo::ProcessSectorStacks() if (sub->portalcoverage[sector_t::floor].subsectors == NULL) { - gl_BuildPortalCoverage(&sub->portalcoverage[sector_t::floor], sub, portal->mDisplacement); + BuildPortalCoverage(&sub->portalcoverage[sector_t::floor], sub, portal->mDisplacement); } GLSectorStackPortal *glportal = portal->GetRenderState(); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 82d0f196e..e7810d03e 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -42,7 +42,6 @@ #include "po_man.h" #include "r_utility.h" #include "p_local.h" -#include "gl/gl_functions.h" #include "serializer.h" #include "g_levellocals.h" #include "events.h" @@ -266,7 +265,7 @@ void GLSceneDrawer::CreateScene() ProcessAll.Clock(); // clip the scene and fill the drawlists - for(unsigned i=0;iglportal = NULL; + for(auto p : level.portalGroups) p->glportal = nullptr; GLRenderer->gl_spriteindex=0; Bsp.Clock(); GLRenderer->mVBO->Map(); @@ -462,7 +461,7 @@ void GLSceneDrawer::RenderTranslucent() //----------------------------------------------------------------------------- // // gl_drawscene - this function renders the scene from the current -// viewpoint, including mirrors and skyboxes and other glSectorPortals +// viewpoint, including mirrors and skyboxes and other portals // It is assumed that the GLPortal::EndFrame returns with the // stencil, z-buffer and the projection matrix intact! // @@ -513,7 +512,7 @@ void GLSceneDrawer::DrawScene(int drawmode) gl_RenderState.ApplyMatrices(); } - // Handle all glSectorPortals after rendering the opaque objects but before + // Handle all portals after rendering the opaque objects but before // doing all translucent stuff recursion++; GLPortal::EndFrame(); @@ -1041,7 +1040,6 @@ void FGLInterface::EndSerialize(FSerializer &arc) if (arc.isReading()) { // The portal data needs to be recreated after reading a savegame. - gl_InitPortals(); } } @@ -1152,6 +1150,7 @@ void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, do // // //=========================================================================== +void gl_PreprocessLevel(); void FGLInterface::PreprocessLevel() { @@ -1160,7 +1159,6 @@ void FGLInterface::PreprocessLevel() void FGLInterface::CleanLevelData() { - gl_CleanLevelData(); } uint32_t FGLInterface::GetCaps() diff --git a/src/gl/scene/gl_scenedrawer.h b/src/gl/scene/gl_scenedrawer.h index 9ca7132f1..4da0adae1 100644 --- a/src/gl/scene/gl_scenedrawer.h +++ b/src/gl/scene/gl_scenedrawer.h @@ -60,7 +60,7 @@ public: void DrawBlend(sector_t * viewsector); void EndDrawScene(sector_t * viewsector); void DrawEndScene2D(sector_t * viewsector); - void RenderActorsInPortal(FGLLinePortal *glport); + void RenderActorsInPortal(FLinePortalSpan *glport); void CheckViewArea(vertex_t *v1, vertex_t *v2, sector_t *frontsector, sector_t *backsector); diff --git a/src/gl/scene/gl_sky.cpp b/src/gl/scene/gl_sky.cpp index b5f0a0a34..f9defd1f9 100644 --- a/src/gl/scene/gl_sky.cpp +++ b/src/gl/scene/gl_sky.cpp @@ -29,7 +29,6 @@ #include "doomdata.h" #include "portal.h" #include "g_levellocals.h" -#include "gl/gl_functions.h" #include "gl/data/gl_data.h" #include "gl/renderer/gl_lightdata.h" @@ -135,7 +134,7 @@ void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect) case PORTS_PORTAL: case PORTS_LINKEDPORTAL: { - FPortal *glport = sector->GetGLPortal(plane); + FSectorPortalGroup *glport = sector->GetPortalGroup(plane); if (glport != NULL) { if (sector->PortalBlocksView(plane)) return; @@ -298,8 +297,8 @@ void GLWall::SkyTop(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex int type = fs->GetPortalType(sector_t::ceiling); if (type == PORTS_STACKEDSECTORTHING || type == PORTS_PORTAL || type == PORTS_LINKEDPORTAL) { - FPortal *pfront = fs->GetGLPortal(sector_t::ceiling); - FPortal *pback = bs->GetGLPortal(sector_t::ceiling); + auto pfront = fs->GetPortalGroup(sector_t::ceiling); + auto pback = bs->GetPortalGroup(sector_t::ceiling); if (pfront == NULL || fs->PortalBlocksView(sector_t::ceiling)) return; if (pfront == pback && !bs->PortalBlocksView(sector_t::ceiling)) return; } @@ -377,8 +376,8 @@ void GLWall::SkyBottom(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,ver int type = fs->GetPortalType(sector_t::floor); if (type == PORTS_STACKEDSECTORTHING || type == PORTS_PORTAL || type == PORTS_LINKEDPORTAL) { - FPortal *pfront = fs->GetGLPortal(sector_t::floor); - FPortal *pback = bs->GetGLPortal(sector_t::floor); + auto pfront = fs->GetPortalGroup(sector_t::floor); + auto pback = bs->GetPortalGroup(sector_t::floor); if (pfront == NULL || fs->PortalBlocksView(sector_t::floor)) return; if (pfront == pback && !bs->PortalBlocksView(sector_t::floor)) return; } diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 55b998120..860db2193 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -30,7 +30,6 @@ #include "p_effect.h" #include "g_level.h" #include "doomstat.h" -#include "gl/gl_functions.h" #include "r_defs.h" #include "r_sky.h" #include "r_utility.h" @@ -1284,7 +1283,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s // //========================================================================== -void GLSceneDrawer::RenderActorsInPortal(FGLLinePortal *glport) +void GLSceneDrawer::RenderActorsInPortal(FLinePortalSpan *glport) { TMap processcheck; if (glport->validcount == validcount) return; // only process once per frame diff --git a/src/gl/scene/gl_spritelight.cpp b/src/gl/scene/gl_spritelight.cpp index bab72ed03..115ec6347 100644 --- a/src/gl/scene/gl_spritelight.cpp +++ b/src/gl/scene/gl_spritelight.cpp @@ -30,7 +30,6 @@ #include "p_local.h" #include "p_effect.h" #include "vectors.h" -#include "gl/gl_functions.h" #include "g_level.h" #include "g_levellocals.h" #include "actorinlines.h" diff --git a/src/gl/scene/gl_vertex.cpp b/src/gl/scene/gl_vertex.cpp index 9d364e886..07f5303fd 100644 --- a/src/gl/scene/gl_vertex.cpp +++ b/src/gl/scene/gl_vertex.cpp @@ -23,7 +23,6 @@ #include "gl/system/gl_system.h" -#include "gl/gl_functions.h" #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_lightdata.h" diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 5d041a55f..7151b1809 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -20,9 +20,9 @@ class FMaterial; struct GLDrawList; struct GLSkyInfo; struct FTexCoordInfo; -struct FPortal; +struct FSectorPortalGroup; struct FFlatVertex; -struct FGLLinePortal; +struct FLinePortalSpan; class GLSceneDrawer; enum @@ -171,9 +171,9 @@ public: FSectorPortal *secportal; // sector portal (formerly skybox) GLSkyInfo * sky; // for normal sky GLHorizonInfo * horizon; // for horizon information - FPortal * portal; // stacked sector portals + FSectorPortalGroup * portal; // stacked sector portals secplane_t * planemirror; // for plane mirrors - FGLLinePortal *lineportal; // line-to-line portals + FLinePortalSpan *lineportal; // line-to-line portals }; diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index f7c62bca1..56e9e004f 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -179,7 +179,7 @@ void GLWall::PutPortal(int ptype) line_t *otherside = lineportal->lines[0]->mDestination; if (otherside != NULL && otherside->portalindex < level.linePortals.Size()) { - mDrawer->RenderActorsInPortal(linePortalToGL[otherside->portalindex]); + mDrawer->RenderActorsInPortal(otherside->getPortal()->mGroup); } portal = new GLLineToLinePortal(lineportal); } @@ -1562,7 +1562,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) if (seg->linedef->isVisualPortal()) { - lineportal = linePortalToGL[seg->linedef->portalindex]; + lineportal = seg->linedef->getPortal()->mGroup; ztop[0] = zceil[0]; ztop[1] = zceil[1]; zbottom[0] = zfloor[0]; @@ -1669,7 +1669,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) if (isportal) { - lineportal = linePortalToGL[seg->linedef->portalindex]; + lineportal = seg->linedef->getPortal()->mGroup; ztop[0] = bch1; ztop[1] = bch2; zbottom[0] = bfh1; diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 6bb0e7d2f..3cbaa32d4 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -27,7 +27,6 @@ #include "g_levellocals.h" #include "actor.h" #include "actorinlines.h" -#include "gl/gl_functions.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_cvars.h" diff --git a/src/gl/shaders/gl_ambientshader.cpp b/src/gl/shaders/gl_ambientshader.cpp index 3d0af2dab..e433ebd00 100644 --- a/src/gl/shaders/gl_ambientshader.cpp +++ b/src/gl/shaders/gl_ambientshader.cpp @@ -23,7 +23,6 @@ #include "gl/system/gl_system.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" diff --git a/src/gl/shaders/gl_bloomshader.cpp b/src/gl/shaders/gl_bloomshader.cpp index bc7b80b01..9dbc4ff6c 100644 --- a/src/gl/shaders/gl_bloomshader.cpp +++ b/src/gl/shaders/gl_bloomshader.cpp @@ -28,7 +28,6 @@ #include "gl/system/gl_system.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" diff --git a/src/gl/shaders/gl_blurshader.cpp b/src/gl/shaders/gl_blurshader.cpp index 56b637f6d..71cf6ffa3 100644 --- a/src/gl/shaders/gl_blurshader.cpp +++ b/src/gl/shaders/gl_blurshader.cpp @@ -28,7 +28,6 @@ #include "gl/system/gl_system.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" diff --git a/src/gl/shaders/gl_colormapshader.cpp b/src/gl/shaders/gl_colormapshader.cpp index e29b27013..2036599e9 100644 --- a/src/gl/shaders/gl_colormapshader.cpp +++ b/src/gl/shaders/gl_colormapshader.cpp @@ -28,7 +28,6 @@ #include "gl/system/gl_system.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" diff --git a/src/gl/shaders/gl_lensshader.cpp b/src/gl/shaders/gl_lensshader.cpp index c5ec679f3..a92b2dece 100644 --- a/src/gl/shaders/gl_lensshader.cpp +++ b/src/gl/shaders/gl_lensshader.cpp @@ -28,7 +28,6 @@ #include "gl/system/gl_system.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" diff --git a/src/gl/shaders/gl_postprocessshader.cpp b/src/gl/shaders/gl_postprocessshader.cpp index 2d96da90c..459e35b9f 100644 --- a/src/gl/shaders/gl_postprocessshader.cpp +++ b/src/gl/shaders/gl_postprocessshader.cpp @@ -23,7 +23,6 @@ #include "gl/system/gl_system.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "w_wad.h" #include "gl/system/gl_interface.h" diff --git a/src/gl/shaders/gl_present3dRowshader.cpp b/src/gl/shaders/gl_present3dRowshader.cpp index 94dd7dc79..0b689f5e8 100644 --- a/src/gl/shaders/gl_present3dRowshader.cpp +++ b/src/gl/shaders/gl_present3dRowshader.cpp @@ -30,7 +30,6 @@ #include "gl/system/gl_system.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" diff --git a/src/gl/shaders/gl_presentshader.cpp b/src/gl/shaders/gl_presentshader.cpp index 06056f539..b3044b7bc 100644 --- a/src/gl/shaders/gl_presentshader.cpp +++ b/src/gl/shaders/gl_presentshader.cpp @@ -28,7 +28,6 @@ #include "gl/system/gl_system.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" diff --git a/src/gl/shaders/gl_shaderprogram.cpp b/src/gl/shaders/gl_shaderprogram.cpp index dfb46c544..5db66840d 100644 --- a/src/gl/shaders/gl_shaderprogram.cpp +++ b/src/gl/shaders/gl_shaderprogram.cpp @@ -28,7 +28,6 @@ #include "gl/system/gl_system.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_cvars.h" diff --git a/src/gl/shaders/gl_shadowmapshader.cpp b/src/gl/shaders/gl_shadowmapshader.cpp index 8b81d386a..41921ef87 100644 --- a/src/gl/shaders/gl_shadowmapshader.cpp +++ b/src/gl/shaders/gl_shadowmapshader.cpp @@ -24,7 +24,6 @@ #include "files.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" diff --git a/src/gl/shaders/gl_tonemapshader.cpp b/src/gl/shaders/gl_tonemapshader.cpp index 5045618be..eede7e915 100644 --- a/src/gl/shaders/gl_tonemapshader.cpp +++ b/src/gl/shaders/gl_tonemapshader.cpp @@ -28,7 +28,6 @@ #include "gl/system/gl_system.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index be21e49d9..76db15c85 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -45,7 +45,6 @@ #include "gl/data/gl_data.h" #include "gl/textures/gl_hwtexture.h" #include "gl/utility/gl_clock.h" -#include "gl/gl_functions.h" #include "gl/data/gl_vertexbuffer.h" #include "gl_debug.h" #include "r_videoscale.h" diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index ea37c1e19..b3856cfe0 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -1024,6 +1024,7 @@ void G_SerializeLevel(FSerializer &arc, bool hubload) } } AActor::RecreateAllAttachedLights(); + InitPortalGroups(); Renderer->EndSerialize(arc); } diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 0320aca07..fe8400a88 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -111,6 +111,7 @@ #include "p_saveg.h" #include "g_levellocals.h" #include "c_dispatch.h" +#include "a_dynlight.h" #ifndef NO_EDATA #include "edata.h" #endif @@ -3499,14 +3500,24 @@ static void P_PrecacheLevel() extern polyblock_t **PolyBlockMap; -//=========================================================================== + +//========================================================================== // // // -//=========================================================================== +//========================================================================== void P_FreeLevelData () { + TThinkerIterator it(STAT_DLIGHT); + auto mo = it.Next(); + while (mo) + { + auto next = it.Next(); + mo->Destroy(); + mo = next; + } + // [ZZ] delete per-map event handlers E_Shutdown(true); MapThingsConverted.Clear(); @@ -3531,14 +3542,26 @@ void P_FreeLevelData () level.killed_monsters = level.found_items = level.found_secrets = wminfo.maxfrags = 0; + // delete allocated data in the level arrays. if (level.sectors.Size() > 0) { delete[] level.sectors[0].e; + if (level.sectors[0].subsectors) + { + delete[] level.sectors[0].subsectors; + level.sectors[0].subsectors = nullptr; + } } for (auto &sub : level.subsectors) { if (sub.BSP != nullptr) delete sub.BSP; } + if (level.sides.Size() > 0 && level.sides[0].segs) + { + delete[] level.sides[0].segs; + level.sides[0].segs = nullptr; + } + FBehavior::StaticUnloadModules (); level.segs.Clear(); diff --git a/src/portal.cpp b/src/portal.cpp index 2565d5d58..2268f8e8e 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -507,6 +507,8 @@ void P_ClearPortals() level.linePortals.Clear(); level.linkedPortals.Clear(); level.sectorPortals.Resize(2); + level.PortalBlockmap.Clear(); + // The first entry must always be the default skybox. This is what every sector gets by default. memset(&level.sectorPortals[0], 0, sizeof(level.sectorPortals[0])); level.sectorPortals[0].mType = PORTS_SKYVIEWPOINT; @@ -515,6 +517,25 @@ void P_ClearPortals() memset(&level.sectorPortals[1], 0, sizeof(level.sectorPortals[0])); level.sectorPortals[1].mType = PORTS_SKYVIEWPOINT; level.sectorPortals[1].mFlags = PORTSF_SKYFLATONLY; + + // also clear the render data + for (auto &sub : level.subsectors) + { + for (int j = 0; j<2; j++) + { + if (sub.portalcoverage[j].subsectors != nullptr) + { + delete[] sub.portalcoverage[j].subsectors; + sub.portalcoverage[j].subsectors = nullptr; + } + } + } + for (unsigned i = 0; i lines; + int validcount = 0; +}; + + //============================================================================ // // All information about a sector plane portal @@ -230,6 +242,24 @@ struct FSectorPortal } }; +//============================================================================ +// +// This groups all sector portals with identical offset. +// +//============================================================================ + +struct GLSectorStackPortal; +struct FSectorPortalGroup +{ + DVector2 mDisplacement; + int plane; + GLSectorStackPortal *glportal; // for quick access to the render data. This is only valid during BSP traversal! + + GLSectorStackPortal *GetRenderState(); +}; + + + //============================================================================ // // Functions @@ -255,6 +285,7 @@ void P_TranslatePortalVXVY(line_t* src, double &velx, double &vely); void P_TranslatePortalAngle(line_t* src, DAngle& angle); void P_TranslatePortalZ(line_t* src, double& vz); DVector2 P_GetOffsetPosition(double x, double y, double dx, double dy); +void InitPortalGroups(); #endif \ No newline at end of file diff --git a/src/posix/sdl/sdlglvideo.cpp b/src/posix/sdl/sdlglvideo.cpp index c5074f4d2..4fbf1005f 100644 --- a/src/posix/sdl/sdlglvideo.cpp +++ b/src/posix/sdl/sdlglvideo.cpp @@ -49,7 +49,6 @@ #include "sdlglvideo.h" #include "gl/system/gl_system.h" #include "r_defs.h" -#include "gl/gl_functions.h" #include "gl/renderer/gl_renderer.h" #include "gl/system/gl_framebuffer.h" diff --git a/src/r_defs.h b/src/r_defs.h index 76a0e1e44..7f17e8466 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -45,7 +45,7 @@ struct FLightNode; struct FGLSection; class FSerializer; -struct FPortal; +struct FSectorPortalGroup; struct FSectorPortal; struct FLinePortal; struct seg_t; @@ -1075,7 +1075,7 @@ public: int subsectorcount; // list of subsectors double transdoorheight; // for transparent door hacks subsector_t ** subsectors; - FPortal * portals[2]; // floor and ceiling portals + FSectorPortalGroup * portals[2]; // floor and ceiling portals enum { @@ -1089,7 +1089,7 @@ public: float GetReflect(int pos) { return gl_plane_reflection_i? reflect[pos] : 0; } bool VBOHeightcheck(int pos) const { return vboheight[pos] == GetPlaneTexZ(pos); } - FPortal *GetGLPortal(int plane) { return portals[plane]; } + FSectorPortalGroup *GetPortalGroup(int plane) { return portals[plane]; } enum { @@ -1418,6 +1418,8 @@ struct FPortalCoverage int sscount; }; +void BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, const DVector2 &displacement); + struct subsector_t { sector_t *sector;