Move visibility stuff into LightVisibility

This commit is contained in:
Magnus Norddahl 2017-01-26 09:49:07 +01:00
parent 933f2d116a
commit 4bbf1ba11c
22 changed files with 121 additions and 109 deletions

View file

@ -137,7 +137,7 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, const Vec4f &clipPlan
args.uniforms.flags = 0;
args.SetColormap(front->ColorMap);
args.SetTexture(tex, decal->Translation, true);
args.uniforms.globvis = (float)swrenderer::r_WallVisibility;
args.uniforms.globvis = (float)swrenderer::LightVisibility::Instance()->WallGlobVis();
if (fullbrightSprite || swrenderer::fixedlightlev >= 0 || swrenderer::fixedcolormap)
{
args.uniforms.light = 256;

View file

@ -73,7 +73,7 @@ void RenderPolyParticle::Render(const TriMatrix &worldToClip, const Vec4f &clipP
PolyDrawArgs args;
args.uniforms.globvis = (float)swrenderer::r_SpriteVisibility;
args.uniforms.globvis = (float)swrenderer::LightVisibility::Instance()->ParticleGlobVis();
if (fullbrightSprite || swrenderer::fixedlightlev >= 0 || swrenderer::fixedcolormap)
{

View file

@ -107,7 +107,7 @@ void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const Vec4f &c
UVTransform xform(ceiling ? fakeFloor->top.model->planes[sector_t::ceiling].xform : fakeFloor->top.model->planes[sector_t::floor].xform, tex);
PolyDrawArgs args;
args.uniforms.globvis = (float)swrenderer::r_TiltVisibility * 48.0f;
args.uniforms.globvis = (float)swrenderer::LightVisibility::Instance()->SlopePlaneGlobVis() * 48.0f;
args.uniforms.light = (uint32_t)(lightlevel / 255.0f * 256.0f);
if (swrenderer::fixedlightlev >= 0 || swrenderer::fixedcolormap)
args.uniforms.light = 256;
@ -301,7 +301,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const Vec4f &clipPlan
UVTransform transform(ceiling ? frontsector->planes[sector_t::ceiling].xform : frontsector->planes[sector_t::floor].xform, tex);
PolyDrawArgs args;
args.uniforms.globvis = (float)swrenderer::r_TiltVisibility * 48.0f;
args.uniforms.globvis = (float)swrenderer::LightVisibility::Instance()->SlopePlaneGlobVis() * 48.0f;
args.uniforms.light = (uint32_t)(frontsector->lightlevel / 255.0f * 256.0f);
if (swrenderer::fixedlightlev >= 0 || swrenderer::fixedcolormap)
args.uniforms.light = 256;

View file

@ -223,7 +223,7 @@ void RenderPolyPlayerSprites::RenderSprite(DPSprite *sprite, AActor *owner, floa
int actualextralight = foggy ? 0 : extralight << 4;
int spriteshade = LIGHT2SHADE(owner->Sector->lightlevel + actualextralight);
double minz = double((2048 * 4) / double(1 << 20));
ColormapNum = GETPALOOKUP(swrenderer::r_SpriteVisibility / minz, spriteshade);
ColormapNum = GETPALOOKUP(swrenderer::LightVisibility::Instance()->SpriteGlobVis() / minz, spriteshade);
if (sprite->GetID() < PSP_TARGETCENTER)
{

View file

@ -90,7 +90,7 @@ void PolyDrawSectorPortal::SaveGlobals()
savedextralight = extralight;
savedpos = ViewPos;
savedangle = ViewAngle;
savedvisibility = swrenderer::R_GetVisibility();
savedvisibility = swrenderer::LightVisibility::Instance()->GetVisibility();
savedcamera = camera;
savedsector = viewsector;
@ -99,7 +99,7 @@ void PolyDrawSectorPortal::SaveGlobals()
// Don't let gun flashes brighten the sky box
AActor *sky = Portal->mSkybox;
extralight = 0;
swrenderer::R_SetVisibility(sky->args[0] * 0.25f);
swrenderer::LightVisibility::Instance()->SetVisibility(sky->args[0] * 0.25f);
ViewPos = sky->InterpolatedPosition(r_TicFracF);
ViewAngle = savedangle + (sky->PrevAngles.Yaw + deltaangle(sky->PrevAngles.Yaw, sky->Angles.Yaw) * r_TicFracF);
}
@ -127,7 +127,7 @@ void PolyDrawSectorPortal::RestoreGlobals()
camera = savedcamera;
viewsector = savedsector;
ViewPos = savedpos;
swrenderer::R_SetVisibility(savedvisibility);
swrenderer::LightVisibility::Instance()->SetVisibility(savedvisibility);
extralight = savedextralight;
ViewAngle = savedangle;
R_SetViewAngle();

View file

@ -241,7 +241,7 @@ void RenderPolyScene::RenderPortals(int portalDepth)
PolyDrawArgs args;
args.objectToClip = &WorldToClip;
args.mode = TriangleDrawMode::Fan;
args.uniforms.globvis = (float)swrenderer::r_WallVisibility;
args.uniforms.globvis = (float)swrenderer::LightVisibility::Instance()->WallGlobVis();
args.uniforms.color = 0;
args.uniforms.light = 256;
args.uniforms.flags = TriUniforms::fixed_light;

View file

@ -55,7 +55,7 @@ void PolySkyDome::Render(const TriMatrix &worldToClip)
int rc = mRows + 1;
PolyDrawArgs args;
args.uniforms.globvis = (float)swrenderer::r_WallVisibility;
args.uniforms.globvis = (float)swrenderer::LightVisibility::Instance()->WallGlobVis();
args.uniforms.light = 256;
args.uniforms.flags = 0;
args.uniforms.subsectorDepth = RenderPolyScene::SkySubsectorDepth;

View file

@ -138,7 +138,7 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, const Vec4f &clipPla
bool fullbrightSprite = ((thing->renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT));
PolyDrawArgs args;
args.uniforms.globvis = (float)swrenderer::r_SpriteVisibility;
args.uniforms.globvis = (float)swrenderer::LightVisibility::Instance()->SpriteGlobVis();
args.uniforms.flags = 0;
if (fullbrightSprite || swrenderer::fixedlightlev >= 0 || swrenderer::fixedcolormap)
{

View file

@ -247,7 +247,7 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane
}
PolyDrawArgs args;
args.uniforms.globvis = (float)swrenderer::r_WallVisibility;
args.uniforms.globvis = (float)swrenderer::LightVisibility::Instance()->WallGlobVis();
args.uniforms.light = (uint32_t)(GetLightLevel() / 255.0f * 256.0f);
args.uniforms.flags = 0;
args.uniforms.subsectorDepth = SubsectorDepth;

View file

@ -100,7 +100,7 @@ void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, const Vec4f &cli
bool fullbrightSprite = ((thing->renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT));
PolyDrawArgs args;
args.uniforms.globvis = (float)swrenderer::r_WallVisibility;
args.uniforms.globvis = (float)swrenderer::LightVisibility::Instance()->WallGlobVis();
if (fullbrightSprite || swrenderer::fixedlightlev >= 0 || swrenderer::fixedcolormap)
{
args.uniforms.light = 256;

View file

@ -904,7 +904,7 @@ namespace swrenderer
if (fixedcolormap == NULL && fixedlightlev < 0)
{
wallshade = LIGHT2SHADE(curline->sidedef->GetLightLevel(foggy, frontsector->lightlevel) + R_ActualExtraLight(foggy));
double GlobVis = r_WallVisibility;
double GlobVis = LightVisibility::Instance()->WallGlobVis();
rw_lightleft = float(GlobVis / WallC.sz1);
rw_lightstep = float((GlobVis / WallC.sz2 - rw_lightleft) / (WallC.sx2 - WallC.sx1));
}

View file

@ -106,7 +106,7 @@ namespace swrenderer
planeheight = fabs(pl->height.Zat0() - ViewPos.Z);
basecolormap = colormap;
GlobVis = r_FloorVisibility / planeheight;
GlobVis = LightVisibility::Instance()->FlatPlaneGlobVis() / planeheight;
ds_light = 0;
if (fixedlightlev >= 0)
{

View file

@ -143,7 +143,7 @@ namespace swrenderer
plane_sz[0] = -plane_sz[0];
}
planelightfloat = (r_TiltVisibility * lxscale * lyscale) / (fabs(pl->height.ZatPoint(ViewPos) - ViewPos.Z)) / 65536.f;
planelightfloat = (LightVisibility::Instance()->SlopePlaneGlobVis() * lxscale * lyscale) / (fabs(pl->height.ZatPoint(ViewPos) - ViewPos.Z)) / 65536.f;
if (pl->height.fC() > 0)
planelightfloat = -planelightfloat;

View file

@ -38,77 +38,10 @@ EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor)
namespace swrenderer
{
double r_BaseVisibility;
double r_WallVisibility;
double r_FloorVisibility;
float r_TiltVisibility;
double r_SpriteVisibility;
int fixedlightlev;
FSWColormap *fixedcolormap;
FSpecialColormap *realfixedcolormap;
namespace
{
double CurrentVisibility = 8.f;
double MaxVisForWall;
double MaxVisForFloor;
}
// Changes how rapidly things get dark with distance
void R_SetVisibility(double vis)
{
// Allow negative visibilities, just for novelty's sake
vis = clamp(vis, -204.7, 204.7); // (205 and larger do not work in 5:4 aspect ratio)
CurrentVisibility = vis;
if (FocalTangent == 0 || FocalLengthY == 0)
{ // If r_visibility is called before the renderer is all set up, don't
// divide by zero. This will be called again later, and the proper
// values can be initialized then.
return;
}
r_BaseVisibility = vis;
MaxVisForWall = (InvZtoScale * (SCREENWIDTH*r_Yaspect) / (viewwidth*SCREENHEIGHT * FocalTangent));
MaxVisForWall = 32767.0 / MaxVisForWall;
MaxVisForFloor = 32767.0 / (viewheight >> 2) * FocalLengthY / 160;
// Prevent overflow on walls
if (r_BaseVisibility < 0 && r_BaseVisibility < -MaxVisForWall)
r_WallVisibility = -MaxVisForWall;
else if (r_BaseVisibility > 0 && r_BaseVisibility > MaxVisForWall)
r_WallVisibility = MaxVisForWall;
else
r_WallVisibility = r_BaseVisibility;
r_WallVisibility = (InvZtoScale * SCREENWIDTH*AspectBaseHeight(WidescreenRatio) /
(viewwidth*SCREENHEIGHT * 3)) * (r_WallVisibility * FocalTangent);
// Prevent overflow on floors/ceilings. Note that the calculation of
// MaxVisForFloor means that planes less than two units from the player's
// view could still overflow, but there is no way to totally eliminate
// that while still using fixed point math.
if (r_BaseVisibility < 0 && r_BaseVisibility < -MaxVisForFloor)
r_FloorVisibility = -MaxVisForFloor;
else if (r_BaseVisibility > 0 && r_BaseVisibility > MaxVisForFloor)
r_FloorVisibility = MaxVisForFloor;
else
r_FloorVisibility = r_BaseVisibility;
r_FloorVisibility = 160.0 * r_FloorVisibility / FocalLengthY;
r_TiltVisibility = float(vis * FocalTangent * (16.f * 320.f) / viewwidth);
r_SpriteVisibility = r_WallVisibility;
}
double R_GetVisibility()
{
return CurrentVisibility;
}
void R_SetupColormap(AActor *actor)
{
player_t *player = actor->player;
@ -154,6 +87,62 @@ namespace swrenderer
}
}
/////////////////////////////////////////////////////////////////////////
LightVisibility *LightVisibility::Instance()
{
static LightVisibility instance;
return &instance;
}
// Changes how rapidly things get dark with distance
void LightVisibility::SetVisibility(double vis)
{
// Allow negative visibilities, just for novelty's sake
vis = clamp(vis, -204.7, 204.7); // (205 and larger do not work in 5:4 aspect ratio)
CurrentVisibility = vis;
if (FocalTangent == 0 || FocalLengthY == 0)
{ // If r_visibility is called before the renderer is all set up, don't
// divide by zero. This will be called again later, and the proper
// values can be initialized then.
return;
}
BaseVisibility = vis;
MaxVisForWall = (InvZtoScale * (SCREENWIDTH*r_Yaspect) / (viewwidth*SCREENHEIGHT * FocalTangent));
MaxVisForWall = 32767.0 / MaxVisForWall;
MaxVisForFloor = 32767.0 / (viewheight >> 2) * FocalLengthY / 160;
// Prevent overflow on walls
if (BaseVisibility < 0 && BaseVisibility < -MaxVisForWall)
WallVisibility = -MaxVisForWall;
else if (BaseVisibility > 0 && BaseVisibility > MaxVisForWall)
WallVisibility = MaxVisForWall;
else
WallVisibility = BaseVisibility;
WallVisibility = (InvZtoScale * SCREENWIDTH*AspectBaseHeight(WidescreenRatio) /
(viewwidth*SCREENHEIGHT * 3)) * (WallVisibility * FocalTangent);
// Prevent overflow on floors/ceilings. Note that the calculation of
// MaxVisForFloor means that planes less than two units from the player's
// view could still overflow, but there is no way to totally eliminate
// that while still using fixed point math.
if (BaseVisibility < 0 && BaseVisibility < -MaxVisForFloor)
FloorVisibility = -MaxVisForFloor;
else if (BaseVisibility > 0 && BaseVisibility > MaxVisForFloor)
FloorVisibility = MaxVisForFloor;
else
FloorVisibility = BaseVisibility;
FloorVisibility = 160.0 * FloorVisibility / FocalLengthY;
TiltVisibility = float(vis * FocalTangent * (16.f * 320.f) / viewwidth);
}
// Controls how quickly light ramps across a 1/z range. Set this, and it
// sets all the r_*Visibility variables (except r_SkyVisibilily, which is
// currently unused).
@ -161,11 +150,11 @@ namespace swrenderer
{
if (argv.argc() < 2)
{
Printf("Visibility is %g\n", R_GetVisibility());
Printf("Visibility is %g\n", LightVisibility::Instance()->GetVisibility());
}
else if (!netgame)
{
R_SetVisibility(atof(argv[1]));
LightVisibility::Instance()->SetVisibility(atof(argv[1]));
}
else
{

View file

@ -18,6 +18,7 @@
#include "v_palette.h"
#include "r_data/colormaps.h"
#include "r_utility.h"
#include "r_viewport.h"
// Lighting.
//
@ -53,23 +54,43 @@ struct FSWColormap;
namespace swrenderer
{
extern double r_BaseVisibility;
extern double r_WallVisibility;
extern double r_FloorVisibility;
extern float r_TiltVisibility;
extern double r_SpriteVisibility;
extern int fixedlightlev;
extern FSWColormap *fixedcolormap;
extern FSpecialColormap *realfixedcolormap;
inline int R_ActualExtraLight(bool fog) { return fog ? 0 : extralight << 4; }
void R_SetVisibility(double visibility);
double R_GetVisibility();
void R_SetupColormap(AActor *actor);
class LightVisibility
{
public:
static LightVisibility *Instance();
void SetVisibility(double visibility);
double GetVisibility() const { return CurrentVisibility; }
double WallGlobVis() const { return WallVisibility; }
double SpriteGlobVis() const { return WallVisibility; }
double ParticleGlobVis() const { return WallVisibility * 0.5; }
double FlatPlaneGlobVis() const { return FloorVisibility; }
double SlopePlaneGlobVis() const { return TiltVisibility; }
// The vis value to pass into the GETPALOOKUP or LIGHTSCALE macros
double WallVis(double screenZ) const { return WallGlobVis() / screenZ; }
double SpriteVis(double screenZ) const { return WallGlobVis() / screenZ; }
double ParticleVis(double screenZ) const { return WallGlobVis() / screenZ; }
double FlatPlaneVis(int screenY, double planeZ) const { return FlatPlaneGlobVis() / fabs(planeZ - ViewPos.Z) * fabs(CenterY - screenY); }
private:
double BaseVisibility = 0.0;
double WallVisibility = 0.0;
double FloorVisibility = 0.0;
float TiltVisibility = 0.0f;
double CurrentVisibility = 8.f;
double MaxVisForWall = 0.0;
double MaxVisForFloor = 0.0;
};
class ColormapLight
{
public:
@ -78,4 +99,6 @@ namespace swrenderer
void SetColormap(double visibility, int shade, FDynamicColormap *basecolormap, bool fullbright, bool invertColormap, bool fadeToBlack);
};
inline int R_ActualExtraLight(bool fog) { return fog ? 0 : extralight << 4; }
}

View file

@ -106,7 +106,7 @@ namespace swrenderer
DAngle savedangle = ViewAngle;
ptrdiff_t savedds_p = drawseglist->ds_p - drawseglist->drawsegs;
size_t savedinteresting = drawseglist->FirstInterestingDrawseg;
double savedvisibility = R_GetVisibility();
double savedvisibility = LightVisibility::Instance()->GetVisibility();
AActor *savedcamera = camera;
sector_t *savedsector = viewsector;
@ -128,7 +128,7 @@ namespace swrenderer
// Don't let gun flashes brighten the sky box
AActor *sky = port->mSkybox;
extralight = 0;
R_SetVisibility(sky->args[0] * 0.25f);
LightVisibility::Instance()->SetVisibility(sky->args[0] * 0.25f);
ViewPos = sky->InterpolatedPosition(r_TicFracF);
ViewAngle = savedangle + (sky->PrevAngles.Yaw + deltaangle(sky->PrevAngles.Yaw, sky->Angles.Yaw) * r_TicFracF);
@ -141,7 +141,7 @@ namespace swrenderer
case PORTS_PORTAL:
case PORTS_LINKEDPORTAL:
extralight = pl->extralight;
R_SetVisibility(pl->visibility);
LightVisibility::Instance()->SetVisibility(pl->visibility);
ViewPos.X = pl->viewpos.X + port->mDisplacement.X;
ViewPos.Y = pl->viewpos.Y + port->mDisplacement.Y;
ViewPos.Z = pl->viewpos.Z;
@ -260,7 +260,7 @@ namespace swrenderer
camera = savedcamera;
viewsector = savedsector;
ViewPos = savedpos;
R_SetVisibility(savedvisibility);
LightVisibility::Instance()->SetVisibility(savedvisibility);
extralight = savedextralight;
ViewAngle = savedangle;
R_SetViewAngle();
@ -523,7 +523,7 @@ namespace swrenderer
stacked_viewpos = ViewPos;
stacked_angle = ViewAngle;
stacked_extralight = extralight;
stacked_visibility = R_GetVisibility();
stacked_visibility = LightVisibility::Instance()->GetVisibility();
}
void RenderPortal::SetMainPortal()

View file

@ -119,7 +119,8 @@ namespace swrenderer
InitTextureMapping();
// Reset r_*Visibility vars
R_SetVisibility(R_GetVisibility());
LightVisibility *visibility = LightVisibility::Instance();
visibility->SetVisibility(visibility->GetVisibility());
SetupBuffer();
}

View file

@ -201,8 +201,7 @@ namespace swrenderer
vis->floorclip = 0;
vis->foggy = foggy;
// Particles are slightly more visible than regular sprites.
vis->Light.SetColormap(tiz * r_SpriteVisibility * 0.5, shade, map, particle->bright != 0, false, false);
vis->Light.SetColormap(tiz * LightVisibility::Instance()->ParticleGlobVis(), shade, map, particle->bright != 0, false, false);
VisibleSpriteList::Instance()->Push(vis);
}

View file

@ -223,7 +223,7 @@ namespace swrenderer
bool fullbright = !vis->foggy && ((renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT));
bool fadeToBlack = (vis->RenderStyle.Flags & STYLEF_FadeToBlack) != 0;
vis->Light.SetColormap(r_SpriteVisibility / MAX(tz, MINZ), spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack);
vis->Light.SetColormap(LightVisibility::Instance()->SpriteGlobVis() / MAX(tz, MINZ), spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack);
VisibleSpriteList::Instance()->Push(vis);
}

View file

@ -135,7 +135,7 @@ namespace swrenderer
int spriteshade = LIGHT2SHADE(sec->lightlevel + R_ActualExtraLight(spr->foggy));
Light.SetColormap(r_SpriteVisibility / MAX(MINZ, (double)spr->depth), spriteshade, mybasecolormap, isFullBright, invertcolormap, fadeToBlack);
Light.SetColormap(LightVisibility::Instance()->SpriteGlobVis() / MAX(MINZ, (double)spr->depth), spriteshade, mybasecolormap, isFullBright, invertcolormap, fadeToBlack);
}
}

