From d748b6ad70175253035e2cba4fc2b77c2371fdc7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 29 Dec 2016 01:12:17 +0100 Subject: [PATCH] - added explicit fog density as a sector property, accessible through UDMF and ACS. - allow changing sector glow information through ACS. --- specs/udmf_zdoom.txt | 3 +++ src/gl/compatibility/gl_20.cpp | 2 +- src/gl/renderer/gl_colormap.h | 3 +++ src/gl/renderer/gl_lightdata.cpp | 33 +++++++++++++++------------ src/gl/renderer/gl_lightdata.h | 2 +- src/namedef.h | 1 + src/p_acs.cpp | 38 ++++++++++++++++++++++++++++++++ src/p_udmf.cpp | 13 ++++++++--- src/r_data/colormaps.h | 1 + 9 files changed, 77 insertions(+), 19 deletions(-) diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index 8a96a3ecf7..0fe7b1e8ea 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -220,6 +220,9 @@ Note: All fields default to false unless mentioned otherwise. floorglowheight = ; // Height of floor glow. This only has an effect for the sector's own glow color, but not for a texture based glow. ceilingglowcolor = ; // Sector's ceiling glow color as RRGGBB value, default = 'use texture's definition'. Set to -1 to disable glowing. ceilingglowheight = ; // Height of ceiling glow. This only has an effect for the sector's own glow color, but not for a texture based glow. + fogdensity = ; // Sets an explicit fog density for the sector, overriding the default calculation from the light level. Value range is 0-510, + // 0 meaning that the default is to be used, 2 equalling the density of a light level of 250, and 255 equalling the density of + // a light level of 0. portal_ceil_alpha = // translucency of ceiling portal (default is 0 (not visible)) portal_ceil_blocksound = // ceiling portal blocks sound. diff --git a/src/gl/compatibility/gl_20.cpp b/src/gl/compatibility/gl_20.cpp index 3486639290..0f9ee5f43f 100644 --- a/src/gl/compatibility/gl_20.cpp +++ b/src/gl/compatibility/gl_20.cpp @@ -515,7 +515,7 @@ void GLWall::RenderFogBoundaryCompat() { // without shaders some approximation is needed. This won't look as good // as the shader version but it's an acceptable compromise. - float fogdensity = gl_GetFogDensity(lightlevel, Colormap.FadeColor); + float fogdensity = gl_GetFogDensity(lightlevel, Colormap.FadeColor, Colormap.fogdensity); float dist1 = Dist2(ViewPos.X, ViewPos.Y, glseg.x1, glseg.y1); float dist2 = Dist2(ViewPos.X, ViewPos.Y, glseg.x2, glseg.y2); diff --git a/src/gl/renderer/gl_colormap.h b/src/gl/renderer/gl_colormap.h index 2122b1248c..37a7629708 100644 --- a/src/gl/renderer/gl_colormap.h +++ b/src/gl/renderer/gl_colormap.h @@ -32,6 +32,7 @@ struct FColormap PalEntry FadeColor; // a is fadedensity>>1 int desaturation; int blendfactor; + int fogdensity; void Clear() { @@ -39,6 +40,7 @@ struct FColormap FadeColor=0; desaturation = 0; blendfactor=0; + fogdensity = 0; } void ClearColor() @@ -55,6 +57,7 @@ struct FColormap desaturation = from->Desaturate; FadeColor = from->Fade; blendfactor = from->Color.a; + fogdensity = from->Fade.a*2; return * this; } diff --git a/src/gl/renderer/gl_lightdata.cpp b/src/gl/renderer/gl_lightdata.cpp index ca2d32c41d..d09484a1f5 100644 --- a/src/gl/renderer/gl_lightdata.cpp +++ b/src/gl/renderer/gl_lightdata.cpp @@ -294,43 +294,48 @@ void gl_SetColor(int sectorlightlevel, int rellight, const FColormap &cm, float // //========================================================================== -float gl_GetFogDensity(int lightlevel, PalEntry fogcolor) +float gl_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity) { float density; - if (glset.lightmode&4) + if (glset.lightmode & 4) { // uses approximations of Legacy's default settings. - density = fogdensity? fogdensity : 18; + density = fogdensity ? fogdensity : 18; } else if ((fogcolor.d & 0xffffff) == 0) { // case 1: black fog if (glset.lightmode != 8) { - density=distfogtable[glset.lightmode!=0][gl_ClampLight(lightlevel)]; + density = distfogtable[glset.lightmode != 0][gl_ClampLight(lightlevel)]; } else { density = 0; } } - else if (outsidefogdensity != 0 && outsidefogcolor.a!=0xff && (fogcolor.d & 0xffffff) == (outsidefogcolor.d & 0xffffff)) + else if (sectorfogdensity != 0) { - // case 2. outsidefogdensity has already been set as needed - density=outsidefogdensity; + // case 2: Sector has an explicit fog density set. + density = sectorfogdensity; } - else if (fogdensity!=0) + else if (outsidefogdensity != 0 && outsidefogcolor.a != 0xff && (fogcolor.d & 0xffffff) == (outsidefogcolor.d & 0xffffff)) { - // case 3: level has fog density set - density=fogdensity; + // case 3. outsidefogdensity has already been set as needed + density = outsidefogdensity; + } + else if (fogdensity != 0) + { + // case 4: level has fog density set + density = fogdensity; } else if (lightlevel < 248) { - // case 4: use light level - density=clamp(255-lightlevel,30,255); + // case 5: use light level + density = clamp(255 - lightlevel, 30, 255); } - else + else { density = 0.f; } @@ -487,7 +492,7 @@ void gl_SetFog(int lightlevel, int rellight, const FColormap *cmap, bool isaddit else if (cmap != NULL && gl_fixedcolormap == 0) { fogcolor = cmap->FadeColor; - fogdensity = gl_GetFogDensity(lightlevel, fogcolor); + fogdensity = gl_GetFogDensity(lightlevel, fogcolor, cmap->fogdensity); fogcolor.a=0; } else diff --git a/src/gl/renderer/gl_lightdata.h b/src/gl/renderer/gl_lightdata.h index 4cc7a7d046..a1abf8c823 100644 --- a/src/gl/renderer/gl_lightdata.h +++ b/src/gl/renderer/gl_lightdata.h @@ -18,7 +18,7 @@ void gl_SetFogParams(int _fogdensity, PalEntry _outsidefogcolor, int _outsidefog int gl_CalcLightLevel(int lightlevel, int rellight, bool weapon); void gl_SetColor(int light, int rellight, const FColormap &cm, float alpha, bool weapon=false); -float gl_GetFogDensity(int lightlevel, PalEntry fogcolor); +float gl_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity); struct sector_t; bool gl_CheckFog(FColormap *cm, int lightlevel); bool gl_CheckFog(sector_t *frontsector, sector_t *backsector); diff --git a/src/namedef.h b/src/namedef.h index e08aec1e2f..bb9d27f404 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -581,6 +581,7 @@ xx(floorglowcolor) xx(floorglowheight) xx(ceilingglowcolor) xx(ceilingglowheight) +xx(fogdensity) // USDF keywords xx(Amount) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 87db324ccd..20313785a0 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -85,6 +85,7 @@ #include "a_pickups.h" #include "a_armor.h" #include "a_ammo.h" +#include "r_data/colormaps.h" extern FILE *Logfile; @@ -4411,6 +4412,11 @@ enum EACSFunctions ACSF_SetActorFlag, ACSF_SetTranslation, + + // OpenGL stuff + ACSF_SetSectorGlow = 400, + ACSF_SetFogDensity, + // ZDaemon ACSF_GetTeamScore = 19620, // (int team) ACSF_SetTeamScore, // (int team, int value @@ -6065,6 +6071,38 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) return 1; } + // OpenGL exclusive functions + case ACSF_SetSectorGlow: + { + int which = !!args[1]; + PalEntry color(args[2], args[3], args[4]); + float height = float(args[5]); + if (args[2] == -1) color = -1; + + FSectorTagIterator it(args[0]); + int s; + while ((s = it.Next()) >= 0) + { + sectors[s].planes[which].GlowColor = color; + sectors[s].planes[which].GlowHeight = height; + } + break; + } + + case ACSF_SetFogDensity: + { + FSectorTagIterator it(args[0]); + int s; + int d = clamp(args[1]/2, 0, 255); + while ((s = it.Next()) >= 0) + { + auto f = sectors[s].ColorMap->Fade; + sectors[s].ColorMap = GetSpecialLights(sectors[s].ColorMap->Color, PalEntry(d, f.r, f.g, f.b), sectors[s].ColorMap->Desaturate); + } + break; + } + + default: break; } diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 15d1b48d3b..b0427045c4 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1279,8 +1279,9 @@ public: void ParseSector(sector_t *sec, int index) { - int lightcolor = -1; - int fadecolor = -1; + PalEntry lightcolor = -1; + PalEntry fadecolor = -1; + int fogdensity = -1; int desaturation = -1; int fplaneflags = 0, cplaneflags = 0; double fp[4] = { 0 }, cp[4] = { 0 }; @@ -1461,6 +1462,10 @@ public: desaturation = int(255*CheckFloat(key)); continue; + case NAME_fogdensity: + fogdensity = clamp(CheckInt(key), 0, 511); + break; + case NAME_Silent: Flag(sec->Flags, SECF_SILENT, key); continue; @@ -1682,7 +1687,7 @@ public: sec->ceilingplane.set(n.X, n.Y, n.Z, cp[3]); } - if (lightcolor == -1 && fadecolor == -1 && desaturation == -1) + if (lightcolor == -1 && fadecolor == -1 && desaturation == -1 && fogdensity == -1) { // [RH] Sectors default to white light with the default fade. // If they are outside (have a sky ceiling), they use the outside fog. @@ -1710,6 +1715,8 @@ public: fadecolor = level.fadeto; } if (desaturation == -1) desaturation = NormalLight.Desaturate; + if (fogdensity != -1) fadecolor.a = fogdensity / 2; + else fadecolor.a = 0; sec->ColorMap = GetSpecialLights (lightcolor, fadecolor, desaturation); } diff --git a/src/r_data/colormaps.h b/src/r_data/colormaps.h index 09006fc1e9..9db564b604 100644 --- a/src/r_data/colormaps.h +++ b/src/r_data/colormaps.h @@ -17,6 +17,7 @@ struct FDynamicColormap void ChangeFade (PalEntry fadecolor); void ChangeColor (PalEntry lightcolor, int desaturate); void ChangeColorFade (PalEntry lightcolor, PalEntry fadecolor); + void ChangeFogDensity(int newdensity); void BuildLights (); static void RebuildAllLights();