From 02c3b3613fef339a70e26452156292297454e7c2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 28 Dec 2016 21:35:42 +0100 Subject: [PATCH] - added UDMF properties to set glows per sector. - for explicitly defined glows, use the one for the current animation frame, if an animated texture is active. For default glows it will still use the base texture's to avoid inconsistencies. --- specs/udmf_zdoom.txt | 5 +- src/gl/dynlights/gl_glow.cpp | 109 ++++++++++++++++++++++++++++++++--- src/gl/dynlights/gl_glow.h | 1 + src/gl/scene/gl_wall.h | 1 - src/gl/scene/gl_walls.cpp | 39 ++----------- src/namedef.h | 4 ++ src/p_saveg.cpp | 2 + src/r_defs.h | 8 ++- src/textures/textures.h | 1 + 9 files changed, 121 insertions(+), 49 deletions(-) diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index 3499500ee6..8a96a3ecf7 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -214,9 +214,12 @@ Note: All fields default to false unless mentioned otherwise. damagehazard = ; // Changes damage model to Strife's delayed damage for the given sector. Default = false. floorterrain = ; // Sets the terrain for the sector's floor. Default = 'use the flat texture's terrain definition.' ceilingterrain = ; // Sets the terrain for the sector's ceiling. Default = 'use the flat texture's terrain definition.' - floor_reflect = ; // reflectiveness of floor (OpenGL only, not functional on sloped sectors) ceiling_reflect = ; // reflectiveness of ceiling (OpenGL only, not functional on sloped sectors) + floorglowcolor = ; // Sector's floor glow color as RRGGBB value, default = 'use texture's definition'. Set to -1 to disable glowing. + 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. portal_ceil_alpha = // translucency of ceiling portal (default is 0 (not visible)) portal_ceil_blocksound = // ceiling portal blocks sound. diff --git a/src/gl/dynlights/gl_glow.cpp b/src/gl/dynlights/gl_glow.cpp index eacbfa9535..e0ed6d0f66 100644 --- a/src/gl/dynlights/gl_glow.cpp +++ b/src/gl/dynlights/gl_glow.cpp @@ -52,7 +52,7 @@ void gl_InitGlow(FScanner &sc) sc.MustGetString(); FTextureID flump=TexMan.CheckForTexture(sc.String, FTexture::TEX_Flat,FTextureManager::TEXMAN_TryAny); FTexture *tex = TexMan[flump]; - if (tex) tex->gl_info.bGlowing = tex->gl_info.bFullbright = true; + if (tex) tex->gl_info.bAutoGlowing = tex->gl_info.bGlowing = tex->gl_info.bFullbright = true; } } else if (sc.Compare("WALLS")) @@ -63,7 +63,7 @@ void gl_InitGlow(FScanner &sc) sc.MustGetString(); FTextureID flump=TexMan.CheckForTexture(sc.String, FTexture::TEX_Wall,FTextureManager::TEXMAN_TryAny); FTexture *tex = TexMan[flump]; - if (tex) tex->gl_info.bGlowing = tex->gl_info.bFullbright = true; + if (tex) tex->gl_info.bAutoGlowing = tex->gl_info.bGlowing = tex->gl_info.bFullbright = true; } } else if (sc.Compare("TEXTURE")) @@ -93,6 +93,7 @@ void gl_InitGlow(FScanner &sc) if (tex && color != 0) { + tex->gl_info.bAutoGlowing = false; tex->gl_info.bGlowing = true; tex->gl_info.GlowColor = color; } @@ -106,17 +107,39 @@ void gl_InitGlow(FScanner &sc) // Checks whether a sprite should be affected by a glow // //========================================================================== -int gl_CheckSpriteGlow(sector_t *sec, int lightlevel, const DVector3 &pos) +int gl_CheckSpriteGlow(sector_t *sector, int lightlevel, const DVector3 &pos) { - FTextureID floorpic = sec->GetTexture(sector_t::floor); - FTexture *tex = TexMan[floorpic]; - if (tex != NULL && tex->isGlowing()) + float bottomglowcolor[4]; + bottomglowcolor[3] = 0; + auto c = sector->planes[sector_t::floor].GlowColor; + if (c == 0) { - double floordiff = pos.Z - sec->floorplane.ZatPoint(pos); - if (floordiff < tex->gl_info.GlowHeight && tex->gl_info.GlowHeight != 0) + FTexture *tex = TexMan[sector->GetTexture(sector_t::floor)]; + if (tex != NULL && tex->isGlowing()) + { + if (!tex->gl_info.bAutoGlowing) tex = TexMan(sector->GetTexture(sector_t::floor)); + if (tex->isGlowing()) // recheck the current animation frame. + { + tex->GetGlowColor(bottomglowcolor); + bottomglowcolor[3] = (float)tex->gl_info.GlowHeight; + } + } + } + else if (c != -1) + { + bottomglowcolor[0] = c.r / 255.f; + bottomglowcolor[1] = c.g / 255.f; + bottomglowcolor[2] = c.b / 255.f; + bottomglowcolor[3] = sector->planes[sector_t::floor].GlowHeight; + } + + if (bottomglowcolor[3]> 0) + { + double floordiff = pos.Z - sector->floorplane.ZatPoint(pos); + if (floordiff < bottomglowcolor[3]) { int maxlight = (255 + lightlevel) >> 1; - double lightfrac = floordiff / tex->gl_info.GlowHeight; + double lightfrac = floordiff / bottomglowcolor[3]; if (lightfrac < 0) lightfrac = 0; lightlevel = int(lightfrac*lightlevel + maxlight*(1 - lightfrac)); } @@ -124,3 +147,71 @@ int gl_CheckSpriteGlow(sector_t *sec, int lightlevel, const DVector3 &pos) return lightlevel; } +//========================================================================== +// +// Checks whether a wall should glow +// +//========================================================================== +bool gl_GetWallGlow(sector_t *sector, float *topglowcolor, float *bottomglowcolor) +{ + bool ret = false; + bottomglowcolor[3] = topglowcolor[3] = 0; + auto c = sector->planes[sector_t::ceiling].GlowColor; + if (c == 0) + { + FTexture *tex = TexMan[sector->GetTexture(sector_t::ceiling)]; + if (tex != NULL && tex->isGlowing()) + { + if (!tex->gl_info.bAutoGlowing) tex = TexMan(sector->GetTexture(sector_t::ceiling)); + if (tex->isGlowing()) // recheck the current animation frame. + { + ret = true; + tex->GetGlowColor(topglowcolor); + topglowcolor[3] = (float)tex->gl_info.GlowHeight; + } + } + } + else if (c != -1) + { + topglowcolor[0] = c.r / 255.f; + topglowcolor[1] = c.g / 255.f; + topglowcolor[2] = c.b / 255.f; + topglowcolor[3] = sector->planes[sector_t::ceiling].GlowHeight; + ret = topglowcolor[3] > 0; + } + + c = sector->planes[sector_t::floor].GlowColor; + if (c == 0) + { + FTexture *tex = TexMan[sector->GetTexture(sector_t::floor)]; + if (tex != NULL && tex->isGlowing()) + { + if (!tex->gl_info.bAutoGlowing) tex = TexMan(sector->GetTexture(sector_t::floor)); + if (tex->isGlowing()) // recheck the current animation frame. + { + ret = true; + tex->GetGlowColor(bottomglowcolor); + bottomglowcolor[3] = (float)tex->gl_info.GlowHeight; + } + } + } + else if (c != -1) + { + bottomglowcolor[0] = c.r / 255.f; + bottomglowcolor[1] = c.g / 255.f; + bottomglowcolor[2] = c.b / 255.f; + bottomglowcolor[3] = sector->planes[sector_t::floor].GlowHeight; + ret = bottomglowcolor[3] > 0; + } + return ret; +} + +#include "c_dispatch.h" +#include "d_player.h" + +CCMD(setglow) +{ + auto s = players[0].mo->Sector; + s->planes[sector_t::floor].GlowHeight = 128; + s->planes[sector_t::floor].GlowColor = 0xff0000; +} \ No newline at end of file diff --git a/src/gl/dynlights/gl_glow.h b/src/gl/dynlights/gl_glow.h index 7d9ae9f7ff..eb433c9996 100644 --- a/src/gl/dynlights/gl_glow.h +++ b/src/gl/dynlights/gl_glow.h @@ -6,5 +6,6 @@ struct sector_t; void gl_InitGlow(const char * lumpnm); int gl_CheckSpriteGlow(sector_t *sec, int lightlevel, const DVector3 &pos); +bool gl_GetWallGlow(sector_t *sector, float *topglowcolor, float *bottomglowcolor); #endif diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index bdee5761fe..902517a9bf 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -174,7 +174,6 @@ public: }; - FTextureID topflat,bottomflat; secplane_t topplane, bottomplane; // we need to save these to pass them to the shader for calculating glows. // these are not the same as ytop and ybottom!!! diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index 30e10b73f8..4d258b3a03 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -48,35 +48,6 @@ #include "gl/shaders/gl_shader.h" -//========================================================================== -// -// Checks whether a wall should glow -// -//========================================================================== -void GLWall::CheckGlowing() -{ - bottomglowcolor[3] = topglowcolor[3] = 0; - if (!gl_isFullbright(Colormap.LightColor, lightlevel)) - { - FTexture *tex = TexMan[topflat]; - if (tex != NULL && tex->isGlowing()) - { - flags |= GLWall::GLWF_GLOW; - tex->GetGlowColor(topglowcolor); - topglowcolor[3] = tex->gl_info.GlowHeight; - } - - tex = TexMan[bottomflat]; - if (tex != NULL && tex->isGlowing()) - { - flags |= GLWall::GLWF_GLOW; - tex->GetGlowColor(bottomglowcolor); - bottomglowcolor[3] = tex->gl_info.GlowHeight; - } - } -} - - //========================================================================== // // @@ -111,8 +82,7 @@ void GLWall::PutWall(bool translucent) if (gltexture == NULL) return; Colormap.Clear(); } - - CheckGlowing(); + if (gl_isFullbright(Colormap.LightColor, lightlevel)) flags &= ~GLWF_GLOW; if (translucent) // translucent walls { @@ -1544,8 +1514,8 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) RenderStyle = STYLE_Normal; gltexture = NULL; - topflat = frontsector->GetTexture(sector_t::ceiling); // for glowing textures. These must be saved because - bottomflat = frontsector->GetTexture(sector_t::floor); // the sector passed here might be a temporary copy. + + if (gl_GetWallGlow(frontsector, topglowcolor, bottomglowcolor)) flags |= GLWF_GLOW; topplane = frontsector->ceilingplane; bottomplane = frontsector->floorplane; @@ -1781,8 +1751,7 @@ void GLWall::ProcessLowerMiniseg(seg_t *seg, sector_t * frontsector, sector_t * RenderStyle = STYLE_Normal; Colormap = frontsector->ColorMap; - topflat = frontsector->GetTexture(sector_t::ceiling); // for glowing textures - bottomflat = frontsector->GetTexture(sector_t::floor); + if (gl_GetWallGlow(frontsector, topglowcolor, bottomglowcolor)) flags |= GLWF_GLOW; topplane = frontsector->ceilingplane; bottomplane = frontsector->floorplane; dynlightindex = -1; diff --git a/src/namedef.h b/src/namedef.h index 61d7303a45..e08aec1e2f 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -577,6 +577,10 @@ xx(floorterrain) xx(ceilingterrain) xx(floor_reflect) xx(ceiling_reflect) +xx(floorglowcolor) +xx(floorglowheight) +xx(ceilingglowcolor) +xx(ceilingglowheight) // USDF keywords xx(Amount) diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 59e83d9e72..93ff5c72b4 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -181,6 +181,8 @@ FSerializer &Serialize(FSerializer &arc, const char *key, sector_t::splane &p, s ("texture", p.Texture, def->Texture) ("texz", p.TexZ, def->TexZ) ("alpha", p.alpha, def->alpha) + ("glowcolor", p.GlowColor, def->GlowColor) + ("glowheight", p.GlowHeight, def->GlowHeight) .EndObject(); } return arc; diff --git a/src/r_defs.h b/src/r_defs.h index da1b26cf05..ceef674352 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -687,8 +687,10 @@ public: int Flags; int Light; double alpha; - FTextureID Texture; double TexZ; + PalEntry GlowColor; + float GlowHeight; + FTextureID Texture; }; @@ -1029,11 +1031,11 @@ public: }; TObjPtr interpolations[4]; + int prevsec; // -1 or number of sector for previous step + int nextsec; // -1 or number of next step sector BYTE soundtraversed; // 0 = untraversed, 1,2 = sndlines -1 // jff 2/26/98 lockout machinery for stairbuilding SBYTE stairlock; // -2 on first locked -1 after thinker done 0 normally - int prevsec; // -1 or number of sector for previous step - int nextsec; // -1 or number of next step sector short linecount; struct line_t **lines; // [linecount] size diff --git a/src/textures/textures.h b/src/textures/textures.h index c6c59fd597..20ee5aec2e 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -315,6 +315,7 @@ public: float shaderspeed; int mIsTransparent:2; bool bGlowing:1; // Texture glows + bool bAutoGlowing : 1; // Glow info is determined from texture image. bool bFullbright:1; // always draw fullbright bool bSkybox:1; // This is a skybox char bBrightmapChecked:1; // Set to 1 if brightmap has been checked