diff --git a/src/maploader/maploader.cpp b/src/maploader/maploader.cpp index c603f18dcc..7b0c241f63 100644 --- a/src/maploader/maploader.cpp +++ b/src/maploader/maploader.cpp @@ -3283,7 +3283,7 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position) P_Recalculate3DFloors(&sec); } - SWRenderer->SetColormap(); //The SW renderer needs to do some special setup for the level's default colormap. + SWRenderer->SetColormap(Level); //The SW renderer needs to do some special setup for the level's default colormap. InitPortalGroups(Level); P_InitHealthGroups(); diff --git a/src/polyrenderer/poly_renderer.cpp b/src/polyrenderer/poly_renderer.cpp index 0556cbe49d..8cc8aa6166 100644 --- a/src/polyrenderer/poly_renderer.cpp +++ b/src/polyrenderer/poly_renderer.cpp @@ -34,6 +34,7 @@ #include "st_stuff.h" #include "g_levellocals.h" #include "p_effect.h" +#include "actorinlines.h" #include "polyrenderer/scene/poly_light.h" #include "swrenderer/scene/r_scene.h" #include "swrenderer/drawers/r_draw_rgba.h" @@ -131,8 +132,9 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines) NetUpdate(); DontMapLines = dontmaplines; - + R_SetupFrame(Viewpoint, Viewwindow, actor); + Level = Viewpoint.ViewLevel; P_FindParticleSubsectors(); PO_LinkToSubsectors(&level); @@ -222,7 +224,7 @@ PolyPortalViewpoint PolyRenderer::SetupPerspectiveMatrix(bool mirror) // We have to scale the pitch to account for the pixel stretching, because the playsim doesn't know about this and treats it as 1:1. double radPitch = Viewpoint.Angles.Pitch.Normalized180().Radians(); double angx = cos(radPitch); - double angy = sin(radPitch) * level.info->pixelstretch; + double angy = sin(radPitch) * PolyRenderer::Instance()->Level->info->pixelstretch; double alen = sqrt(angx*angx + angy*angy); float adjustedPitch = (float)asin(angy / alen); float adjustedViewAngle = (float)(Viewpoint.Angles.Yaw - 90).Radians(); @@ -238,7 +240,7 @@ PolyPortalViewpoint PolyRenderer::SetupPerspectiveMatrix(bool mirror) Mat4f::Rotate((float)Viewpoint.Angles.Roll.Radians(), 0.0f, 0.0f, 1.0f) * Mat4f::Rotate(adjustedPitch, 1.0f, 0.0f, 0.0f) * Mat4f::Rotate(adjustedViewAngle, 0.0f, -1.0f, 0.0f) * - Mat4f::Scale(1.0f, level.info->pixelstretch, 1.0f) * + Mat4f::Scale(1.0f, PolyRenderer::Instance()->Level->info->pixelstretch, 1.0f) * Mat4f::SwapYZ() * Mat4f::Translate((float)-Viewpoint.Pos.X, (float)-Viewpoint.Pos.Y, (float)-Viewpoint.Pos.Z); diff --git a/src/polyrenderer/poly_renderer.h b/src/polyrenderer/poly_renderer.h index 34b880e1cb..949196af9c 100644 --- a/src/polyrenderer/poly_renderer.h +++ b/src/polyrenderer/poly_renderer.h @@ -68,6 +68,7 @@ public: FRenderViewpoint Viewpoint; PolyLightVisibility Light; RenderPolyScene Scene; + FLevelLocals *Level; private: void RenderActorView(AActor *actor, bool dontmaplines); diff --git a/src/polyrenderer/scene/poly_cull.cpp b/src/polyrenderer/scene/poly_cull.cpp index 6668e2f2bb..1428a5931f 100644 --- a/src/polyrenderer/scene/poly_cull.cpp +++ b/src/polyrenderer/scene/poly_cull.cpp @@ -32,18 +32,18 @@ void PolyCull::CullScene(sector_t *portalSector, line_t *portalLine) { for (uint32_t sub : PvsSubsectors) SubsectorDepths[sub] = 0xffffffff; - SubsectorDepths.resize(level.subsectors.Size(), 0xffffffff); + SubsectorDepths.resize(PolyRenderer::Instance()->Level->subsectors.Size(), 0xffffffff); for (uint32_t sector : SeenSectors) SectorSeen[sector] = false; - SectorSeen.resize(level.sectors.Size()); + SectorSeen.resize(PolyRenderer::Instance()->Level->sectors.Size()); PvsSubsectors.clear(); SeenSectors.clear(); NextPvsLineStart = 0; PvsLineStart.clear(); - PvsLineVisible.resize(level.segs.Size()); + PvsLineVisible.resize(PolyRenderer::Instance()->Level->segs.Size()); PortalSector = portalSector; PortalLine = portalLine; @@ -78,10 +78,10 @@ void PolyCull::CullScene(sector_t *portalSector, line_t *portalLine) FirstSkyHeight = true; MaxCeilingHeight = 0.0; MinFloorHeight = 0.0; - if (level.nodes.Size() == 0) - CullSubsector(&level.subsectors[0]); + if (PolyRenderer::Instance()->Level->nodes.Size() == 0) + CullSubsector(&PolyRenderer::Instance()->Level->subsectors[0]); else - CullNode(level.HeadNode()); + CullNode(PolyRenderer::Instance()->Level->HeadNode()); } void PolyCull::CullNode(void *node) diff --git a/src/polyrenderer/scene/poly_light.cpp b/src/polyrenderer/scene/poly_light.cpp index e0854fdcec..e7ebf4c1e0 100644 --- a/src/polyrenderer/scene/poly_light.cpp +++ b/src/polyrenderer/scene/poly_light.cpp @@ -34,7 +34,7 @@ void PolyLightVisibility::SetVisibility(FViewWindow &viewwindow, float vis) fixed_t PolyLightVisibility::LightLevelToShade(int lightlevel, bool foggy) { - bool nolightfade = !foggy && ((level.flags3 & LEVEL3_NOLIGHTFADE)); + bool nolightfade = !foggy && ((PolyRenderer::Instance()->Level->flags3 & LEVEL3_NOLIGHTFADE)); if (nolightfade) { return (MAX(255 - lightlevel, 0) * NUMCOLORMAPS) << (FRACBITS - 8); diff --git a/src/polyrenderer/scene/poly_particle.cpp b/src/polyrenderer/scene/poly_particle.cpp index 73617ebce1..d7db9be84e 100644 --- a/src/polyrenderer/scene/poly_particle.cpp +++ b/src/polyrenderer/scene/poly_particle.cpp @@ -35,7 +35,7 @@ EXTERN_CVAR(Int, gl_particles_style) void RenderPolyParticle::Render(PolyRenderThread *thread, particle_t *particle, subsector_t *sub, uint32_t stencilValue) { double timefrac = r_viewpoint.TicFrac; - if (paused || bglobal.freeze || (level.flags2 & LEVEL2_FROZEN)) + if (paused || bglobal.freeze || (PolyRenderer::Instance()->Level->flags2 & LEVEL2_FROZEN)) timefrac = 0.; DVector3 pos = particle->Pos + (particle->Vel * timefrac); double psize = particle->size / 8.0; diff --git a/src/polyrenderer/scene/poly_plane.cpp b/src/polyrenderer/scene/poly_plane.cpp index 27a3f2efa1..1a1ceb0e0c 100644 --- a/src/polyrenderer/scene/poly_plane.cpp +++ b/src/polyrenderer/scene/poly_plane.cpp @@ -246,7 +246,7 @@ void RenderPolyPlane::RenderSkyWalls(PolyRenderThread *thread, PolyDrawArgs &arg void RenderPolyPlane::SetLightLevel(PolyRenderThread *thread, PolyDrawArgs &args, const PolyTransferHeights &fakeflat, bool ceiling) { - bool foggy = level.fadeto || fakeflat.FrontSector->Colormap.FadeColor || (level.flags & LEVEL_HASFADETABLE); + bool foggy = PolyRenderer::Instance()->Level->fadeto || fakeflat.FrontSector->Colormap.FadeColor || (PolyRenderer::Instance()->Level->flags & LEVEL_HASFADETABLE); int lightlevel = ceiling ? fakeflat.CeilingLightLevel : fakeflat.FloorLightLevel; int actualextralight = foggy ? 0 : PolyRenderer::Instance()->Viewpoint.extralight << 4; diff --git a/src/polyrenderer/scene/poly_playersprite.cpp b/src/polyrenderer/scene/poly_playersprite.cpp index 93cfca926c..6009535082 100644 --- a/src/polyrenderer/scene/poly_playersprite.cpp +++ b/src/polyrenderer/scene/poly_playersprite.cpp @@ -106,7 +106,7 @@ void RenderPolyPlayerSprites::Render(PolyRenderThread *thread) } // [RH] set foggy flag - bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); + bool foggy = (PolyRenderer::Instance()->Level->fadeto || basecolormap->Fade || (PolyRenderer::Instance()->Level->flags & LEVEL_HASFADETABLE)); // get light level lightnum = ((floorlight + ceilinglight) >> 1) + (foggy ? 0 : viewpoint.extralight << 4); @@ -458,7 +458,7 @@ void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *p fixed_t RenderPolyPlayerSprites::LightLevelToShade(int lightlevel, bool foggy) { - bool nolightfade = !foggy && ((level.flags3 & LEVEL3_NOLIGHTFADE)); + bool nolightfade = !foggy && ((PolyRenderer::Instance()->Level->flags3 & LEVEL3_NOLIGHTFADE)); if (nolightfade) { return (MAX(255 - lightlevel, 0) * NUMCOLORMAPS) << (FRACBITS - 8); diff --git a/src/polyrenderer/scene/poly_portal.cpp b/src/polyrenderer/scene/poly_portal.cpp index a4a7ec467a..ea9b2b949d 100644 --- a/src/polyrenderer/scene/poly_portal.cpp +++ b/src/polyrenderer/scene/poly_portal.cpp @@ -91,13 +91,13 @@ void PolyDrawSectorPortal::SaveGlobals() viewpoint.SetViewAngle(viewwindow); Portal->mFlags |= PORTSF_INSKYBOX; - if (Portal->mPartner > 0) level.sectorPortals[Portal->mPartner].mFlags |= PORTSF_INSKYBOX; + if (Portal->mPartner > 0) PolyRenderer::Instance()->Level->sectorPortals[Portal->mPartner].mFlags |= PORTSF_INSKYBOX; } void PolyDrawSectorPortal::RestoreGlobals() { Portal->mFlags &= ~PORTSF_INSKYBOX; - if (Portal->mPartner > 0) level.sectorPortals[Portal->mPartner].mFlags &= ~PORTSF_INSKYBOX; + if (Portal->mPartner > 0) PolyRenderer::Instance()->Level->sectorPortals[Portal->mPartner].mFlags &= ~PORTSF_INSKYBOX; auto &viewpoint = PolyRenderer::Instance()->Viewpoint; const auto &viewwindow = PolyRenderer::Instance()->Viewwindow; diff --git a/src/polyrenderer/scene/poly_scene.cpp b/src/polyrenderer/scene/poly_scene.cpp index f92c73762e..a351f57c7e 100644 --- a/src/polyrenderer/scene/poly_scene.cpp +++ b/src/polyrenderer/scene/poly_scene.cpp @@ -70,7 +70,7 @@ void RenderPolyScene::Render(PolyPortalViewpoint *viewpoint) const auto &rviewpoint = PolyRenderer::Instance()->Viewpoint; for (uint32_t sectorIndex : Cull.SeenSectors) { - sector_t *sector = &level.sectors[sectorIndex]; + sector_t *sector = &PolyRenderer::Instance()->Level->sectors[sectorIndex]; for (AActor *thing = sector->thinglist; thing != nullptr; thing = thing->snext) { if (!RenderPolySprite::IsThingCulled(thing)) @@ -132,7 +132,7 @@ void RenderPolyScene::RenderSectors() int end = thread->End; for (int i = start; i < end; i++) { - RenderSubsector(thread, &level.subsectors[subsectors[i]], i); + RenderSubsector(thread, &PolyRenderer::Instance()->Level->subsectors[subsectors[i]], i); } }, [&](PolyRenderThread *thread) { @@ -254,15 +254,15 @@ int RenderPolyScene::PointOnSide(const DVector2 &pos, const node_t *node) void RenderPolyScene::AddSprite(PolyRenderThread *thread, AActor *thing, double sortDistance, const DVector2 &left, const DVector2 &right) { - if (level.nodes.Size() == 0) + if (PolyRenderer::Instance()->Level->nodes.Size() == 0) { - subsector_t *sub = &level.subsectors[0]; + subsector_t *sub = &PolyRenderer::Instance()->Level->subsectors[0]; if (Cull.SubsectorDepths[sub->Index()] != 0xffffffff) thread->TranslucentObjects.push_back(thread->FrameMemory->NewObject(thing, sub, Cull.SubsectorDepths[sub->Index()], sortDistance, 0.0f, 1.0f, CurrentViewpoint->StencilValue)); } else { - AddSprite(thread, thing, sortDistance, left, right, 0.0, 1.0, level.HeadNode()); + AddSprite(thread, thing, sortDistance, left, right, 0.0, 1.0, PolyRenderer::Instance()->Level->HeadNode()); } } @@ -303,15 +303,15 @@ void RenderPolyScene::AddSprite(PolyRenderThread *thread, AActor *thing, double void RenderPolyScene::AddModel(PolyRenderThread *thread, AActor *thing, double sortDistance, DVector2 pos) { - if (level.nodes.Size() == 0) + if (PolyRenderer::Instance()->Level->nodes.Size() == 0) { - subsector_t *sub = &level.subsectors[0]; + subsector_t *sub = &PolyRenderer::Instance()->Level->subsectors[0]; if (Cull.SubsectorDepths[sub->Index()] != 0xffffffff) thread->TranslucentObjects.push_back(thread->FrameMemory->NewObject(thing, sub, Cull.SubsectorDepths[sub->Index()], sortDistance, 0.0f, 1.0f, CurrentViewpoint->StencilValue)); } else { - void *node = level.HeadNode(); + void *node = PolyRenderer::Instance()->Level->HeadNode(); while (!((size_t)node & 1)) // Keep going until found a subsector { @@ -444,7 +444,7 @@ PolyTransferHeights::PolyTransferHeights(subsector_t *sub) : Subsector(sub) // If player's view height is underneath fake floor, lower the // drawn ceiling to be just under the floor height, and replace - // the drawn floor and ceiling textures, and light level, with + // the drawn floor and ceiling textures, and light PolyRenderer::Instance()->Level->, with // the control sector's. // // Similar for ceiling, only reflected. diff --git a/src/polyrenderer/scene/poly_sky.cpp b/src/polyrenderer/scene/poly_sky.cpp index 4e3e2fbfd8..b279746c0d 100644 --- a/src/polyrenderer/scene/poly_sky.cpp +++ b/src/polyrenderer/scene/poly_sky.cpp @@ -229,7 +229,7 @@ Mat4f PolySkyDome::GLSkyMath() float xscale = texw < 1024.f ? floor(1024.f / float(texw)) : 1.f; float yscale = 1.f; - if (texh <= 128 && (level.flags & LEVEL_FORCETILEDSKY)) + if (texh <= 128 && (PolyRenderer::Instance()->Level->flags & LEVEL_FORCETILEDSKY)) { modelMatrix = modelMatrix * Mat4f::Translate(0.f, 0.f, (-40 + tex->GetSkyOffset() + skyoffset)*skyoffsetfactor); modelMatrix = modelMatrix * Mat4f::Scale(1.f, 1.f, 1.2f * 1.17f); @@ -307,7 +307,7 @@ void PolySkySetup::Update() } else if (skyheight > 200) { - skytexturemid = (200 - skyheight) * sskytex1->GetScale().Y + ((r_skymode == 2 && !(level.flags & LEVEL_FORCETILEDSKY)) ? skytex1->GetSkyOffset() : 0); + skytexturemid = (200 - skyheight) * sskytex1->GetScale().Y + ((r_skymode == 2 && !(PolyRenderer::Instance()->Level->flags & LEVEL_FORCETILEDSKY)) ? skytex1->GetSkyOffset() : 0); } if (viewwidth != 0 && viewheight != 0) @@ -337,7 +337,7 @@ void PolySkySetup::Update() FTextureID sky1tex, sky2tex; double frontdpos = 0, backdpos = 0; - if ((level.flags & LEVEL_SWAPSKIES) && !(level.flags & LEVEL_DOUBLESKY)) + if ((PolyRenderer::Instance()->Level->flags & LEVEL_SWAPSKIES) && !(PolyRenderer::Instance()->Level->flags & LEVEL_DOUBLESKY)) { sky1tex = sky2texture; } @@ -355,7 +355,7 @@ void PolySkySetup::Update() { // use sky1 sky1: frontskytex = GetSWTex(sky1tex); - if (level.flags & LEVEL_DOUBLESKY) + if (PolyRenderer::Instance()->Level->flags & LEVEL_DOUBLESKY) backskytex = GetSWTex(sky2tex); else backskytex = nullptr; @@ -376,7 +376,7 @@ void PolySkySetup::Update() else { // MBF's linedef-controlled skies // Sky Linedef - const line_t *l = &level.lines[(sectorSky & ~PL_SKYFLAT) - 1]; + const line_t *l = &PolyRenderer::Instance()->Level->lines[(sectorSky & ~PL_SKYFLAT) - 1]; // Sky transferred from first sidedef const side_t *s = l->sidedef[0]; @@ -384,7 +384,7 @@ void PolySkySetup::Update() // Texture comes from upper texture of reference sidedef // [RH] If swapping skies, then use the lower sidedef - if (level.flags & LEVEL_SWAPSKIES && s->GetTexture(side_t::bottom).isValid()) + if (PolyRenderer::Instance()->Level->flags & LEVEL_SWAPSKIES && s->GetTexture(side_t::bottom).isValid()) { pos = side_t::bottom; } diff --git a/src/r_renderer.h b/src/r_renderer.h index 46fd9a4303..126d7a2eef 100644 --- a/src/r_renderer.h +++ b/src/r_renderer.h @@ -14,6 +14,7 @@ struct sector_t; class FCanvasTexture; class FileWriter; class DCanvas; +struct FLevelLocals; struct FRenderer { @@ -32,7 +33,7 @@ struct FRenderer virtual void DrawRemainingPlayerSprites() = 0; // set up the colormap for a newly loaded level. - virtual void SetColormap() = 0; + virtual void SetColormap(FLevelLocals *) = 0; virtual void SetClearColor(int color) = 0; diff --git a/src/swrenderer/drawers/r_draw_pal.cpp b/src/swrenderer/drawers/r_draw_pal.cpp index 5be7ba5cc7..e6280e1973 100644 --- a/src/swrenderer/drawers/r_draw_pal.cpp +++ b/src/swrenderer/drawers/r_draw_pal.cpp @@ -69,7 +69,7 @@ EXTERN_CVAR(Int, gl_particles_style) table seemed to be quite ultimate. The computation of the RGB for each pixel is accelerated by using two - 1k tables for each translucency level. + 1k tables for each translucency level The xth element of one of these tables contains the r, g and b values for the colour x, weighted for the current translucency level (for example, the weighted rgb values for background colour at 75% translucency are 1/4 diff --git a/src/swrenderer/line/r_wallsetup.cpp b/src/swrenderer/line/r_wallsetup.cpp index 87c491b673..168e8425f4 100644 --- a/src/swrenderer/line/r_wallsetup.cpp +++ b/src/swrenderer/line/r_wallsetup.cpp @@ -266,7 +266,7 @@ namespace swrenderer if (!lit) { basecolormap = GetColorTable(frontsector->Colormap, frontsector->SpecialColors[sector_t::walltop]); - foggy = level.fadeto || frontsector->Colormap.FadeColor || (level.flags & LEVEL_HASFADETABLE); + foggy = frontsector->Level->fadeto || frontsector->Colormap.FadeColor || (frontsector->Level->flags & LEVEL_HASFADETABLE); if (!(lineseg->sidedef->Flags & WALLF_POLYOBJ)) lightlevel = lineseg->sidedef->GetLightLevel(foggy, frontsector->lightlevel); @@ -276,7 +276,7 @@ namespace swrenderer else { basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); - foggy = level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE); + foggy = frontsector->Level->fadeto || basecolormap->Fade || (frontsector->Level->flags & LEVEL_HASFADETABLE); lightlevel = lineseg->sidedef->GetLightLevel(foggy, *lit->p_lightlevel, lit->lightsource != nullptr); } } diff --git a/src/swrenderer/plane/r_flatplane.cpp b/src/swrenderer/plane/r_flatplane.cpp index 11f8fef865..b75d5c5452 100644 --- a/src/swrenderer/plane/r_flatplane.cpp +++ b/src/swrenderer/plane/r_flatplane.cpp @@ -135,7 +135,8 @@ namespace swrenderer planeheight = fabs(pl->height.Zat0() - Thread->Viewport->viewpoint.Pos.Z); // [RH] set foggy flag - foggy = (level.fadeto || colormap->Fade || (level.flags & LEVEL_HASFADETABLE)); + auto Level = Thread->Viewport->Level(); + foggy = (Level->fadeto || colormap->Fade || (Level->flags & LEVEL_HASFADETABLE)); lightlevel = pl->lightlevel; CameraLight *cameraLight = CameraLight::Instance(); diff --git a/src/swrenderer/plane/r_skyplane.cpp b/src/swrenderer/plane/r_skyplane.cpp index 24653860d8..d441f28e48 100644 --- a/src/swrenderer/plane/r_skyplane.cpp +++ b/src/swrenderer/plane/r_skyplane.cpp @@ -70,6 +70,7 @@ namespace swrenderer RenderSkyPlane::RenderSkyPlane(RenderThread *thread) { Thread = thread; + auto Level = Thread->Viewport->Level(); auto skytex1 = TexMan.GetPalettedTexture(sky1texture, true); auto skytex2 = TexMan.GetPalettedTexture(sky2texture, true); @@ -87,7 +88,7 @@ namespace swrenderer } else if (skyheight > 200) { - skytexturemid = (200 - skyheight) * sskytex1->GetScale().Y + ((r_skymode == 2 && !(level.flags & LEVEL_FORCETILEDSKY)) ? skytex1->GetSkyOffset() : 0); + skytexturemid = (200 - skyheight) * sskytex1->GetScale().Y + ((r_skymode == 2 && !(Level->flags & LEVEL_FORCETILEDSKY)) ? skytex1->GetSkyOffset() : 0); } if (viewwidth != 0 && viewheight != 0) @@ -118,8 +119,9 @@ namespace swrenderer { FTextureID sky1tex, sky2tex; double frontdpos = 0, backdpos = 0; + auto Level = Thread->Viewport->Level(); - if ((level.flags & LEVEL_SWAPSKIES) && !(level.flags & LEVEL_DOUBLESKY)) + if ((Level->flags & LEVEL_SWAPSKIES) && !(Level->flags & LEVEL_DOUBLESKY)) { sky1tex = sky2texture; } @@ -137,7 +139,7 @@ namespace swrenderer { // use sky1 sky1: frontskytex = GetSWTex(sky1tex); - if (level.flags & LEVEL_DOUBLESKY) + if (Level->flags & LEVEL_DOUBLESKY) backskytex = GetSWTex(sky2tex); else backskytex = NULL; @@ -158,7 +160,7 @@ namespace swrenderer else { // MBF's linedef-controlled skies // Sky Linedef - const line_t *l = &level.lines[(pl->sky & ~PL_SKYFLAT) - 1]; + const line_t *l = &Level->lines[(pl->sky & ~PL_SKYFLAT) - 1]; // Sky transferred from first sidedef const side_t *s = l->sidedef[0]; @@ -166,7 +168,7 @@ namespace swrenderer // Texture comes from upper texture of reference sidedef // [RH] If swapping skies, then use the lower sidedef - if (level.flags & LEVEL_SWAPSKIES && s->GetTexture(side_t::bottom).isValid()) + if (Level->flags & LEVEL_SWAPSKIES && s->GetTexture(side_t::bottom).isValid()) { pos = side_t::bottom; } @@ -224,6 +226,7 @@ namespace swrenderer { RenderPortal *renderportal = Thread->Portal.get(); auto viewport = Thread->Viewport.get(); + auto Level = viewport->Level(); double uv_stepd = skyiscale * yrepeat; double v = (texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / frontskytex->GetHeight(); @@ -256,7 +259,7 @@ namespace swrenderer drawerargs.SetTextureVPos(uv_pos); drawerargs.SetDest(viewport, start_x, y1); drawerargs.SetCount(y2 - y1); - drawerargs.SetFadeSky(r_skymode == 2 && !(level.flags & LEVEL_FORCETILEDSKY)); + drawerargs.SetFadeSky(r_skymode == 2 && !(Level->flags & LEVEL_FORCETILEDSKY)); drawerargs.SetSolidTop(frontskytex->GetSkyCapColor(false)); drawerargs.SetSolidBottom(frontskytex->GetSkyCapColor(true)); diff --git a/src/swrenderer/plane/r_slopeplane.cpp b/src/swrenderer/plane/r_slopeplane.cpp index 3c7dcb72d1..c143e86c3f 100644 --- a/src/swrenderer/plane/r_slopeplane.cpp +++ b/src/swrenderer/plane/r_slopeplane.cpp @@ -174,7 +174,8 @@ namespace swrenderer // [RH] set foggy flag basecolormap = colormap; - foggy = level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE); + auto Level = viewport->Level(); + foggy = Level->fadeto || basecolormap->Fade || (Level->flags & LEVEL_HASFADETABLE); planelightfloat = (Thread->Light->SlopePlaneGlobVis(foggy) * lxscale * lyscale) / (fabs(pl->height.ZatPoint(Thread->Viewport->viewpoint.Pos) - Thread->Viewport->viewpoint.Pos.Z)) / 65536.f; diff --git a/src/swrenderer/r_swrenderer.cpp b/src/swrenderer/r_swrenderer.cpp index 3414265325..93802f4c81 100644 --- a/src/swrenderer/r_swrenderer.cpp +++ b/src/swrenderer/r_swrenderer.cpp @@ -202,7 +202,7 @@ void FSoftwareRenderer::RenderView(player_t *player, DCanvas *target, void *vide r_viewwindow = mScene.MainThread()->Viewport->viewwindow; } - level.canvasTextureInfo.UpdateAll([&](AActor *camera, FCanvasTexture *camtex, double fov) + r_viewpoint.ViewLevel->canvasTextureInfo.UpdateAll([&](AActor *camera, FCanvasTexture *camtex, double fov) { RenderTextureView(camtex, camera, fov); }); @@ -296,15 +296,15 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *camtex, AActor *viewp r_viewwindow = cameraViewwindow; } -void FSoftwareRenderer::SetColormap() +void FSoftwareRenderer::SetColormap(FLevelLocals *Level) { // This just sets the default colormap for the spftware renderer. NormalLight.Maps = realcolormaps.Maps; NormalLight.ChangeColor(PalEntry(255, 255, 255), 0); - NormalLight.ChangeFade(level.fadeto); - if (level.fadeto == 0) + NormalLight.ChangeFade(Level->fadeto); + if (Level->fadeto == 0) { - SetDefaultColormap(level.info->FadeTable); + SetDefaultColormap(Level->info->FadeTable); } } diff --git a/src/swrenderer/r_swrenderer.h b/src/swrenderer/r_swrenderer.h index 61d0044ff5..84627f2cda 100644 --- a/src/swrenderer/r_swrenderer.h +++ b/src/swrenderer/r_swrenderer.h @@ -23,7 +23,7 @@ struct FSoftwareRenderer : public FRenderer void SetClearColor(int color) override; void RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, double fov); - void SetColormap() override; + void SetColormap(FLevelLocals *Level) override; void Init() override; private: diff --git a/src/swrenderer/scene/r_light.cpp b/src/swrenderer/scene/r_light.cpp index 73a9e84d72..0834a990c5 100644 --- a/src/swrenderer/scene/r_light.cpp +++ b/src/swrenderer/scene/r_light.cpp @@ -39,6 +39,7 @@ #include "g_level.h" #include "r_utility.h" #include "d_player.h" +#include "g_levellocals.h" #include "swrenderer/scene/r_light.h" #include "swrenderer/viewport/r_viewport.h" @@ -139,12 +140,12 @@ namespace swrenderer TiltVisibility = float(vis * viewport->viewwindow.FocalTangent * (16.f * 320.f) / viewwidth); - NoLightFade = !!(level.flags3 & LEVEL3_NOLIGHTFADE); + NoLightFade = !!(viewport->Level()->flags3 & LEVEL3_NOLIGHTFADE); } - fixed_t LightVisibility::LightLevelToShadeImpl(int lightlevel, bool foggy) + fixed_t LightVisibility::LightLevelToShadeImpl(RenderViewport *viewport, int lightlevel, bool foggy) { - bool nolightfade = !foggy && ((level.flags3 & LEVEL3_NOLIGHTFADE)); + bool nolightfade = !foggy && ((viewport->Level()->flags3 & LEVEL3_NOLIGHTFADE)); if (nolightfade) { return (MAX(255 - lightlevel, 0) * NUMCOLORMAPS) << (FRACBITS - 8); diff --git a/src/swrenderer/scene/r_light.h b/src/swrenderer/scene/r_light.h index 5c2938cecb..d2d2a383da 100644 --- a/src/swrenderer/scene/r_light.h +++ b/src/swrenderer/scene/r_light.h @@ -87,7 +87,7 @@ namespace swrenderer double SlopePlaneGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : TiltVisibility; } - static fixed_t LightLevelToShade(int lightlevel, bool foggy, RenderViewport *viewport) { return LightLevelToShadeImpl(lightlevel + ActualExtraLight(foggy, viewport), foggy); } + static fixed_t LightLevelToShade(int lightlevel, bool foggy, RenderViewport *viewport) { return LightLevelToShadeImpl(viewport, lightlevel + ActualExtraLight(foggy, viewport), foggy); } static int ActualExtraLight(bool fog, RenderViewport *viewport) { return fog ? 0 : viewport->viewpoint.extralight << 4; } @@ -96,7 +96,7 @@ namespace swrenderer double SpriteGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : WallVisibility; } double FlatPlaneGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : FloorVisibility; } - static fixed_t LightLevelToShadeImpl(int lightlevel, bool foggy); + static fixed_t LightLevelToShadeImpl(RenderViewport *viewport, int lightlevel, bool foggy); double BaseVisibility = 0.0; double WallVisibility = 0.0; diff --git a/src/swrenderer/scene/r_opaque_pass.cpp b/src/swrenderer/scene/r_opaque_pass.cpp index 115d37daf5..79d3112b2f 100644 --- a/src/swrenderer/scene/r_opaque_pass.cpp +++ b/src/swrenderer/scene/r_opaque_pass.cpp @@ -492,9 +492,10 @@ namespace swrenderer PvsSubsectors.push_back(sub->Index()); } + auto Level = sub->sector->Level; #ifdef RANGECHECK - if (outersubsector && (unsigned)sub->Index() >= level.subsectors.Size()) - I_Error("RenderSubsector: ss %i with numss = %u", sub->Index(), level.subsectors.Size()); + if (outersubsector && (unsigned)sub->Index() >= Level->subsectors.Size()) + I_Error("RenderSubsector: ss %i with numss = %u", sub->Index(), Level->subsectors.Size()); #endif if (sub->polys) @@ -515,7 +516,7 @@ namespace swrenderer sector_t *frontsector = FakeFlat(sub->sector, &tempsec, &floorlightlevel, &ceilinglightlevel, nullptr, 0, 0, 0, 0); // [RH] set foggy flag - bool foggy = level.fadeto || frontsector->Colormap.FadeColor || (level.flags & LEVEL_HASFADETABLE); + bool foggy = Level->fadeto || frontsector->Colormap.FadeColor || (Level->flags & LEVEL_HASFADETABLE); // kg3D - fake lights CameraLight *cameraLight = CameraLight::Instance(); @@ -611,7 +612,7 @@ namespace swrenderer AddSprites(sub->sector, frontsector->GetTexture(sector_t::ceiling) == skyflatnum ? ceilinglightlevel : floorlightlevel, FakeSide, foggy, GetColorTable(frontsector->Colormap, frontsector->SpecialColors[sector_t::sprites], true)); // [RH] Add particles - if ((unsigned int)(sub->Index()) < level.subsectors.Size()) + if ((unsigned int)(sub->Index()) < Level->subsectors.Size()) { // Only do it for the main BSP. int lightlevel = (floorlightlevel + ceilinglightlevel) / 2; for (int i = ParticlesInSubsec[sub->Index()]; i != NO_PARTICLE; i = Particles[i].snext) @@ -817,21 +818,21 @@ namespace swrenderer } } - void RenderOpaquePass::RenderScene() + void RenderOpaquePass::RenderScene(FLevelLocals *Level) { if (Thread->MainThread) WallCycles.Clock(); for (uint32_t sub : PvsSubsectors) SubsectorDepths[sub] = 0xffffffff; - SubsectorDepths.resize(level.subsectors.Size(), 0xffffffff); + SubsectorDepths.resize(Level->subsectors.Size(), 0xffffffff); PvsSubsectors.clear(); SeenSpriteSectors.clear(); SeenActors.clear(); InSubsector = nullptr; - RenderBSPNode(level.HeadNode()); // The head node is the last node output. + RenderBSPNode(Level->HeadNode()); // The head node is the last node output. if (Thread->MainThread) WallCycles.Unclock(); @@ -845,9 +846,9 @@ namespace swrenderer void RenderOpaquePass::RenderBSPNode(void *node) { - if (level.nodes.Size() == 0) + if (Thread->Viewport->Level()->nodes.Size() == 0) { - RenderSubsector(&level.subsectors[0]); + RenderSubsector(&Thread->Viewport->Level()->subsectors[0]); return; } while (!((size_t)node & 1)) // Keep going until found a subsector diff --git a/src/swrenderer/scene/r_opaque_pass.h b/src/swrenderer/scene/r_opaque_pass.h index a02b1d6ddb..4bd18bdd7e 100644 --- a/src/swrenderer/scene/r_opaque_pass.h +++ b/src/swrenderer/scene/r_opaque_pass.h @@ -64,7 +64,7 @@ namespace swrenderer RenderOpaquePass(RenderThread *thread); void ClearClip(); - void RenderScene(); + void RenderScene(FLevelLocals *Level); void ResetFakingUnderwater() { r_fakingunderwater = false; } sector_t *FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel, seg_t *backline, int backx1, int backx2, double frontcz1, double frontcz2); diff --git a/src/swrenderer/scene/r_portal.cpp b/src/swrenderer/scene/r_portal.cpp index 61fc4fc3a2..d78930e417 100644 --- a/src/swrenderer/scene/r_portal.cpp +++ b/src/swrenderer/scene/r_portal.cpp @@ -167,8 +167,10 @@ namespace swrenderer continue; } + auto Level = Thread->Viewport->Level(); + SetInSkyBox(port); - if (port->mPartner > 0) SetInSkyBox(&level.sectorPortals[port->mPartner]); + if (port->mPartner > 0) SetInSkyBox(&Level->sectorPortals[port->mPartner]); Thread->Viewport->viewpoint.camera = nullptr; Thread->Viewport->viewpoint.sector = port->mDestination; assert(Thread->Viewport->viewpoint.sector != nullptr); @@ -221,12 +223,12 @@ namespace swrenderer memcpy(draw_segment->sprtopclip, ceilingclip + pl->left, (pl->right - pl->left) * sizeof(short)); drawseglist->Push(draw_segment); - Thread->OpaquePass->RenderScene(); + Thread->OpaquePass->RenderScene(Thread->Viewport->Level()); Thread->Clip3D->ResetClip(); // reset clips (floor/ceiling) planes->Render(); ClearInSkyBox(port); - if (port->mPartner > 0) SetInSkyBox(&level.sectorPortals[port->mPartner]); + if (port->mPartner > 0) SetInSkyBox(&Level->sectorPortals[port->mPartner]); } // Draw all the masked textures in a second pass, in the reverse order they @@ -438,7 +440,7 @@ namespace swrenderer memcpy(ceilingclip + pds->x1, &pds->ceilingclip[0], pds->len * sizeof(*ceilingclip)); memcpy(floorclip + pds->x1, &pds->floorclip[0], pds->len * sizeof(*floorclip)); - Thread->OpaquePass->RenderScene(); + Thread->OpaquePass->RenderScene(Thread->Viewport->Level()); Thread->Clip3D->ResetClip(); // reset clips (floor/ceiling) if (!savedvisibility && viewpoint.camera) viewpoint.camera->renderflags &= ~RF_INVISIBLE; diff --git a/src/swrenderer/scene/r_scene.cpp b/src/swrenderer/scene/r_scene.cpp index c8baa1d4ef..0678607a21 100644 --- a/src/swrenderer/scene/r_scene.cpp +++ b/src/swrenderer/scene/r_scene.cpp @@ -292,7 +292,7 @@ namespace swrenderer if (thread->X2 < viewwidth) thread->ClipSegments->Clip(thread->X2, viewwidth, true, &visitor); - thread->OpaquePass->RenderScene(); + thread->OpaquePass->RenderScene(thread->Viewport->Level()); thread->Clip3D->ResetClip(); // reset clips (floor/ceiling) if (thread->MainThread) diff --git a/src/swrenderer/things/r_model.cpp b/src/swrenderer/things/r_model.cpp index c7cda60253..6dca4cbf3f 100644 --- a/src/swrenderer/things/r_model.cpp +++ b/src/swrenderer/things/r_model.cpp @@ -273,10 +273,11 @@ namespace swrenderer { // Calculate the WorldToView matrix as it would have looked like without yshearing: const auto &Viewpoint = Thread->Viewport->viewpoint; + auto Level = Thread->Viewport->Level(); const auto &Viewwindow = Thread->Viewport->viewwindow; double radPitch = Viewpoint.Angles.Pitch.Normalized180().Radians(); double angx = cos(radPitch); - double angy = sin(radPitch) * level.info->pixelstretch; + double angy = sin(radPitch) * Level->info->pixelstretch; double alen = sqrt(angx*angx + angy*angy); float adjustedPitch = (float)asin(angy / alen); float adjustedViewAngle = (float)(Viewpoint.Angles.Yaw - 90).Radians(); @@ -286,7 +287,7 @@ namespace swrenderer Mat4f altWorldToView = Mat4f::Rotate(adjustedPitch, 1.0f, 0.0f, 0.0f) * Mat4f::Rotate(adjustedViewAngle, 0.0f, -1.0f, 0.0f) * - Mat4f::Scale(1.0f, level.info->pixelstretch, 1.0f) * + Mat4f::Scale(1.0f, Level->info->pixelstretch, 1.0f) * Mat4f::SwapYZ() * Mat4f::Translate((float)-Viewpoint.Pos.X, (float)-Viewpoint.Pos.Y, (float)-Viewpoint.Pos.Z); diff --git a/src/swrenderer/things/r_particle.cpp b/src/swrenderer/things/r_particle.cpp index 07d460b425..ed961da96f 100644 --- a/src/swrenderer/things/r_particle.cpp +++ b/src/swrenderer/things/r_particle.cpp @@ -79,7 +79,7 @@ namespace swrenderer sector_t* heightsec = NULL; double timefrac = r_viewpoint.TicFrac; - if (paused || bglobal.freeze || (level.flags2 & LEVEL2_FROZEN)) + if (paused || bglobal.freeze || (sector->Level->flags2 & LEVEL2_FROZEN)) timefrac = 0.; double ippx = particle->Pos.X + particle->Vel.X * timefrac; diff --git a/src/swrenderer/things/r_playersprite.cpp b/src/swrenderer/things/r_playersprite.cpp index fd1b8adf85..812d2df370 100644 --- a/src/swrenderer/things/r_playersprite.cpp +++ b/src/swrenderer/things/r_playersprite.cpp @@ -134,7 +134,8 @@ namespace swrenderer } // [RH] set foggy flag - bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); + auto Level = Thread->Viewport->Level(); + bool foggy = (Level->fadeto || basecolormap->Fade || (Level->flags & LEVEL_HASFADETABLE)); // get light level int lightlevel = (floorlight + ceilinglight) >> 1; diff --git a/src/swrenderer/things/r_visiblespritelist.cpp b/src/swrenderer/things/r_visiblespritelist.cpp index f6181b506c..108fdb1c73 100644 --- a/src/swrenderer/things/r_visiblespritelist.cpp +++ b/src/swrenderer/things/r_visiblespritelist.cpp @@ -110,9 +110,10 @@ namespace swrenderer uint32_t VisibleSpriteList::FindSubsectorDepth(RenderThread *thread, const DVector2 &worldPos) { - if (level.nodes.Size() == 0) + auto Level = thread->Viewport->Level(); + if (Level->nodes.Size() == 0) { - subsector_t *sub = &level.subsectors[0]; + subsector_t *sub = &Level->subsectors[0]; return thread->OpaquePass->GetSubsectorDepth(sub->Index()); } else diff --git a/src/swrenderer/viewport/r_viewport.cpp b/src/swrenderer/viewport/r_viewport.cpp index e3cfc15483..2e39b1d3d2 100644 --- a/src/swrenderer/viewport/r_viewport.cpp +++ b/src/swrenderer/viewport/r_viewport.cpp @@ -135,7 +135,7 @@ namespace swrenderer virtwidth = virtwidth * AspectMultiplier(viewwindow.WidescreenRatio) / 48; } - double ypixelstretch = (level.info) ? level.info->pixelstretch : 1.2; + double ypixelstretch = (Level()->info) ? Level()->info->pixelstretch : 1.2; BaseYaspectMul = 320.0 * virtheight2 / (r_Yaspect * virtwidth2); YaspectMul = 320.0 * virtheight / (r_Yaspect * virtwidth) * ypixelstretch / 1.2; diff --git a/src/swrenderer/viewport/r_viewport.h b/src/swrenderer/viewport/r_viewport.h index 69adc5778d..93400f3e46 100644 --- a/src/swrenderer/viewport/r_viewport.h +++ b/src/swrenderer/viewport/r_viewport.h @@ -5,6 +5,7 @@ #include #include "v_video.h" #include "r_defs.h" +#include "actorinlines.h" #include "polyrenderer/math/gpu_types.h" #define MINZ double((2048*4) / double(1 << 20)) @@ -80,6 +81,11 @@ namespace swrenderer return (CenterY - screenY - 0.5) / FocalLengthY * viewZ; } + FLevelLocals *Level() + { + return viewpoint.ViewLevel; + } + private: void InitTextureMapping(); void SetupBuffer();