From ac212e0147caa2499fae3b54ff78758db6376d98 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Tue, 5 Dec 2023 10:01:03 +0100 Subject: [PATCH] Use HWFlat for ceilings and floors --- src/CMakeLists.txt | 2 - src/maploader/maploader.cpp | 2 - .../hwrenderer/doom_levelsubmesh.cpp | 344 ++++++------------ src/rendering/hwrenderer/doom_levelsubmesh.h | 8 - src/rendering/hwrenderer/hw_entrypoint.cpp | 3 - src/rendering/hwrenderer/scene/hw_bsp.cpp | 63 +--- .../hwrenderer/scene/hw_drawinfo.cpp | 19 - src/rendering/hwrenderer/scene/hw_drawinfo.h | 2 - .../hwrenderer/scene/hw_drawlist.cpp | 7 +- .../hwrenderer/scene/hw_drawstructs.h | 17 +- .../hwrenderer/scene/hw_flatdispatcher.h | 86 +++++ src/rendering/hwrenderer/scene/hw_flats.cpp | 51 ++- .../hwrenderer/scene/hw_meshcache.cpp | 162 --------- src/rendering/hwrenderer/scene/hw_meshcache.h | 36 -- .../hwrenderer/scene/hw_meshportal.cpp | 64 ---- .../hwrenderer/scene/hw_meshportal.h | 12 - .../hwrenderer/scene/hw_renderhacks.cpp | 10 +- src/rendering/hwrenderer/scene/hw_walls.cpp | 8 - 18 files changed, 268 insertions(+), 628 deletions(-) create mode 100644 src/rendering/hwrenderer/scene/hw_flatdispatcher.h delete mode 100644 src/rendering/hwrenderer/scene/hw_meshcache.cpp delete mode 100644 src/rendering/hwrenderer/scene/hw_meshcache.h delete mode 100644 src/rendering/hwrenderer/scene/hw_meshportal.cpp delete mode 100644 src/rendering/hwrenderer/scene/hw_meshportal.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e7fa474a7..874654605 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -727,7 +727,6 @@ set( FASTMATH_SOURCES rendering/hwrenderer/scene/hw_clipper.cpp rendering/hwrenderer/scene/hw_flats.cpp rendering/hwrenderer/scene/hw_portal.cpp - rendering/hwrenderer/scene/hw_meshportal.cpp rendering/hwrenderer/scene/hw_renderhacks.cpp rendering/hwrenderer/scene/hw_sky.cpp rendering/hwrenderer/scene/hw_skyportal.cpp @@ -896,7 +895,6 @@ set (PCH_SOURCES rendering/hwrenderer/scene/hw_lighting.cpp rendering/hwrenderer/scene/hw_drawlistadd.cpp rendering/hwrenderer/scene/hw_setcolor.cpp - rendering/hwrenderer/scene/hw_meshcache.cpp maploader/edata.cpp maploader/specials.cpp maploader/maploader.cpp diff --git a/src/maploader/maploader.cpp b/src/maploader/maploader.cpp index cb3ce4bfe..fee51d9fa 100644 --- a/src/maploader/maploader.cpp +++ b/src/maploader/maploader.cpp @@ -83,7 +83,6 @@ #include "vm.h" #include "texturemanager.h" #include "hw_vertexbuilder.h" -#include "scene/hw_meshcache.h" #include "version.h" #include "vulkan/accelstructs/halffloat.h" @@ -3713,7 +3712,6 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position) InitRenderInfo(); // create hardware independent renderer resources for the level. This must be done BEFORE the PolyObj Spawn!!! Level->ClearDynamic3DFloorData(); // CreateVBO must be run on the plain 3D floor data. CreateVBO(*screen->RenderState(), Level->sectors); - meshcache.Clear(); for (auto &sec : Level->sectors) { diff --git a/src/rendering/hwrenderer/doom_levelsubmesh.cpp b/src/rendering/hwrenderer/doom_levelsubmesh.cpp index 149634dff..bed2d1b56 100644 --- a/src/rendering/hwrenderer/doom_levelsubmesh.cpp +++ b/src/rendering/hwrenderer/doom_levelsubmesh.cpp @@ -8,9 +8,11 @@ #include "g_levellocals.h" #include "a_dynlight.h" #include "hw_renderstate.h" +#include "hw_vertexbuilder.h" #include "hwrenderer/scene/hw_drawstructs.h" #include "hwrenderer/scene/hw_drawinfo.h" #include "hwrenderer/scene/hw_walldispatcher.h" +#include "hwrenderer/scene/hw_flatdispatcher.h" #include "common/rendering/hwrenderer/data/hw_meshbuilder.h" #include "common/rendering/vulkan/accelstructs/vk_lightmap.h" #include "common/rendering/vulkan/accelstructs/halffloat.h" @@ -88,6 +90,8 @@ void DoomLevelSubmesh::CreateStaticSurfaces(FLevelLocals& doomMap) } } + MeshBuilder state; + // Create surface objects for all visible side parts for (unsigned int i = 0; i < doomMap.sides.Size(); i++) { @@ -104,7 +108,6 @@ void DoomLevelSubmesh::CreateStaticSurfaces(FLevelLocals& doomMap) sector_t* front = side->sector; sector_t* back = (side->linedef->frontsector == front) ? side->linedef->backsector : side->linedef->frontsector; - MeshBuilder state; HWMeshHelper result; HWWallDispatcher disp(&doomMap, &result, ELightMode::ZDoomSoftware); HWWall wall; @@ -150,8 +153,18 @@ void DoomLevelSubmesh::CreateStaticSurfaces(FLevelLocals& doomMap) MeshUniformIndexes.Push(uniformsIndex); } } + for (MeshDrawCommand& command : it.second.mIndexedDraws) + { + for (int i = command.Start, end = command.Start + command.Count; i < end; i++) + { + MeshVertices.Push(state.mVertices[state.mIndexes[i]]); + MeshUniformIndexes.Push(uniformsIndex); + } + } } state.mSortedLists.clear(); + state.mVertices.Clear(); + state.mIndexes.Clear(); DoomLevelMeshSurface surf; surf.Submesh = this; @@ -177,20 +190,103 @@ void DoomLevelSubmesh::CreateStaticSurfaces(FLevelLocals& doomMap) } // Create surfaces for all flats - for (unsigned int i = 0; i < doomMap.subsectors.Size(); i++) + for (unsigned int i = 0; i < doomMap.sectors.Size(); i++) { - subsector_t* sub = &doomMap.subsectors[i]; - if (sub->numlines < 3 || !sub->sector) - continue; - sector_t* sector = sub->sector; - - CreateFloorSurface(doomMap, sub, sector, nullptr, i); - CreateCeilingSurface(doomMap, sub, sector, nullptr, i); - - for (unsigned int j = 0; j < sector->e->XFloor.ffloors.Size(); j++) + sector_t* sector = &doomMap.sectors[i]; + for (FSection& section : doomMap.sections.SectionsForSector(i)) { - CreateFloorSurface(doomMap, sub, sector, sector->e->XFloor.ffloors[j]->model, i); - CreateCeilingSurface(doomMap, sub, sector, sector->e->XFloor.ffloors[j]->model, i); + int sectionIndex = doomMap.sections.SectionIndex(§ion); + + HWFlatMeshHelper result; + HWFlatDispatcher disp(&doomMap, &result, ELightMode::ZDoomSoftware); + + HWFlat flat; + flat.section = §ion; + flat.ProcessSector(&disp, state, sector); + + // Part 1: solid geometry. This is set up so that there are no transparent parts + state.SetDepthFunc(DF_Less); + state.ClearDepthBias(); + state.EnableTexture(gl_texture); + state.EnableBrightmap(true); + + for (HWFlat& flatpart : result.list) + { + if (flatpart.texture && flatpart.texture->isMasked()) + { + state.AlphaFunc(Alpha_GEqual, gl_mask_threshold); + } + else + { + state.AlphaFunc(Alpha_GEqual, 0.f); + } + + flatpart.DrawFlat(&disp, state, false); + + int pipelineID = 0; + int uniformsIndex = 0; + bool foundDraw = false; + for (auto& it : state.mSortedLists) + { + const MeshApplyState& applyState = it.first; + + pipelineID = screen->GetLevelMeshPipelineID(applyState.applyData, applyState.surfaceUniforms, applyState.material); + uniformsIndex = MeshSurfaceUniforms.Size(); + MeshSurfaceUniforms.Push(applyState.surfaceUniforms); + MeshSurfaceMaterials.Push(applyState.material); + + foundDraw = true; + break; + } + state.mSortedLists.clear(); + state.mVertices.Clear(); + state.mIndexes.Clear(); + + if (!foundDraw) + continue; + + auto plane = sector->GetSecPlane(flatpart.ceiling); + + DoomLevelMeshSurface surf; + surf.Submesh = this; + surf.Type = flatpart.ceiling ? ST_CEILING : ST_FLOOR; + surf.ControlSector = flatpart.controlsector ? flatpart.controlsector->model : nullptr; + surf.AlwaysUpdate = !!(sector->Flags & SECF_LM_DYNAMIC); + surf.sectorGroup = sectorGroup[sector->Index()]; + surf.alpha = flatpart.alpha; + surf.texture = flatpart.texture; + surf.PipelineID = pipelineID; + surf.plane = FVector4((float)plane.Normal().X, (float)plane.Normal().Y, (float)plane.Normal().Z, -(float)plane.D); + + for (subsector_t* sub : section.subsectors) + { + int startVertIndex = MeshVertices.Size(); + + for (int i = 0, end = sub->numlines; i < end; i++) + { + auto& vt = sub->firstline[i].v1; + + FFlatVertex ffv; + ffv.x = (float)vt->fX(); + ffv.y = (float)vt->fY(); + ffv.z = (float)plane.ZatPoint(vt); + ffv.u = (float)vt->fX() / 64.f; + ffv.v = -(float)vt->fY() / 64.f; + ffv.lu = 0.0f; + ffv.lv = 0.0f; + ffv.lindex = -1.0f; + + MeshVertices.Push(ffv); + MeshUniformIndexes.Push(uniformsIndex); + } + + surf.TypeIndex = sub->Index(); + surf.Subsector = sub; + surf.startVertIndex = startVertIndex; + surf.numVerts = sub->numlines; + Surfaces.Push(surf); + } + } } } } @@ -532,192 +628,6 @@ void DoomLevelSubmesh::SetSideLightmap(DoomLevelMeshSurface* surface) } } -void DoomLevelSubmesh::CreateFloorSurface(FLevelLocals &doomMap, subsector_t *sub, sector_t *sector, sector_t *controlSector, int typeIndex) -{ - DoomLevelMeshSurface surf; - surf.Submesh = this; - - secplane_t plane; - if (!controlSector) - { - plane = sector->floorplane; - surf.bSky = IsSkySector(sector, sector_t::floor); - } - else - { - plane = controlSector->ceilingplane; - plane.FlipVert(); - surf.bSky = false; - } - - surf.numVerts = sub->numlines; - surf.startVertIndex = MeshVertices.Size(); - surf.texture = TexMan.GetGameTexture((controlSector ? controlSector : sector)->planes[sector_t::floor].Texture); - - FGameTexture* txt = surf.texture; - float w = txt->GetDisplayWidth(); - float h = txt->GetDisplayHeight(); - VSMatrix mat = GetPlaneTextureRotationMatrix(txt, sector, sector_t::floor); - - int uniformsIndex = MeshSurfaceUniforms.Size(); - - MeshVertices.Resize(surf.startVertIndex + surf.numVerts); - - FFlatVertex* verts = &MeshVertices[surf.startVertIndex]; - - for (int j = 0; j < surf.numVerts; j++) - { - seg_t* seg = &sub->firstline[j]; - FVector2 v1 = ToFVector2(seg->v1->fPos()); - FVector2 uv = (mat * FVector4(v1.X / 64.f, -v1.Y / 64.f, 0.f, 1.f)).XY(); // The magic 64.f and negative Y is based on SetFlatVertex - - verts[j].x = v1.X; - verts[j].y = v1.Y; - verts[j].z = (float)plane.ZatPoint(v1); - verts[j].u = uv.X; - verts[j].v = uv.Y; - - MeshUniformIndexes.Push(uniformsIndex); - } - - surf.Type = ST_FLOOR; - surf.TypeIndex = typeIndex; - surf.sampleDimension = (controlSector ? controlSector : sector)->planes[sector_t::floor].LightmapSampleDistance; - surf.ControlSector = controlSector; - surf.plane = FVector4((float)plane.Normal().X, (float)plane.Normal().Y, (float)plane.Normal().Z, -(float)plane.D); - surf.sectorGroup = sectorGroup[sector->Index()]; - surf.AlwaysUpdate = !!(sector->Flags & SECF_LM_DYNAMIC); - surf.Subsector = sub; - - SurfaceUniforms uniforms = DefaultUniforms(); - uniforms.uLightLevel = sector->lightlevel * (1.0f / 255.0f); - - FMaterialState material; - material.mMaterial = FMaterial::ValidateTexture(txt, 0); - material.mClampMode = CLAMP_NONE; - material.mTranslation = 0; - material.mOverrideShader = -1; - material.mChanged = true; - if (material.mMaterial) - { - auto scale = material.mMaterial->GetDetailScale(); - uniforms.uDetailParms = { scale.X, scale.Y, 2, 0 }; - } - - MeshSurfaceUniforms.Push(uniforms); - MeshSurfaceMaterials.Push(material); - Surfaces.Push(surf); -} - -void DoomLevelSubmesh::CreateCeilingSurface(FLevelLocals& doomMap, subsector_t* sub, sector_t* sector, sector_t* controlSector, int typeIndex) -{ - DoomLevelMeshSurface surf; - surf.Submesh = this; - - secplane_t plane; - if (!controlSector) - { - plane = sector->ceilingplane; - surf.bSky = IsSkySector(sector, sector_t::ceiling); - } - else - { - plane = controlSector->floorplane; - plane.FlipVert(); - surf.bSky = false; - } - - surf.numVerts = sub->numlines; - surf.startVertIndex = MeshVertices.Size(); - surf.texture = TexMan.GetGameTexture((controlSector ? controlSector : sector)->planes[sector_t::ceiling].Texture); - - FGameTexture* txt = surf.texture; - float w = txt->GetDisplayWidth(); - float h = txt->GetDisplayHeight(); - VSMatrix mat = GetPlaneTextureRotationMatrix(txt, sector, sector_t::ceiling); - - int uniformsIndex = MeshSurfaceUniforms.Size(); - - MeshVertices.Resize(surf.startVertIndex + surf.numVerts); - - FFlatVertex* verts = &MeshVertices[surf.startVertIndex]; - - for (int j = 0; j < surf.numVerts; j++) - { - seg_t* seg = &sub->firstline[j]; - FVector2 v1 = ToFVector2(seg->v1->fPos()); - FVector2 uv = (mat * FVector4(v1.X / 64.f, -v1.Y / 64.f, 0.f, 1.f)).XY(); // The magic 64.f and negative Y is based on SetFlatVertex - - verts[j].x = v1.X; - verts[j].y = v1.Y; - verts[j].z = (float)plane.ZatPoint(v1); - verts[j].u = uv.X; - verts[j].v = uv.Y; - - MeshUniformIndexes.Push(uniformsIndex); - } - - surf.Type = ST_CEILING; - surf.TypeIndex = typeIndex; - surf.sampleDimension = (controlSector ? controlSector : sector)->planes[sector_t::ceiling].LightmapSampleDistance; - surf.ControlSector = controlSector; - surf.plane = FVector4((float)plane.Normal().X, (float)plane.Normal().Y, (float)plane.Normal().Z, -(float)plane.D); - surf.sectorGroup = sectorGroup[sector->Index()]; - surf.AlwaysUpdate = !!(sector->Flags & SECF_LM_DYNAMIC); - surf.Subsector = sub; - - SurfaceUniforms uniforms = DefaultUniforms(); - uniforms.uLightLevel = sector->lightlevel * (1.0f / 255.0f); - - FMaterialState material; - material.mMaterial = FMaterial::ValidateTexture(txt, 0); - material.mClampMode = CLAMP_NONE; - material.mTranslation = 0; - material.mOverrideShader = -1; - material.mChanged = true; - if (material.mMaterial) - { - auto scale = material.mMaterial->GetDetailScale(); - uniforms.uDetailParms = { scale.X, scale.Y, 2, 0 }; - } - - MeshSurfaceUniforms.Push(uniforms); - MeshSurfaceMaterials.Push(material); - Surfaces.Push(surf); -} - -void DoomLevelSubmesh::CreateSubsectorSurfaces(FLevelLocals &doomMap) -{ - for (unsigned int i = 0; i < doomMap.subsectors.Size(); i++) - { - subsector_t *sub = &doomMap.subsectors[i]; - - if (sub->numlines < 3) - { - continue; - } - - sector_t *sector = sub->sector; - if (!sector) - continue; - - CreateFloorSurface(doomMap, sub, sector, nullptr, i); - CreateCeilingSurface(doomMap, sub, sector, nullptr, i); - - for (unsigned int j = 0; j < sector->e->XFloor.ffloors.Size(); j++) - { - CreateFloorSurface(doomMap, sub, sector, sector->e->XFloor.ffloors[j]->model, i); - CreateCeilingSurface(doomMap, sub, sector, sector->e->XFloor.ffloors[j]->model, i); - } - } -} - -bool DoomLevelSubmesh::IsSkySector(sector_t* sector, int plane) -{ - // plane is either sector_t::ceiling or sector_t::floor - return sector->GetTexture(plane) == skyflatnum; -} - bool DoomLevelSubmesh::IsDegenerate(const FVector3 &v0, const FVector3 &v1, const FVector3 &v2) { // A degenerate triangle has a zero cross product for two of its sides. @@ -933,39 +843,3 @@ void DoomLevelSubmesh::BuildSurfaceParams(int lightMapTextureWidth, int lightMap surface.AtlasTile.Width = width; surface.AtlasTile.Height = height; } - -SurfaceUniforms DoomLevelSubmesh::DefaultUniforms() -{ - SurfaceUniforms surfaceUniforms = {}; - surfaceUniforms.uFogColor = toFVector4(PalEntry(0xffffffff)); - surfaceUniforms.uDesaturationFactor = 0.0f; - surfaceUniforms.uAlphaThreshold = 0.5f; - surfaceUniforms.uAddColor = toFVector4(PalEntry(0)); - surfaceUniforms.uObjectColor = toFVector4(PalEntry(0xffffffff)); - surfaceUniforms.uObjectColor2 = toFVector4(PalEntry(0)); - surfaceUniforms.uTextureBlendColor = toFVector4(PalEntry(0)); - surfaceUniforms.uTextureAddColor = toFVector4(PalEntry(0)); - surfaceUniforms.uTextureModulateColor = toFVector4(PalEntry(0)); - surfaceUniforms.uLightDist = 0.0f; - surfaceUniforms.uLightFactor = 0.0f; - surfaceUniforms.uFogDensity = 0.0f; - surfaceUniforms.uLightLevel = -1.0f; - surfaceUniforms.uInterpolationFactor = 0; - surfaceUniforms.uVertexColor = { 1.0f, 1.0f, 1.0f, 1.0f }; - surfaceUniforms.uGlowTopColor = { 0.0f, 0.0f, 0.0f, 0.0f }; - surfaceUniforms.uGlowBottomColor = { 0.0f, 0.0f, 0.0f, 0.0f }; - surfaceUniforms.uGlowTopPlane = { 0.0f, 0.0f, 0.0f, 0.0f }; - surfaceUniforms.uGlowBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f }; - surfaceUniforms.uGradientTopPlane = { 0.0f, 0.0f, 0.0f, 0.0f }; - surfaceUniforms.uGradientBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f }; - surfaceUniforms.uSplitTopPlane = { 0.0f, 0.0f, 0.0f, 0.0f }; - surfaceUniforms.uSplitBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f }; - surfaceUniforms.uDynLightColor = { 0.0f, 0.0f, 0.0f, 1.0f }; - surfaceUniforms.uDetailParms = { 0.0f, 0.0f, 0.0f, 0.0f }; -#ifdef NPOT_EMULATION - surfaceUniforms.uNpotEmulation = { 0,0,0,0 }; -#endif - surfaceUniforms.uClipSplit.X = -1000000.f; - surfaceUniforms.uClipSplit.Y = 1000000.f; - return surfaceUniforms; -} diff --git a/src/rendering/hwrenderer/doom_levelsubmesh.h b/src/rendering/hwrenderer/doom_levelsubmesh.h index 5874d53e8..09694fb9a 100644 --- a/src/rendering/hwrenderer/doom_levelsubmesh.h +++ b/src/rendering/hwrenderer/doom_levelsubmesh.h @@ -58,10 +58,6 @@ private: void CreateStaticSurfaces(FLevelLocals& doomMap); void CreateDynamicSurfaces(FLevelLocals& doomMap); - void CreateSubsectorSurfaces(FLevelLocals& doomMap); - void CreateCeilingSurface(FLevelLocals& doomMap, subsector_t* sub, sector_t* sector, sector_t* controlSector, int typeIndex); - void CreateFloorSurface(FLevelLocals& doomMap, subsector_t* sub, sector_t* sector, sector_t* controlSector, int typeIndex); - void SetSubsectorLightmap(DoomLevelMeshSurface* surface); void SetSideLightmap(DoomLevelMeshSurface* surface); @@ -69,8 +65,6 @@ private: void CreateIndexes(); - static bool IsSkySector(sector_t* sector, int plane); - static FVector4 ToPlane(const FVector3& pt1, const FVector3& pt2, const FVector3& pt3) { FVector3 n = ((pt2 - pt1) ^ (pt3 - pt2)).Unit(); @@ -111,8 +105,6 @@ private: static FVector2 ToFVector2(const DVector2& v) { return FVector2((float)v.X, (float)v.Y); } static FVector3 ToFVector3(const DVector3& v) { return FVector3((float)v.X, (float)v.Y, (float)v.Z); } static FVector4 ToFVector4(const DVector4& v) { return FVector4((float)v.X, (float)v.Y, (float)v.Z, (float)v.W); } - - static SurfaceUniforms DefaultUniforms(); }; static_assert(alignof(FVector2) == alignof(float[2]) && sizeof(FVector2) == sizeof(float) * 2); diff --git a/src/rendering/hwrenderer/hw_entrypoint.cpp b/src/rendering/hwrenderer/hw_entrypoint.cpp index a7e42ab93..810a4ebd5 100644 --- a/src/rendering/hwrenderer/hw_entrypoint.cpp +++ b/src/rendering/hwrenderer/hw_entrypoint.cpp @@ -47,7 +47,6 @@ #include "hwrenderer/scene/hw_fakeflat.h" #include "hwrenderer/scene/hw_clipper.h" #include "hwrenderer/scene/hw_portal.h" -#include "hwrenderer/scene/hw_meshcache.h" #include "hwrenderer/scene/hw_drawcontext.h" #include "hw_vrmodes.h" @@ -134,8 +133,6 @@ sector_t* RenderViewpoint(FRenderViewpoint& mainvp, AActor* camera, IntRect* bou hw_ClearFakeFlat(&mainthread_drawctx); - meshcache.Update(&mainthread_drawctx, mainvp); - // Render (potentially) multiple views for stereo 3d // Fixme. The view offsetting should be done with a static table and not require setup of the entire render state for the mode. auto vrmode = VRMode::GetVRMode(mainview && toscreen); diff --git a/src/rendering/hwrenderer/scene/hw_bsp.cpp b/src/rendering/hwrenderer/scene/hw_bsp.cpp index a57c6a761..d89acd029 100644 --- a/src/rendering/hwrenderer/scene/hw_bsp.cpp +++ b/src/rendering/hwrenderer/scene/hw_bsp.cpp @@ -42,8 +42,8 @@ #include "hw_clock.h" #include "flatvertices.h" #include "hw_vertexbuilder.h" -#include "hw_meshportal.h" #include "hw_walldispatcher.h" +#include "hw_flatdispatcher.h" #ifdef ARCH_IA32 #include @@ -52,7 +52,6 @@ CVAR(Bool, gl_multithread, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) EXTERN_CVAR(Float, r_actorspriteshadowdist) -EXTERN_CVAR(Bool, gl_meshcache) thread_local bool isWorkerThread; ctpl::thread_pool renderPool(1); @@ -109,6 +108,7 @@ void HWDrawInfo::WorkerThread() { sector_t *front, *back; HWWallDispatcher disp(this); + HWFlatDispatcher fdisp(this); FRenderState& state = *screen->RenderState(); @@ -171,23 +171,12 @@ void HWDrawInfo::WorkerThread() } else back = nullptr; - if (MeshBSP) - { - SetupWall.Clock(); - HWPortalWall portalwall; - portalwall.Process(&disp, state, job->seg, front, back); - rendered_lines++; - SetupWall.Unclock(); - } - else - { - HWWall wall; - SetupWall.Clock(); - wall.sub = job->sub; - wall.Process(&disp, state, job->seg, front, back); - rendered_lines++; - SetupWall.Unclock(); - } + HWWall wall; + SetupWall.Clock(); + wall.sub = job->sub; + wall.Process(&disp, state, job->seg, front, back); + rendered_lines++; + SetupWall.Unclock(); break; } @@ -197,7 +186,7 @@ void HWDrawInfo::WorkerThread() SetupFlat.Clock(); flat.section = job->sub->section; front = hw_FakeFlat(drawctx, job->sub->render_sector, in_area, false); - flat.ProcessSector(this, state, front); + flat.ProcessSector(&fdisp, state, front); SetupFlat.Unclock(); break; } @@ -361,15 +350,6 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip, FRenderState& state) { jobQueue.AddJob(RenderJob::WallJob, seg->Subsector, seg); } - else if (MeshBSP) - { - SetupWall.Clock(); - HWPortalWall portalwall; - HWWallDispatcher disp(this); - portalwall.Process(&disp, state, seg, currentsector, backsector); - rendered_lines++; - SetupWall.Unclock(); - } else { HWWall wall; @@ -757,20 +737,18 @@ void HWDrawInfo::DoSubsector(subsector_t * sub, FRenderState& state) { srf |= SSRF_PROCESSED; - if (!MeshBSP) + if (multithread) { - if (multithread) - { - jobQueue.AddJob(RenderJob::FlatJob, sub); - } - else - { - HWFlat flat; - flat.section = sub->section; - SetupFlat.Clock(); - flat.ProcessSector(this, state, fakesector); - SetupFlat.Unclock(); - } + jobQueue.AddJob(RenderJob::FlatJob, sub); + } + else + { + HWFlat flat; + flat.section = sub->section; + HWFlatDispatcher disp(this); + SetupFlat.Clock(); + flat.ProcessSector(&disp, state, fakesector); + SetupFlat.Unclock(); } } // mark subsector as processed - but mark for rendering only if it has an actual area. @@ -870,7 +848,6 @@ void HWDrawInfo::RenderBSP(void *node, bool drawpsprites, FRenderState& state) validcount++; // used for processing sidedefs only once by the renderer. - MeshBSP = gl_meshcache; multithread = gl_multithread; if (multithread) { diff --git a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp index 00b49f636..0744c518b 100644 --- a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp +++ b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp @@ -43,7 +43,6 @@ #include "flatvertices.h" #include "hw_vrmodes.h" #include "hw_clipper.h" -#include "hw_meshcache.h" #include "v_draw.h" #include "texturemanager.h" #include "actorinlines.h" @@ -66,7 +65,6 @@ CVAR(Float, gl_mask_sprite_threshold, 0.5f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, gl_coronas, true, CVAR_ARCHIVE); -CVAR(Bool, gl_meshcache, false, 0/*CVAR_ARCHIVE | CVAR_GLOBALCONFIG*/) CVAR(Bool, gl_levelmesh, false, 0/*CVAR_ARCHIVE | CVAR_GLOBALCONFIG*/) sector_t * hw_FakeFlat(sector_t * sec, sector_t * dest, area_t in_area, bool back); @@ -594,21 +592,11 @@ void HWDrawInfo::RenderScene(FRenderState &state) drawlists[GLDL_PLAINWALLS].DrawWalls(this, state, false); drawlists[GLDL_PLAINFLATS].DrawFlats(this, state, false); - if (gl_meshcache && meshcache.Opaque) - { - meshcache.Opaque->Draw(state); - } - // Part 2: masked geometry. This is set up so that only pixels with alpha>gl_mask_threshold will show state.AlphaFunc(Alpha_GEqual, gl_mask_threshold); drawlists[GLDL_MASKEDWALLS].DrawWalls(this, state, false); drawlists[GLDL_MASKEDFLATS].DrawFlats(this, state, false); - if (gl_meshcache && meshcache.Translucent) - { - meshcache.Translucent->Draw(state); - } - // Part 3: masked geometry with polygon offset. This list is empty most of the time so only waste time on it when in use. if (drawlists[GLDL_MASKEDWALLSOFS].Size() > 0) { @@ -617,13 +605,6 @@ void HWDrawInfo::RenderScene(FRenderState &state) state.ClearDepthBias(); } - if (gl_meshcache && meshcache.TranslucentDepthBiased) - { - state.SetDepthBias(-1, -128); - meshcache.TranslucentDepthBiased->Draw(state); - state.ClearDepthBias(); - } - drawlists[GLDL_MODELS].Draw(this, state, false); state.SetRenderStyle(STYLE_Translucent); diff --git a/src/rendering/hwrenderer/scene/hw_drawinfo.h b/src/rendering/hwrenderer/scene/hw_drawinfo.h index 255cffd60..1bf0d70f8 100644 --- a/src/rendering/hwrenderer/scene/hw_drawinfo.h +++ b/src/rendering/hwrenderer/scene/hw_drawinfo.h @@ -181,8 +181,6 @@ struct HWDrawInfo fixed_t viewx, viewy; // since the nodes are still fixed point, keeping the view position also fixed point for node traversal is faster. bool multithread; - bool MeshBSP = false; - bool MeshBuilding = false; TArray QueryResultsBuffer; HWDrawInfo(HWDrawContext* drawctx) : drawctx(drawctx) { for (HWDrawList& list : drawlists) list.drawctx = drawctx; } diff --git a/src/rendering/hwrenderer/scene/hw_drawlist.cpp b/src/rendering/hwrenderer/scene/hw_drawlist.cpp index 8b598a2ff..61f1ebd90 100644 --- a/src/rendering/hwrenderer/scene/hw_drawlist.cpp +++ b/src/rendering/hwrenderer/scene/hw_drawlist.cpp @@ -39,6 +39,7 @@ #include "hw_fakeflat.h" #include "hw_drawcontext.h" #include "hw_walldispatcher.h" +#include "hw_flatdispatcher.h" //========================================================================== // @@ -714,8 +715,9 @@ void HWDrawList::DoDraw(HWDrawInfo *di, FRenderState &state, bool translucent, i case DrawType_FLAT: { HWFlat * f= flats[drawitems[i].index]; + HWFlatDispatcher dis(di); RenderFlat.Clock(); - f->DrawFlat(di, state, translucent); + f->DrawFlat(&dis, state, translucent); RenderFlat.Unclock(); } break; @@ -777,10 +779,11 @@ void HWDrawList::DrawWalls(HWDrawInfo *di, FRenderState &state, bool translucent //========================================================================== void HWDrawList::DrawFlats(HWDrawInfo *di, FRenderState &state, bool translucent) { + HWFlatDispatcher dis(di); RenderFlat.Clock(); for (unsigned i = 0; iDrawFlat(di, state, translucent); + flats[drawitems[i].index]->DrawFlat(&dis, state, translucent); } RenderFlat.Unclock(); } diff --git a/src/rendering/hwrenderer/scene/hw_drawstructs.h b/src/rendering/hwrenderer/scene/hw_drawstructs.h index 3f2769133..351c5dad6 100644 --- a/src/rendering/hwrenderer/scene/hw_drawstructs.h +++ b/src/rendering/hwrenderer/scene/hw_drawstructs.h @@ -33,6 +33,7 @@ struct FSection; enum area_t : int; class HWDrawContext; class DoomLevelMeshSurface; +struct HWFlatDispatcher; enum HWRenderStyle { @@ -347,16 +348,18 @@ public: int dynlightindex; - void CreateSkyboxVertices(FFlatVertex *buffer); - void SetupLights(HWDrawInfo *di, FRenderState& state, FLightNode *head, FDynLightData &lightdata, int portalgroup); + F3DFloor* controlsector; - void PutFlat(HWDrawInfo *di, bool fog = false); - void Process(HWDrawInfo *di, FRenderState& state, sector_t * model, int whichplane, bool notexture); + void CreateSkyboxVertices(FFlatVertex *buffer); + void SetupLights(HWFlatDispatcher *di, FRenderState& state, FLightNode *head, FDynLightData &lightdata, int portalgroup); + + void PutFlat(HWFlatDispatcher *di, bool fog = false); + void Process(HWFlatDispatcher *di, FRenderState& state, sector_t * model, int whichplane, bool notexture); void SetFrom3DFloor(F3DFloor *rover, bool top, bool underside); - void ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * frontsector, int which = 7 /*SSRF_RENDERALL*/); // cannot use constant due to circular dependencies. + void ProcessSector(HWFlatDispatcher *di, FRenderState& state, sector_t * frontsector, int which = 7 /*SSRF_RENDERALL*/); // cannot use constant due to circular dependencies. - void DrawSubsectors(HWDrawInfo *di, FRenderState &state); - void DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent); + void DrawSubsectors(HWFlatDispatcher *di, FRenderState &state); + void DrawFlat(HWFlatDispatcher *di, FRenderState &state, bool translucent); void DrawOtherPlanes(HWDrawInfo *di, FRenderState &state); void DrawFloodPlanes(HWDrawInfo *di, FRenderState &state); diff --git a/src/rendering/hwrenderer/scene/hw_flatdispatcher.h b/src/rendering/hwrenderer/scene/hw_flatdispatcher.h new file mode 100644 index 000000000..1b84d5765 --- /dev/null +++ b/src/rendering/hwrenderer/scene/hw_flatdispatcher.h @@ -0,0 +1,86 @@ +#pragma once + +struct HWFlatMeshHelper +{ + TArray list; + TArray translucent; + TArray translucentborder; + TArray portals; + uint8_t section_renderflags = 0; +}; + +struct HWFlatDispatcher +{ + FLevelLocals* Level; + HWDrawInfo* di; + HWFlatMeshHelper* mh; + ELightMode lightmode; + + HWFlatDispatcher(HWDrawInfo* info) + { + Level = info->Level; + di = info; + mh = nullptr; + lightmode = info->lightmode; + } + + HWFlatDispatcher(FLevelLocals* lev, HWFlatMeshHelper* help, ELightMode lm) + { + Level = lev; + di = nullptr; + mh = help; + lightmode = lm; + } + + bool isFullbrightScene() + { + // The mesh builder cannot know this and must treat everything as not fullbright. + return di && di->isFullbrightScene(); + } + + void AddFlat(HWFlat* flat, bool fog) + { + if (di) + { + di->AddFlat(flat, fog); + } + else + { + if (flat->renderstyle != STYLE_Translucent || flat->alpha < 1.f - FLT_EPSILON || fog || flat->texture == nullptr) + { + // translucent 3D floors go into the regular translucent list, translucent portals go into the translucent border list. + if (flat->renderflags & SSRF_RENDER3DPLANES) + mh->translucent.Push(*flat); + else + mh->translucentborder.Push(*flat); + } + else if (flat->texture->GetTranslucency()) + { + if (flat->stack) + { + mh->translucentborder.Push(*flat); + } + else if ((flat->renderflags & SSRF_RENDER3DPLANES) && !flat->plane.plane.isSlope()) + { + mh->translucent.Push(*flat); + } + else + { + mh->list.Push(*flat); + } + } + else + { + bool masked = flat->texture->isMasked() && ((flat->renderflags & SSRF_RENDER3DPLANES) || flat->stack); + if (masked) + { + mh->list.Push(*flat); // Do we need a different list for this? + } + else + { + mh->list.Push(*flat); + } + } + } + } +}; diff --git a/src/rendering/hwrenderer/scene/hw_flats.cpp b/src/rendering/hwrenderer/scene/hw_flats.cpp index a3e2c1ddd..2f0984290 100644 --- a/src/rendering/hwrenderer/scene/hw_flats.cpp +++ b/src/rendering/hwrenderer/scene/hw_flats.cpp @@ -47,6 +47,7 @@ #include "hw_drawstructs.h" #include "hw_renderstate.h" #include "texturemanager.h" +#include "hw_flatdispatcher.h" #ifdef _DEBUG CVAR(Int, gl_breaksec, -1, 0) @@ -156,8 +157,14 @@ void HWFlat::CreateSkyboxVertices(FFlatVertex *vert) // //========================================================================== -void HWFlat::SetupLights(HWDrawInfo *di, FRenderState& state, FLightNode * node, FDynLightData &lightdata, int portalgroup) +void HWFlat::SetupLights(HWFlatDispatcher *di, FRenderState& state, FLightNode * node, FDynLightData &lightdata, int portalgroup) { + if (!di->di) + { + dynlightindex = -1; + return; + } + Plane p; lightdata.Clear(); @@ -200,7 +207,7 @@ void HWFlat::SetupLights(HWDrawInfo *di, FRenderState& state, FLightNode * node, // //========================================================================== -void HWFlat::DrawSubsectors(HWDrawInfo *di, FRenderState &state) +void HWFlat::DrawSubsectors(HWFlatDispatcher *di, FRenderState &state) { if (di->Level->HasDynamicLights && !di->isFullbrightScene()) { @@ -309,7 +316,7 @@ void HWFlat::DrawFloodPlanes(HWDrawInfo *di, FRenderState &state) // // //========================================================================== -void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent) +void HWFlat::DrawFlat(HWFlatDispatcher *di, FRenderState &state, bool translucent) { #ifdef _DEBUG if (sector->sectornum == gl_breaksec) @@ -323,7 +330,7 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent) state.SetNormal(plane.plane.Normal().X, plane.plane.Normal().Z, plane.plane.Normal().Y); SetColor(state, di->Level, di->lightmode, lightlevel, rel, di->isFullbrightScene(), Colormap, alpha); - SetFog(state, di->Level, di->lightmode, lightlevel, rel, di->isFullbrightScene(), &Colormap, false, di->drawctx->portalState.inskybox); + SetFog(state, di->Level, di->lightmode, lightlevel, rel, di->isFullbrightScene(), &Colormap, false, di->di ? di->di->drawctx->portalState.inskybox : false); state.SetObjectColor(FlatColor | 0xff000000); state.SetAddColor(AddColor | 0xff000000); state.ApplyTextureManipulation(TextureFx); @@ -331,11 +338,13 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent) if (hacktype & SSRF_PLANEHACK) { - DrawOtherPlanes(di, state); + if (di->di) + DrawOtherPlanes(di->di, state); } else if (hacktype & SSRF_FLOODHACK) { - DrawFloodPlanes(di, state); + if (di->di) + DrawFloodPlanes(di->di, state); } else if (!translucent) { @@ -391,7 +400,7 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent) // //========================================================================== -inline void HWFlat::PutFlat(HWDrawInfo *di, bool fog) +inline void HWFlat::PutFlat(HWFlatDispatcher *di, bool fog) { if (di->isFullbrightScene()) { @@ -407,7 +416,7 @@ inline void HWFlat::PutFlat(HWDrawInfo *di, bool fog) // //========================================================================== -void HWFlat::Process(HWDrawInfo *di, FRenderState& state, sector_t * model, int whichplane, bool fog) +void HWFlat::Process(HWFlatDispatcher *di, FRenderState& state, sector_t * model, int whichplane, bool fog) { plane.GetFromSector(model, whichplane); if (whichplane != int(ceiling)) @@ -478,6 +487,8 @@ void HWFlat::SetFrom3DFloor(F3DFloor *rover, bool top, bool underside) alpha = rover->alpha/255.0f; renderstyle = rover->flags&FF_ADDITIVETRANS? STYLE_Add : STYLE_Translucent; iboindex = plane.vindex; + + controlsector = rover; } //========================================================================== @@ -488,7 +499,7 @@ void HWFlat::SetFrom3DFloor(F3DFloor *rover, bool top, bool underside) // //========================================================================== -void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * frontsector, int which) +void HWFlat::ProcessSector(HWFlatDispatcher *di, FRenderState& state, sector_t * frontsector, int which) { lightlist_t * light; FSectorPortal *port; @@ -500,6 +511,8 @@ void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * front } #endif + controlsector = nullptr; + // Get the real sector for this one. sector = &di->Level->sectors[frontsector->sectornum]; extsector_t::xfloor &x = sector->e->XFloor; @@ -507,13 +520,13 @@ void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * front hacktype = (which & (SSRF_PLANEHACK|SSRF_FLOODHACK)); uint8_t sink; - uint8_t &srf = hacktype? sink : di->section_renderflags[di->Level->sections.SectionIndex(section)]; - const auto &vp = di->Viewpoint; + uint8_t &srf = hacktype? sink : (di->di ? di->di->section_renderflags[di->Level->sections.SectionIndex(section)] : di->mh->section_renderflags); + FRenderViewpoint* vp = di->di ? &di->di->Viewpoint : nullptr; // // Lightmaps // - if (level.lightmaps) + if (di->di && level.lightmaps) { for (int i = 0, count = sector->subsectorcount; i < count; ++i) { @@ -524,7 +537,7 @@ void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * front { if (auto surface = sector->subsectors[i]->surface[plane].Size() > j ? sector->subsectors[i]->surface[plane][j] : nullptr) { - di->PushVisibleSurface(surface); + di->di->PushVisibleSurface(surface); } } } @@ -538,7 +551,7 @@ void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * front // // // - if ((which & SSRF_RENDERFLOOR) && (di->MeshBuilding || frontsector->floorplane.ZatPoint(vp.Pos) <= vp.Pos.Z) && (!section || !(section->flags & FSection::DONTRENDERFLOOR))) + if ((which & SSRF_RENDERFLOOR) && (!di->di || frontsector->floorplane.ZatPoint(vp->Pos) <= vp->Pos.Z) && (!section || !(section->flags & FSection::DONTRENDERFLOOR))) { // process the original floor first. @@ -596,7 +609,7 @@ void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * front // // // - if ((which & SSRF_RENDERCEILING) && (di->MeshBuilding || frontsector->ceilingplane.ZatPoint(vp.Pos) >= vp.Pos.Z) && (!section || !(section->flags & FSection::DONTRENDERCEILING))) + if ((which & SSRF_RENDERCEILING) && (!di->di || frontsector->ceilingplane.ZatPoint(vp->Pos) >= vp->Pos.Z) && (!section || !(section->flags & FSection::DONTRENDERCEILING))) { // process the original ceiling first. @@ -681,7 +694,7 @@ void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * front double ff_top = rover->top.plane->ZatPoint(sector->centerspot); if (ff_top < lastceilingheight) { - if (di->MeshBuilding || vp.Pos.Z <= rover->top.plane->ZatPoint(vp.Pos)) + if (!di->di || vp->Pos.Z <= rover->top.plane->ZatPoint(vp->Pos)) { SetFrom3DFloor(rover, true, !!(rover->flags&FF_FOG)); Colormap.FadeColor = frontsector->Colormap.FadeColor; @@ -695,7 +708,7 @@ void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * front double ff_bottom = rover->bottom.plane->ZatPoint(sector->centerspot); if (ff_bottom < lastceilingheight) { - if (di->MeshBuilding || vp.Pos.Z <= rover->bottom.plane->ZatPoint(vp.Pos)) + if (!di->di || vp->Pos.Z <= rover->bottom.plane->ZatPoint(vp->Pos)) { SetFrom3DFloor(rover, false, !(rover->flags&FF_FOG)); Colormap.FadeColor = frontsector->Colormap.FadeColor; @@ -721,7 +734,7 @@ void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * front double ff_bottom = rover->bottom.plane->ZatPoint(sector->centerspot); if (ff_bottom > lastfloorheight || (rover->flags&FF_FIX)) { - if (di->MeshBuilding || vp.Pos.Z >= rover->bottom.plane->ZatPoint(vp.Pos)) + if (!di->di || vp->Pos.Z >= rover->bottom.plane->ZatPoint(vp->Pos)) { SetFrom3DFloor(rover, false, !(rover->flags&FF_FOG)); Colormap.FadeColor = frontsector->Colormap.FadeColor; @@ -742,7 +755,7 @@ void HWFlat::ProcessSector(HWDrawInfo *di, FRenderState& state, sector_t * front double ff_top = rover->top.plane->ZatPoint(sector->centerspot); if (ff_top > lastfloorheight) { - if (di->MeshBuilding || vp.Pos.Z >= rover->top.plane->ZatPoint(vp.Pos)) + if (!di->di || vp->Pos.Z >= rover->top.plane->ZatPoint(vp->Pos)) { SetFrom3DFloor(rover, true, !!(rover->flags&FF_FOG)); Colormap.FadeColor = frontsector->Colormap.FadeColor; diff --git a/src/rendering/hwrenderer/scene/hw_meshcache.cpp b/src/rendering/hwrenderer/scene/hw_meshcache.cpp deleted file mode 100644 index 96c5fe65d..000000000 --- a/src/rendering/hwrenderer/scene/hw_meshcache.cpp +++ /dev/null @@ -1,162 +0,0 @@ - -#include "hw_meshcache.h" -#include "hw_drawinfo.h" -#include "hw_drawstructs.h" -#include "hw_mesh.h" -#include "hw_fakeflat.h" -#include "hw_vertexbuilder.h" -#include "hw_walldispatcher.h" -#include "g_levellocals.h" -#include - -EXTERN_CVAR(Bool, gl_texture) -EXTERN_CVAR(Float, gl_mask_threshold) -EXTERN_CVAR(Bool, gl_meshcache) - -HWMeshCache meshcache; - -void HWMeshCache::Clear() -{ -#if 0 - Sectors.Reset(); -#endif - Opaque.reset(); - Translucent.reset(); - TranslucentDepthBiased.reset(); -} - -void HWMeshCache::Update(HWDrawContext* drawctx, FRenderViewpoint& vp) -{ - if (!gl_meshcache) - return; - - auto level = vp.ViewLevel; - -#if 0 - - unsigned int count = level->sectors.Size(); - Sectors.Resize(count); - - // Look for changes - for (unsigned int i = 0; i < count; i++) - { - auto sector = &level->sectors[i]; - auto cacheitem = &Sectors[i]; - if (cacheitem->Floorplane != sector->floorplane || cacheitem->Ceilingplane != sector->ceilingplane) // Sector height changes - { - cacheitem->NeedsUpdate = true; - for (line_t* line : sector->Lines) - { - sector_t* backsector = (line->frontsector == sector) ? line->backsector : line->frontsector; - if (backsector) - { - Sectors[backsector->Index()].NeedsUpdate = true; - } - } - } - } - - // Update changed sectors - for (unsigned int i = 0; i < count; i++) - { - auto sector = &level->sectors[i]; - auto cacheitem = &Sectors[i]; - if (cacheitem->NeedsUpdate) - { - cacheitem->NeedsUpdate = false; - cacheitem->Sector = sector; - cacheitem->Floorplane = sector->floorplane; - cacheitem->Ceilingplane = sector->ceilingplane; - cacheitem->Update(vp); - } - } - -#endif - - if (!Opaque) - { - HWDrawInfo* di = HWDrawInfo::StartDrawInfo(drawctx, vp.ViewLevel, nullptr, vp, nullptr); - di->MeshBuilding = true; - - MeshBuilder state; - state.SetShadowData(sector_vertices, sector_indexes); - - // Add to the draw lists - - unsigned int count = level->sectors.Size(); - for (unsigned int i = 0; i < count; i++) - { - auto sector = &level->sectors[i]; - - // CheckUpdate(state, sector); - std::unordered_set seenSections; - for (int i = 0, count = sector->subsectorcount; i < count; i++) - { - subsector_t* subsector = sector->subsectors[i]; - if (seenSections.find(subsector->section) == seenSections.end()) - { - seenSections.insert(subsector->section); - - HWFlat flat; - flat.section = subsector->section; - sector_t* front = hw_FakeFlat(di->drawctx, subsector->render_sector, area_default, false); - flat.ProcessSector(di, state, front); - } - } - - for (line_t* line : sector->Lines) - { - side_t* side = (line->sidedef[0]->sector == sector) ? line->sidedef[0] : line->sidedef[1]; - - HWWall wall; - HWWallDispatcher disp(di); - wall.sub = sector->subsectors[0]; - wall.Process(&disp, state, side->segs[0], sector, (line->sidedef[0]->sector == sector) ? line->backsector : line->frontsector); - } - } - - // Convert draw lists to meshes - - state.SetDepthMask(true); - state.EnableFog(true); - state.SetRenderStyle(STYLE_Source); - - di->drawlists[GLDL_PLAINWALLS].SortWalls(); - di->drawlists[GLDL_PLAINFLATS].SortFlats(); - di->drawlists[GLDL_MASKEDWALLS].SortWalls(); - di->drawlists[GLDL_MASKEDFLATS].SortFlats(); - di->drawlists[GLDL_MASKEDWALLSOFS].SortWalls(); - - // Part 1: solid geometry. This is set up so that there are no transparent parts - state.SetDepthFunc(DF_Less); - state.AlphaFunc(Alpha_GEqual, 0.f); - state.ClearDepthBias(); - state.EnableTexture(gl_texture); - state.EnableBrightmap(true); - di->drawlists[GLDL_PLAINWALLS].DrawWalls(di, state, false); - di->drawlists[GLDL_PLAINFLATS].DrawFlats(di, state, false); - Opaque = state.Create(); - - // Part 2: masked geometry. This is set up so that only pixels with alpha>gl_mask_threshold will show - state.AlphaFunc(Alpha_GEqual, gl_mask_threshold); - di->drawlists[GLDL_MASKEDWALLS].DrawWalls(di, state, false); - di->drawlists[GLDL_MASKEDFLATS].DrawFlats(di, state, false); - Translucent = state.Create(); - - // Part 3: masked geometry with polygon offset. This list is empty most of the time so only waste time on it when in use. - if (di->drawlists[GLDL_MASKEDWALLSOFS].Size() > 0) - { - state.SetDepthBias(-1, -128); - di->drawlists[GLDL_MASKEDWALLSOFS].DrawWalls(di, state, false); - state.ClearDepthBias(); - TranslucentDepthBiased = state.Create(); - } - else - { - TranslucentDepthBiased.reset(); - } - - di->MeshBuilding = false; - di->EndDrawInfo(); - } -} diff --git a/src/rendering/hwrenderer/scene/hw_meshcache.h b/src/rendering/hwrenderer/scene/hw_meshcache.h deleted file mode 100644 index 03dfcafa0..000000000 --- a/src/rendering/hwrenderer/scene/hw_meshcache.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include "hw_mesh.h" -#include "r_defs.h" - -struct FRenderViewpoint; -class HWDrawContext; - -#if 0 -class HWCachedSector -{ -public: - bool NeedsUpdate = true; - - sector_t* Sector = nullptr; - secplane_t Floorplane; - secplane_t Ceilingplane; -}; -#endif - -class HWMeshCache -{ -public: - void Clear(); - void Update(HWDrawContext* drawctx, FRenderViewpoint& vp); - -#if 0 - TArray Sectors; -#endif - - std::unique_ptr Opaque; - std::unique_ptr Translucent; - std::unique_ptr TranslucentDepthBiased; -}; - -extern HWMeshCache meshcache; diff --git a/src/rendering/hwrenderer/scene/hw_meshportal.cpp b/src/rendering/hwrenderer/scene/hw_meshportal.cpp deleted file mode 100644 index bedf25700..000000000 --- a/src/rendering/hwrenderer/scene/hw_meshportal.cpp +++ /dev/null @@ -1,64 +0,0 @@ - -#include "hw_meshportal.h" -#include "p_local.h" -#include "p_lnspec.h" -#include "a_dynlight.h" -#include "a_sharedglobal.h" -#include "r_defs.h" -#include "r_sky.h" -#include "r_utility.h" -#include "p_maputl.h" -#include "doomdata.h" -#include "g_levellocals.h" -#include "actorinlines.h" -#include "texturemanager.h" -#include "hw_dynlightdata.h" -#include "hw_material.h" -#include "hw_cvars.h" -#include "hw_clock.h" -#include "hw_lighting.h" -#include "hw_drawcontext.h" -#include "hw_drawinfo.h" -#include "hw_renderstate.h" - -void HWPortalWall::Process(HWWallDispatcher* di, FRenderState& state, seg_t* seg, sector_t* frontsector, sector_t* backsector) -{ - // The portal code wants a HWWall struct. - - if (IsPortal(di, state, seg, frontsector, backsector)) - { - HWWall wall; - wall.sub = seg->Subsector; - wall.Process(di, state, seg, frontsector, backsector); - } -} - -bool HWPortalWall::IsPortal(HWWallDispatcher* di, FRenderState& state, seg_t* seg, sector_t* frontsector, sector_t* backsector) -{ - // Note: This is incomplete. It assumes a completely valid map. Good luck adding the full range of checks! - - if (seg->linedef->special == Line_Mirror && gl_mirrors) - return true; - - if (seg->linedef->special == Line_Horizon) - return true; - - if (seg->linedef->isVisualPortal() && seg->sidedef == seg->linedef->sidedef[0]) - return true; - - if (seg->linedef->GetTransferredPortal()) - return true; - - for (int plane : { sector_t::floor, sector_t::ceiling }) - { - FSectorPortal* sportal = frontsector->ValidatePortal(plane); - if (frontsector->ValidatePortal(plane) && !(sportal->mFlags & PORTSF_INSKYBOX)) // no recursions - return true; - if (frontsector->GetTexture(plane) == skyflatnum) - return true; - if (frontsector->GetReflect(plane) > 0) - return true; - } - - return false; -} diff --git a/src/rendering/hwrenderer/scene/hw_meshportal.h b/src/rendering/hwrenderer/scene/hw_meshportal.h deleted file mode 100644 index 533f847d6..000000000 --- a/src/rendering/hwrenderer/scene/hw_meshportal.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include "hw_drawstructs.h" - -class HWPortalWall -{ -public: - static void Process(HWWallDispatcher* di, FRenderState& state, seg_t* seg, sector_t* frontsector, sector_t* backsector); - -private: - static bool IsPortal(HWWallDispatcher* di, FRenderState& state, seg_t* seg, sector_t* frontsector, sector_t* backsector); -}; diff --git a/src/rendering/hwrenderer/scene/hw_renderhacks.cpp b/src/rendering/hwrenderer/scene/hw_renderhacks.cpp index ab71d355b..0df035da4 100644 --- a/src/rendering/hwrenderer/scene/hw_renderhacks.cpp +++ b/src/rendering/hwrenderer/scene/hw_renderhacks.cpp @@ -42,6 +42,7 @@ #include "hwrenderer/scene/hw_portal.h" #include "hw_fakeflat.h" #include "hw_walldispatcher.h" +#include "hw_flatdispatcher.h" //========================================================================== // @@ -51,6 +52,7 @@ void HWDrawInfo::DispatchRenderHacks(FRenderState& state) { + HWFlatDispatcher dis(this); TMap::Pair *pair; TMap::Pair *fpair; TMap::Iterator ofi(otherFloorPlanes); @@ -59,28 +61,28 @@ void HWDrawInfo::DispatchRenderHacks(FRenderState& state) while (ofi.NextPair(pair)) { auto sec = hw_FakeFlat(drawctx, &Level->sectors[pair->Key], in_area, false); - glflat.ProcessSector(this, state, sec, SSRF_RENDERFLOOR | SSRF_PLANEHACK); + glflat.ProcessSector(&dis, state, sec, SSRF_RENDERFLOOR | SSRF_PLANEHACK); } TMap::Iterator oci(otherCeilingPlanes); while (oci.NextPair(pair)) { auto sec = hw_FakeFlat(drawctx, &Level->sectors[pair->Key], in_area, false); - glflat.ProcessSector(this, state, sec, SSRF_RENDERCEILING | SSRF_PLANEHACK); + glflat.ProcessSector(&dis, state, sec, SSRF_RENDERCEILING | SSRF_PLANEHACK); } TMap::Iterator ffi(floodFloorSegs); while (ffi.NextPair(fpair)) { auto sec = hw_FakeFlat(drawctx, &Level->sectors[fpair->Key], in_area, false); - glflat.ProcessSector(this, state, sec, SSRF_RENDERFLOOR | SSRF_FLOODHACK); + glflat.ProcessSector(&dis, state, sec, SSRF_RENDERFLOOR | SSRF_FLOODHACK); } TMap::Iterator fci(floodCeilingSegs); while (fci.NextPair(fpair)) { auto sec = hw_FakeFlat(drawctx, &Level->sectors[fpair->Key], in_area, false); - glflat.ProcessSector(this, state, sec, SSRF_RENDERCEILING | SSRF_FLOODHACK); + glflat.ProcessSector(&dis, state, sec, SSRF_RENDERCEILING | SSRF_FLOODHACK); } } diff --git a/src/rendering/hwrenderer/scene/hw_walls.cpp b/src/rendering/hwrenderer/scene/hw_walls.cpp index a5ac585b1..7189226fd 100644 --- a/src/rendering/hwrenderer/scene/hw_walls.cpp +++ b/src/rendering/hwrenderer/scene/hw_walls.cpp @@ -45,8 +45,6 @@ #include "hw_skydome.h" #include "hw_walldispatcher.h" -EXTERN_CVAR(Bool, gl_meshcache); - void SetGlowPlanes(FRenderState &state, const secplane_t& top, const secplane_t& bottom) { auto& tn = top.Normal(); @@ -491,9 +489,6 @@ const char HWWall::passflag[] = { //========================================================================== void HWWall::PutWall(HWWallDispatcher *di, FRenderState& state, bool translucent) { - if (gl_meshcache && di->di && !di->di->MeshBuilding) // Don't draw walls when only collecting portals - return; - if (texture && texture->GetTranslucency() && passflag[type] == 2) { translucent = true; @@ -559,9 +554,6 @@ void HWWall::PutWall(HWWallDispatcher *di, FRenderState& state, bool translucent void HWWall::PutPortal(HWWallDispatcher *di, FRenderState& state, int ptype, int plane) { - if (di->di && di->di->MeshBuilding) - return; - HWPortal * portal = nullptr; auto ddi = di->di;