View file

@ -175,7 +175,7 @@ namespace swrenderer
bool fullbright = !vis->foggy && ((renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT));
bool fadeToBlack = (vis->RenderStyle.Flags & STYLEF_FadeToBlack) != 0;
vis->Light.SetColormap(r_SpriteVisibility / MAX(tz, MINZ), spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack);
vis->Light.SetColormap(LightVisibility::Instance()->SpriteGlobVis() / MAX(tz, MINZ), spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack);
VisibleSpriteList::Instance()->Push(vis, true);
}

View file

@ -132,7 +132,7 @@ namespace swrenderer
vis->wallc = wallc;
vis->foggy = foggy;
vis->Light.SetColormap(r_SpriteVisibility / MAX(tz, MINZ), spriteshade, basecolormap, false, false, false);
vis->Light.SetColormap(LightVisibility::Instance()->SpriteGlobVis() / MAX(tz, MINZ), spriteshade, basecolormap, false, false, false);
VisibleSpriteList::Instance()->Push(vis);
}
@ -180,7 +180,7 @@ namespace swrenderer
}
int shade = LIGHT2SHADE(spr->sector->lightlevel + R_ActualExtraLight(spr->foggy));
double GlobVis = r_WallVisibility;
double GlobVis = LightVisibility::Instance()->WallGlobVis();
float lightleft = float(GlobVis / spr->wallc.sz1);
float lightstep = float((GlobVis / spr->wallc.sz2 - lightleft) / (spr->wallc.sx2 - spr->wallc.sx1));
float light = lightleft + (x1 - spr->wallc.sx1) * lightstep;