diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2e3c14385..393d71694 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1043,7 +1043,6 @@ set (PCH_SOURCES g_statusbar/sbar_mugshot.cpp g_statusbar/shared_sbar.cpp gl/compatibility/gl_20.cpp - gl/data/gl_setup.cpp gl/data/gl_vertexbuffer.cpp gl/dynlights/gl_glow.cpp gl/dynlights/gl_lightbuffer.cpp @@ -1150,6 +1149,7 @@ set (PCH_SOURCES r_data/sprites.cpp r_data/portalgroups.cpp r_data/voxels.cpp + r_data/renderinfo.cpp r_data/renderstyle.cpp r_data/r_interpolate.cpp r_data/r_vanillatrans.cpp diff --git a/src/g_levellocals.h b/src/g_levellocals.h index 53fea8f97..78d6e9034 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -91,6 +91,7 @@ struct FLevelLocals TArray linkedPortals; // only the linked portals, this is used to speed up looking for them in P_CollectConnectedGroups. TArray portalGroups; TArray linePortalSpans; + int NumMapSections; TArray Zones; diff --git a/src/gl/data/gl_data.h b/src/gl/data/gl_data.h index bd68bf591..e39d6f077 100644 --- a/src/gl/data/gl_data.h +++ b/src/gl/data/gl_data.h @@ -17,9 +17,4 @@ inline int getExtraLight() return r_viewpoint.extralight * gl_weaponlight; } - -struct GLSectorStackPortal; - -extern TArray currentmapsection; - #endif diff --git a/src/gl/scene/gl_bsp.cpp b/src/gl/scene/gl_bsp.cpp index 1c8ecd4ad..aa71e1966 100644 --- a/src/gl/scene/gl_bsp.cpp +++ b/src/gl/scene/gl_bsp.cpp @@ -423,7 +423,7 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub) if (!sector) return; // If the mapsections differ this subsector can't possibly be visible from the current view point - if (!(currentmapsection[sub->mapsection>>3] & (1 << (sub->mapsection & 7)))) return; + if (!CurrentMapSections[sub->mapsection]) return; if (sub->flags & SSECF_POLYORG) return; // never render polyobject origin subsectors because their vertices no longer are where one may expect. if (gl_drawinfo->ss_renderflags[sub->Index()] & SSRF_SEEN) diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index e8a4b73cf..884eafcfa 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -579,20 +579,22 @@ GLPortal * GLPortal::FindPortal(const void * src) //----------------------------------------------------------------------------- // -// +// Save/RestoreMapSection +// +// saves CurrentMapSection for a recursive call of SceneDrawer::DrawScene // //----------------------------------------------------------------------------- void GLPortal::SaveMapSection() { - savedmapsection.Resize(currentmapsection.Size()); - memcpy(&savedmapsection[0], ¤tmapsection[0], currentmapsection.Size()); - memset(¤tmapsection[0], 0, currentmapsection.Size()); + SavedMapSection = std::move(drawer->CurrentMapSections); + drawer->CurrentMapSections.Resize(SavedMapSection.Size()); + drawer->CurrentMapSections.Zero(); } void GLPortal::RestoreMapSection() { - memcpy(¤tmapsection[0], &savedmapsection[0], currentmapsection.Size()); + drawer->CurrentMapSections = std::move(SavedMapSection); } //----------------------------------------------------------------------------- @@ -650,7 +652,7 @@ void GLSkyboxPortal::DrawContents() int mapsection = R_PointInSubsector(r_viewpoint.Pos)->mapsection; SaveMapSection(); - currentmapsection[mapsection >> 3] |= 1 << (mapsection & 7); + drawer->CurrentMapSections.Set(mapsection); drawer->DrawScene(DM_SKYPORTAL); portal->mFlags &= ~PORTSF_INSKYBOX; @@ -732,7 +734,7 @@ void GLSectorStackPortal::SetupCoverage() for(int j=0;jportalcoverage[plane].sscount; j++) { subsector_t *dsub = &::level.subsectors[sub->portalcoverage[plane].subsectors[j]]; - currentmapsection[dsub->mapsection>>3] |= 1 << (dsub->mapsection&7); + drawer->CurrentMapSections.Set(dsub->mapsection); gl_drawinfo->ss_renderflags[dsub->Index()] |= SSRF_SEEN; } } @@ -1055,8 +1057,7 @@ void GLLineToLinePortal::DrawContents() if (line->sidedef[0]->Flags & WALLF_POLYOBJ) sub = R_PointInSubsector(line->v1->fixX(), line->v1->fixY()); else sub = line->frontsector->subsectors[0]; - int mapsection = sub->mapsection; - currentmapsection[mapsection >> 3] |= 1 << (mapsection & 7); + drawer->CurrentMapSections.Set(sub->mapsection); } GLRenderer->mViewActor = nullptr; diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index 6c3f024f8..fb09f8c2a 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -109,7 +109,7 @@ private: ActorRenderFlags savedvisibility; GLPortal *PrevPortal; GLPortal *PrevClipPortal; - TArray savedmapsection; + BitArray SavedMapSection; TArray mPrimIndices; protected: diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 2517e23ad..47ba1d27e 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -88,7 +88,6 @@ EXTERN_CVAR (Bool, r_drawvoxels) extern bool NoInterpolateView; area_t in_area; -TArray currentmapsection; int camtexcount; //----------------------------------------------------------------------------- @@ -737,8 +736,9 @@ void GLSceneDrawer::ProcessScene(bool toscreen) GLPortal::BeginScene(); int mapsection = R_PointInSubsector(r_viewpoint.Pos)->mapsection; - memset(¤tmapsection[0], 0, currentmapsection.Size()); - currentmapsection[mapsection>>3] |= 1 << (mapsection & 7); + CurrentMapSections.Resize(level.NumMapSections); + CurrentMapSections.Zero(); + CurrentMapSections.Set(mapsection); DrawScene(toscreen ? DM_MAINVIEW : DM_OFFSCREEN); FDrawInfo::EndDrawInfo(); @@ -1129,10 +1129,12 @@ void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, do // // //=========================================================================== -void gl_PreprocessLevel(); void FGLInterface::PreprocessLevel() { - gl_PreprocessLevel(); + if (GLRenderer != NULL) + { + GLRenderer->SetupLevel(); + } } uint32_t FGLInterface::GetCaps() diff --git a/src/gl/scene/gl_scenedrawer.h b/src/gl/scene/gl_scenedrawer.h index 4da0adae1..fab871819 100644 --- a/src/gl/scene/gl_scenedrawer.h +++ b/src/gl/scene/gl_scenedrawer.h @@ -45,6 +45,7 @@ public: Clipper clipper; int FixedColormap; area_t in_area; + BitArray CurrentMapSections; // this cannot be a single number, because a group of portals with the same displacement may link different sections. angle_t FrustumAngle(); void SetViewMatrix(float vx, float vy, float vz, bool mirror, bool planemirror); @@ -71,7 +72,7 @@ public: void DrawPSprite(player_t * player, DPSprite *psp, float sx, float sy, bool hudModelStep, int OverrideShader, bool alphatexture); void DrawPlayerSprites(sector_t * viewsector, bool hudModelStep); void DrawTargeterSprites(); - + void InitClipper(angle_t a1, angle_t a2) { clipper.Clear(); diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 860db2193..60eea0b59 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -721,7 +721,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) } // If this thing is in a map section that's not in view it can't possibly be visible - if (!thruportal && !(currentmapsection[thing->subsector->mapsection >> 3] & (1 << (thing->subsector->mapsection & 7)))) return; + if (!thruportal && !mDrawer->CurrentMapSections[thing->subsector->mapsection]) return; // [RH] Interpolate the sprite's position to make it look smooth DVector3 thingpos = thing->InterpolatedPosition(r_viewpoint.TicFrac); diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 98c20b1cb..ab4d519f4 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -129,6 +129,7 @@ void P_SetSlopes (); void P_CopySlopes(); void BloodCrypt (void *data, int key, int len); void P_ClearUDMFKeys(); +void InitRenderInfo(); extern AActor *P_SpawnMapThing (FMapThing *mthing, int position); @@ -4120,6 +4121,7 @@ void P_SetupLevel (const char *lumpname, int position) } // This must be done BEFORE the PolyObj Spawn!!! + InitRenderInfo(); Renderer->PreprocessLevel(); InitPortalGroups(); diff --git a/src/gl/data/gl_setup.cpp b/src/r_data/renderinfo.cpp similarity index 97% rename from src/gl/data/gl_setup.cpp rename to src/r_data/renderinfo.cpp index 658b2607d..38e159f27 100644 --- a/src/gl/data/gl_setup.cpp +++ b/src/r_data/renderinfo.cpp @@ -21,8 +21,8 @@ // /* ** gl_setup.cpp -** Initializes the data structures required by the GL renderer to handle -** a level +** Initializes the data structures required by the hardware renderer to handle +** render hacks and optimization. ** **/ @@ -42,13 +42,6 @@ #include "g_level.h" #include "g_levellocals.h" -#include "gl/renderer/gl_renderer.h" -#include "gl/data/gl_data.h" -#include "gl/data/gl_vertexbuffer.h" -#include "gl/dynlights/gl_dynlight.h" -#include "gl/dynlights/gl_glow.h" -#include "gl/utility/gl_clock.h" - //========================================================================== // // Map section generation @@ -208,7 +201,7 @@ struct MapSectionGenerator } while (set); num = MergeMapSections(num); - currentmapsection.Resize(1 + num/8); + level.NumMapSections = num; #ifdef DEBUG Printf("%d map sections found\n", num); #endif @@ -544,7 +537,7 @@ static void PrepareSegs() // //========================================================================== -void gl_PreprocessLevel() +void InitRenderInfo() { PrepareSegs(); PrepareSectorData(); @@ -581,11 +574,6 @@ void gl_PreprocessLevel() } delete[] checkmap; - if (GLRenderer != NULL) - { - GLRenderer->SetupLevel(); - } - #if 0 gl_CreateSections(); #endif diff --git a/src/tarray.h b/src/tarray.h index 7f566112b..7d68e58c5 100644 --- a/src/tarray.h +++ b/src/tarray.h @@ -1259,3 +1259,74 @@ public: Clear(); } }; + + +class BitArray +{ + TArray bytes; + unsigned size; + +public: + void Resize(unsigned elem) + { + bytes.Resize((elem + 7) / 8); + size = elem; + } + + BitArray() : size(0) + { + } + + BitArray(const BitArray & arr) + { + bytes = arr.bytes; + size = arr.size; + } + + BitArray &operator=(const BitArray & arr) + { + bytes = arr.bytes; + size = arr.size; + return *this; + } + + BitArray(BitArray && arr) + { + bytes = std::move(arr.bytes); + size = arr.size; + arr.size = 0; + } + + BitArray &operator=(BitArray && arr) + { + bytes = std::move(arr.bytes); + size = arr.size; + arr.size = 0; + return *this; + } + + bool operator[](size_t index) const + { + return !!(bytes[index >> 3] & (1 << (index & 7))); + } + + void Set(size_t index) + { + bytes[index >> 3] |= (1 << (index & 7)); + } + + void Clear(size_t index) + { + bytes[index >> 3] &= ~(1 << (index & 7)); + } + + unsigned Size() const + { + return size; + } + + void Zero() + { + memset(&bytes[0], 0, bytes.Size()); + } +};