diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index 112e54bfc..797d092ef 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -216,13 +216,20 @@ Note: All fields default to false unless mentioned otherwise. 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. 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. + // a light level of 0. (OpenGL only) + floorglowcolor = ; // Sector's floor glow color as RRGGBB value, default = 'use texture's definition'. Set to -1 to disable glowing. (OpenGL 3.x and newer only) + floorglowheight = ; // Height of floor glow. This only has an effect for the sector's own glow color, but not for a texture based glow. (OpenGL 3.x and newer only) + ceilingglowcolor = ; // Sector's ceiling glow color as RRGGBB value, default = 'use texture's definition'. Set to -1 to disable glowing. (OpenGL 3.x and newer only) + ceilingglowheight = ; // Height of ceiling glow. This only has an effect for the sector's own glow color, but not for a texture based glow. (OpenGL 3.x and newer only) + color_floor = ; // Material color of sector's floor (OpenGL only, dynamic lighting only works properly in OpenGL 3.x and later) Default is white (0xffffff) + color_ceiling = ; // Material color of sector's ceiling (OpenGL only, dynamic lighting only works properly in OpenGL 3.x and later) Default is white (0xffffff) + color_walltop = ; // Material color of top of sector's sidedefs (OpenGL only, dynamic lighting only works properly in OpenGL 3.x and later, + in OpenGL 2.x this will define the entire wall's color) Default is white (0xffffff) + color_wallbottom = ; // Material color of bottom of sector's sidedefs (OpenGL 3.x and later only) Default is white (0xffffff) + color_sprites = ; // Material color of sprites in sector (OpenGL only.) Default is white (0xffffff) + portal_ceil_blocksound = // ceiling portal blocks sound. portal_ceil_disabled = // ceiling portal disabled. @@ -413,9 +420,12 @@ Added 'moreids' for linedefs and sectors. added clarification about character encoding added sector damage properties. -1.27 05.01.2016 +1.27 05.01.2017 floor_reflect and ceiling_reflect. +1.28 28.01.2017 +sector material colors. + =============================================================================== EOF =============================================================================== diff --git a/src/am_map.cpp b/src/am_map.cpp index f7f140f4d..fad6a13ac 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -1898,6 +1898,7 @@ void AM_drawSubsectors() double scalex, scaley; double originx, originy; FDynamicColormap *colormap; + PalEntry flatcolor; mpoint_t originpt; screen->StartSimplePolys(); @@ -1941,6 +1942,7 @@ void AM_drawSubsectors() colormap = sec->ColorMap; FTextureID maptex = sec->GetTexture(sector_t::floor); + flatcolor = sec->SpecialColors[sector_t::floor]; scalex = sec->GetXScale(sector_t::floor); scaley = sec->GetYScale(sector_t::floor); @@ -1989,6 +1991,7 @@ void AM_drawSubsectors() if (roverz < cmpz) { maptex = *(rover->top.texture); + flatcolor = *(rover->top.flatcolor); floorplane = rover->top.plane; sector_t *model = rover->top.model; int selector = (rover->flags & FF_INVERTPLANES) ? sector_t::floor : sector_t::ceiling; @@ -2049,6 +2052,7 @@ void AM_drawSubsectors() scale / scaley, rotation, colormap, + flatcolor, floorlight, f_y + f_h ); diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 5aaa402e8..20b53c8fd 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -3875,7 +3875,7 @@ void FParser::SF_SetColor(void) color.r=intvalue(t_argv[1]); color.g=intvalue(t_argv[2]); color.b=intvalue(t_argv[3]); - color.a=0; + color.a = 0; } else return; @@ -3883,7 +3883,17 @@ void FParser::SF_SetColor(void) FSSectorTagIterator itr(tagnum); while ((i = itr.Next()) >= 0) { - level.sectors[i].ColorMap = GetSpecialLights (color, level.sectors[i].ColorMap->Fade, 0); + if (!DFraggleThinker::ActiveThinker->setcolormaterial) + level.sectors[i].ColorMap = GetSpecialLights(color, level.sectors[i].ColorMap->Fade, 0); + else + { + // little hack for testing the D64 color stuff. + for (int j = 0; j < 4; j++) level.sectors[i].SpecialColors[j] = color; + // simulates 'nocoloredspritelighting' settings. + int v = (color.r + color.g + color.b) / 3; + v = (255 + v + v) / 3; + level.sectors[i].SpecialColors[sector_t::sprites] = PalEntry(255, v, v, v); + } } } } diff --git a/src/fragglescript/t_load.cpp b/src/fragglescript/t_load.cpp index b3b38543d..eb7b602bf 100644 --- a/src/fragglescript/t_load.cpp +++ b/src/fragglescript/t_load.cpp @@ -73,15 +73,18 @@ struct FFsOptions : public FOptionalMapinfoData { identifier = "fragglescript"; nocheckposition = false; + setcolormaterial = false; } virtual FOptionalMapinfoData *Clone() const { FFsOptions *newopt = new FFsOptions; newopt->identifier = identifier; newopt->nocheckposition = nocheckposition; + newopt->setcolormaterial = setcolormaterial; return newopt; } bool nocheckposition; + bool setcolormaterial; }; DEFINE_MAP_OPTION(fs_nocheckposition, false) @@ -99,6 +102,21 @@ DEFINE_MAP_OPTION(fs_nocheckposition, false) } } +DEFINE_MAP_OPTION(fs_setcolormaterial, false) +{ + FFsOptions *opt = info->GetOptData("fragglescript"); + + if (parse.CheckAssign()) + { + parse.sc.MustGetNumber(); + opt->setcolormaterial = !!parse.sc.Number; + } + else + { + opt->setcolormaterial = true; + } +} + //----------------------------------------------------------------------------- // // Process the lump to strip all unneeded information from it @@ -307,6 +325,7 @@ bool FScriptLoader::ParseInfo(MapData * map) if (opt != NULL) { DFraggleThinker::ActiveThinker->nocheckposition = opt->nocheckposition; + DFraggleThinker::ActiveThinker->setcolormaterial = opt->setcolormaterial; } } diff --git a/src/fragglescript/t_script.h b/src/fragglescript/t_script.h index 7a5c21a10..6172c352a 100644 --- a/src/fragglescript/t_script.h +++ b/src/fragglescript/t_script.h @@ -695,6 +695,7 @@ public: TObjPtr RunningScripts; TArray > SpawnedThings; bool nocheckposition; + bool setcolormaterial; DFraggleThinker(); void OnDestroy() override; diff --git a/src/gl/renderer/gl_2ddrawer.cpp b/src/gl/renderer/gl_2ddrawer.cpp index ba78634a3..1907edeef 100644 --- a/src/gl/renderer/gl_2ddrawer.cpp +++ b/src/gl/renderer/gl_2ddrawer.cpp @@ -174,7 +174,7 @@ void F2DDrawer::AddTexture(FTexture *img, DrawParms &parms) void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, - DAngle rotation, FDynamicColormap *colormap, int lightlevel) + DAngle rotation, FDynamicColormap *colormap, PalEntry flatcolor, int lightlevel) { FMaterial *gltexture = FMaterial::ValidateTexture(texture, false); @@ -191,6 +191,7 @@ void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints, poly.mLightLevel = lightlevel; poly.mVertCount = npoints; poly.mVertIndex = (int)mVertices.Reserve(npoints); + poly.mFlatColor = flatcolor; bool dorotate = rotation != 0; @@ -438,8 +439,10 @@ void F2DDrawer::Draw() cm = dsp->mColormap; gl_SetColor(dsp->mLightLevel, 0, cm, 1.f); gl_RenderState.SetMaterial(dsp->mTexture, CLAMP_NONE, 0, -1, false); + gl_RenderState.SetObjectColor(dsp->mFlatColor|0xff000000); gl_RenderState.Apply(); glDrawArrays(GL_TRIANGLE_FAN, dsp->mVertIndex, dsp->mVertCount); + gl_RenderState.SetObjectColor(0xffffffff); break; } diff --git a/src/gl/renderer/gl_2ddrawer.h b/src/gl/renderer/gl_2ddrawer.h index 8c27f13d8..61f3153d3 100644 --- a/src/gl/renderer/gl_2ddrawer.h +++ b/src/gl/renderer/gl_2ddrawer.h @@ -45,6 +45,7 @@ class F2DDrawer : public FSimpleVertexBuffer FMaterial *mTexture; int mLightLevel; FDynamicColormap *mColormap; + PalEntry mFlatColor; }; TArray mVertices; @@ -61,7 +62,7 @@ public: void AddPoly(FTexture *texture, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, - DAngle rotation, FDynamicColormap *colormap, int lightlevel); + DAngle rotation, FDynamicColormap *colormap, PalEntry flatcolor, int lightlevel); void AddLine(int x1, int y1, int x2, int y2, int palcolor, uint32 color); void AddPixel(int x1, int y1, int palcolor, uint32 color); diff --git a/src/gl/renderer/gl_lightdata.cpp b/src/gl/renderer/gl_lightdata.cpp index 3ba557737..b0dccbcba 100644 --- a/src/gl/renderer/gl_lightdata.cpp +++ b/src/gl/renderer/gl_lightdata.cpp @@ -304,6 +304,11 @@ float gl_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity) // uses approximations of Legacy's default settings. density = fogdensity ? fogdensity : 18; } + else if (sectorfogdensity != 0) + { + // case 2: Sector has an explicit fog density set. + density = sectorfogdensity; + } else if ((fogcolor.d & 0xffffff) == 0) { // case 1: black fog @@ -316,11 +321,6 @@ float gl_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity) density = 0; } } - else if (sectorfogdensity != 0) - { - // case 2: Sector has an explicit fog density set. - density = sectorfogdensity; - } else if (outsidefogdensity != 0 && outsidefogcolor.a != 0xff && (fogcolor.d & 0xffffff) == (outsidefogcolor.d & 0xffffff)) { // case 3. outsidefogdensity has already been set as needed diff --git a/src/gl/renderer/gl_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index c504088f4..72121d338 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -135,12 +135,14 @@ CUSTOM_CVAR(Float, gl_ssao_exponent, 1.8f, 0) CUSTOM_CVAR(Float, gl_paltonemap_powtable, 2.0f, CVAR_ARCHIVE | CVAR_NOINITCALL) { - GLRenderer->ClearTonemapPalette(); + if (GLRenderer) + GLRenderer->ClearTonemapPalette(); } CUSTOM_CVAR(Bool, gl_paltonemap_reverselookup, true, CVAR_ARCHIVE | CVAR_NOINITCALL) { - GLRenderer->ClearTonemapPalette(); + if (GLRenderer) + GLRenderer->ClearTonemapPalette(); } diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index 869b46d2d..95739e86d 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -216,7 +216,7 @@ public: void FillSimplePoly(FTexture *texture, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, - DAngle rotation, FDynamicColormap *colormap, int lightlevel, int bottomclip); + DAngle rotation, FDynamicColormap *colormap, PalEntry flatcolor, int lightlevel, int bottomclip); int PTM_BestColor (const uint32 *pal_in, int r, int g, int b, int first, int num); diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 429f69c34..c3c884013 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -72,6 +72,7 @@ void FRenderState::Reset() mModelMatrixEnabled = false; mTextureMatrixEnabled = false; mObjectColor = 0xffffffff; + mObjectColor2 = 0; mVertexBuffer = mCurrentVertexBuffer = NULL; mColormapState = CM_DEFAULT; mSoftLight = 0; @@ -144,6 +145,8 @@ bool FRenderState::ApplyShader() glVertexAttrib4fv(VATTR_COLOR, mColor.vec); glVertexAttrib4fv(VATTR_NORMAL, mNormal.vec); + //activeShader->muObjectColor2.Set(mObjectColor2); + activeShader->muObjectColor2.Set(mObjectColor2); activeShader->muDesaturation.Set(mDesaturation / 255.f); activeShader->muFogEnabled.Set(fogset); @@ -166,8 +169,6 @@ bool FRenderState::ApplyShader() { activeShader->muGlowTopColor.Set(mGlowTop.vec); activeShader->muGlowBottomColor.Set(mGlowBottom.vec); - activeShader->muGlowTopPlane.Set(mGlowTopPlane.vec); - activeShader->muGlowBottomPlane.Set(mGlowBottomPlane.vec); activeShader->currentglowstate = 1; } else if (activeShader->currentglowstate) @@ -175,10 +176,13 @@ bool FRenderState::ApplyShader() // if glowing is on, disable it. activeShader->muGlowTopColor.Set(nulvec); activeShader->muGlowBottomColor.Set(nulvec); - activeShader->muGlowTopPlane.Set(nulvec); - activeShader->muGlowBottomPlane.Set(nulvec); activeShader->currentglowstate = 0; } + if (mGlowEnabled || mObjectColor2.a != 0) + { + activeShader->muGlowTopPlane.Set(mGlowTopPlane.vec); + activeShader->muGlowBottomPlane.Set(mGlowBottomPlane.vec); + } if (mSplitEnabled) { diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 76e2c791c..2bef2ff91 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -106,6 +106,7 @@ class FRenderState FStateVec4 mClipLine; PalEntry mFogColor; PalEntry mObjectColor; + PalEntry mObjectColor2; FStateVec4 mDynColor; float mClipSplit[2]; @@ -381,6 +382,11 @@ public: mObjectColor = pe; } + void SetObjectColor2(PalEntry pe) + { + mObjectColor2 = pe; + } + void SetFog(PalEntry c, float d) { const float LOG2E = 1.442692f; // = 1/log(2) diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index c4296c50d..1ed0fecfa 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -379,6 +379,7 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG case GLPASS_ALL: // Same, but also creates the dynlight data. gl_SetColor(lightlevel, rel, Colormap,1.0f); gl_SetFog(lightlevel, rel, &Colormap, false); + gl_RenderState.SetObjectColor(FlatColor | 0xff000000); if (sector->special != GLSector_Skybox) { gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false); @@ -391,6 +392,7 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG gl_RenderState.SetMaterial(gltexture, CLAMP_XY, 0, -1, false); DrawSkyboxSector(pass, (pass == GLPASS_ALL || dynlightindex > -1)); } + gl_RenderState.SetObjectColor(0xffffffff); break; case GLPASS_LIGHTSONLY: @@ -404,7 +406,8 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE); gl_SetColor(lightlevel, rel, Colormap, alpha); gl_SetFog(lightlevel, rel, &Colormap, false); - if (!gltexture) + gl_RenderState.SetObjectColor(FlatColor | 0xff000000); + if (!gltexture) { gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); gl_RenderState.EnableTexture(false); @@ -421,6 +424,7 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG gl_RenderState.EnableTextureMatrix(false); } if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gl_RenderState.SetObjectColor(0xffffffff); break; case GLPASS_LIGHTTEX: @@ -546,8 +550,16 @@ void GLFlat::SetFrom3DFloor(F3DFloor *rover, bool top, bool underside) lightlist_t *light = P_GetPlaneLight(sector, plane.plane, underside); lightlevel = gl_ClampLight(*light->p_lightlevel); - if (rover->flags & FF_FOG) Colormap.LightColor = (light->extra_colormap)->Fade; - else Colormap.CopyFrom3DLight(light); + if (rover->flags & FF_FOG) + { + Colormap.LightColor = (light->extra_colormap)->Fade; + FlatColor = 0xffffffff; + } + else + { + Colormap.CopyFrom3DLight(light); + FlatColor = *plane.flatcolor; + } alpha = rover->alpha/255.0f; @@ -604,6 +616,7 @@ void GLFlat::ProcessSector(sector_t * frontsector) lightlevel = gl_ClampLight(frontsector->GetFloorLight()); Colormap = frontsector->ColorMap; + FlatColor = frontsector->SpecialColors[sector_t::floor]; port = frontsector->ValidatePortal(sector_t::floor); if ((stack = (port != NULL))) { @@ -663,6 +676,7 @@ void GLFlat::ProcessSector(sector_t * frontsector) lightlevel = gl_ClampLight(frontsector->GetCeilingLight()); Colormap = frontsector->ColorMap; + FlatColor = frontsector->SpecialColors[sector_t::ceiling]; port = frontsector->ValidatePortal(sector_t::ceiling); if ((stack = (port != NULL))) { diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 9ca52e18f..af8cbf18e 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -309,6 +309,7 @@ void GLSprite::Draw(int pass) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_sprite_threshold); gl_RenderState.SetColor(0.2f,0.2f,0.2f,fuzzalpha, Colormap.desaturation); additivefog = true; + lightlist = nullptr; // the fuzz effect does not use the sector's light level so splitting is not needed. } else if (RenderStyle.BlendOp == STYLEOP_Add && RenderStyle.DestAlpha == STYLEALPHA_One) { @@ -320,15 +321,21 @@ void GLSprite::Draw(int pass) glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-1.0f, -128.0f); } - if (RenderStyle.BlendOp!=STYLEOP_Shadow) + if (RenderStyle.BlendOp != STYLEOP_Shadow) { if (gl_lights && GLRenderer->mLightCount && !gl_fixedcolormap && !fullbright) { gl_SetDynSpriteLight(gl_light_sprites ? actor : NULL, gl_light_particles ? particle : NULL); } + PalEntry finalcol(ThingColor.a, + ThingColor.r * actor->Sector->SpecialColors[sector_t::sprites].r / 255, + ThingColor.g * actor->Sector->SpecialColors[sector_t::sprites].g / 255, + ThingColor.b * actor->Sector->SpecialColors[sector_t::sprites].b / 255); + + gl_RenderState.SetObjectColor(finalcol); gl_SetColor(lightlevel, rel, Colormap, trans); } - gl_RenderState.SetObjectColor(ThingColor); + if (gl_isBlack(Colormap.FadeColor)) foglevel=lightlevel; diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 902517a9b..151a5ef71 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -301,6 +301,7 @@ public: FMaterial *gltexture; FColormap Colormap; // light and fog + PalEntry FlatColor; ERenderStyle renderstyle; float alpha; diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 7849114ff..34a4cc282 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -24,6 +24,7 @@ #include "p_local.h" #include "p_lnspec.h" #include "a_sharedglobal.h" +#include "g_levellocals.h" #include "gl/gl_functions.h" #include "gl/system/gl_interface.h" @@ -326,9 +327,9 @@ void GLWall::RenderTextured(int rflags) if (flags & GLWF_GLOW) { gl_RenderState.EnableGlow(true); - gl_RenderState.SetGlowPlanes(topplane, bottomplane); gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor); } + gl_RenderState.SetGlowPlanes(topplane, bottomplane); gl_RenderState.SetMaterial(gltexture, flags & 3, 0, -1, false); if (type == RENDERWALL_M2SNF) @@ -339,12 +340,14 @@ void GLWall::RenderTextured(int rflags) } gl_SetFog(255, 0, NULL, false); } + gl_RenderState.SetObjectColor(seg->frontsector->SpecialColors[sector_t::walltop] | 0xff000000); + gl_RenderState.SetObjectColor2(seg->frontsector->SpecialColors[sector_t::wallbottom] | 0xff000000); float absalpha = fabsf(alpha); if (lightlist == NULL) { - gl_SetColor(lightlevel, rel, Colormap, absalpha); if (type != RENDERWALL_M2SNF) gl_SetFog(lightlevel, rel, &Colormap, RenderStyle == STYLE_Add); + gl_SetColor(lightlevel, rel, Colormap, absalpha); RenderWall(rflags); } else @@ -374,6 +377,8 @@ void GLWall::RenderTextured(int rflags) gl_RenderState.EnableSplit(false); } + gl_RenderState.SetObjectColor(0xffffffff); + gl_RenderState.SetObjectColor2(0); gl_RenderState.SetTextureMode(tmode); gl_RenderState.EnableGlow(false); } diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index d53e252e3..62a051e58 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -370,7 +370,12 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) // now draw the different layers of the weapon gl_RenderState.EnableBrightmap(true); - gl_RenderState.SetObjectColor(ThingColor); + PalEntry finalcol(ThingColor.a, + ThingColor.r * viewsector->SpecialColors[sector_t::sprites].r / 255, + ThingColor.g * viewsector->SpecialColors[sector_t::sprites].g / 255, + ThingColor.b * viewsector->SpecialColors[sector_t::sprites].b / 255); + + gl_RenderState.SetObjectColor(finalcol); gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_sprite_threshold); // hack alert! Rather than changing everything in the underlying lighting code let's just temporarily change diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index ef512faea..421139050 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -225,6 +225,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * muFogColor.Init(hShader, "uFogColor"); muDynLightColor.Init(hShader, "uDynLightColor"); muObjectColor.Init(hShader, "uObjectColor"); + muObjectColor2.Init(hShader, "uObjectColor2"); muGlowBottomColor.Init(hShader, "uGlowBottomColor"); muGlowTopColor.Init(hShader, "uGlowTopColor"); muGlowBottomPlane.Init(hShader, "uGlowBottomPlane"); diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index f9eb5c292..e8012aa5d 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -271,6 +271,7 @@ class FShader FBufferedUniformPE muFogColor; FBufferedUniform4f muDynLightColor; FBufferedUniformPE muObjectColor; + FBufferedUniformPE muObjectColor2; FUniform4f muGlowBottomColor; FUniform4f muGlowTopColor; FUniform4f muGlowBottomPlane; diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 6d4fdcff8..1a4582d80 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -470,11 +470,11 @@ void OpenGLFrameBuffer::Clear(int left, int top, int right, int bottom, int palc void OpenGLFrameBuffer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, - DAngle rotation, FDynamicColormap *colormap, int lightlevel, int bottomclip) + DAngle rotation, FDynamicColormap *colormap, PalEntry flatcolor, int lightlevel, int bottomclip) { if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr && npoints >= 3) { - GLRenderer->m2DDrawer->AddPoly(texture, points, npoints, originx, originy, scalex, scaley, rotation, colormap, lightlevel); + GLRenderer->m2DDrawer->AddPoly(texture, points, npoints, originx, originy, scalex, scaley, rotation, colormap, flatcolor, lightlevel); } } diff --git a/src/gl/system/gl_framebuffer.h b/src/gl/system/gl_framebuffer.h index 27c3d1cf9..0eb289ffe 100644 --- a/src/gl/system/gl_framebuffer.h +++ b/src/gl/system/gl_framebuffer.h @@ -71,7 +71,7 @@ public: void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, - DAngle rotation, FDynamicColormap *colormap, int lightlevel, int bottomclip); + DAngle rotation, FDynamicColormap *colormap, PalEntry flatcolor, int lightlevel, int bottomclip); FNativePalette *CreatePalette(FRemapTable *remap); diff --git a/src/namedef.h b/src/namedef.h index 731947da7..ef7f1c58d 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -549,6 +549,11 @@ xx(Lightceilingabsolute) xx(Gravity) xx(Lightcolor) xx(Fadecolor) +xx(Color_Floor) +xx(Color_Ceiling) +xx(Color_Walltop) +xx(Color_Wallbottom) +xx(Color_Sprites) xx(Desaturation) xx(SoundSequence) xx(Silent) diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index 102ed57b0..77e34adba 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -136,12 +136,14 @@ static void P_Add3DFloor(sector_t* sec, sector_t* sec2, line_t* master, int flag { ffloor->bottom.plane = &sec2->floorplane; ffloor->bottom.texture = &sec2->planes[sector_t::floor].Texture; + ffloor->bottom.flatcolor = &sec2->SpecialColors[sector_t::floor]; ffloor->bottom.isceiling = sector_t::floor; } else { ffloor->bottom.plane = &sec2->ceilingplane; ffloor->bottom.texture = &sec2->planes[sector_t::ceiling].Texture; + ffloor->bottom.flatcolor = &sec2->SpecialColors[sector_t::ceiling]; ffloor->bottom.isceiling = sector_t::ceiling; } @@ -149,6 +151,7 @@ static void P_Add3DFloor(sector_t* sec, sector_t* sec2, line_t* master, int flag { ffloor->top.plane = &sec2->ceilingplane; ffloor->top.texture = &sec2->planes[sector_t::ceiling].Texture; + ffloor->top.flatcolor = &sec2->SpecialColors[sector_t::ceiling]; ffloor->toplightlevel = &sec2->lightlevel; ffloor->top.isceiling = sector_t::ceiling; } @@ -156,6 +159,7 @@ static void P_Add3DFloor(sector_t* sec, sector_t* sec2, line_t* master, int flag { ffloor->top.plane = &sec->floorplane; ffloor->top.texture = &sec2->planes[sector_t::floor].Texture; + ffloor->top.flatcolor = &sec2->SpecialColors[sector_t::floor]; ffloor->toplightlevel = &sec->lightlevel; ffloor->top.isceiling = sector_t::floor; ffloor->top.model = sec; @@ -165,10 +169,7 @@ static void P_Add3DFloor(sector_t* sec, sector_t* sec2, line_t* master, int flag if (flags&FF_INVERTSECTOR) { // switch the planes - F3DFloor::planeref sp = ffloor->top; - - ffloor->top=ffloor->bottom; - ffloor->bottom=sp; + std::swap(ffloor->top, ffloor->bottom); if (flags&FF_SWIMMABLE) { @@ -192,11 +193,10 @@ static void P_Add3DFloor(sector_t* sec, sector_t* sec2, line_t* master, int flag ffloor->flags &= ~FF_ADDITIVETRANS; } - if(flags & FF_THISINSIDE) { + if(flags & FF_THISINSIDE) + { // switch the planes - F3DFloor::planeref sp = ffloor->top; - ffloor->top=ffloor->bottom; - ffloor->bottom=sp; + std::swap(ffloor->top, ffloor->bottom); } sec->e->XFloor.ffloors.Push(ffloor); diff --git a/src/p_3dfloors.h b/src/p_3dfloors.h index fc784c55c..75b8656e4 100644 --- a/src/p_3dfloors.h +++ b/src/p_3dfloors.h @@ -69,6 +69,7 @@ struct F3DFloor secplane_t * plane; const FTextureID * texture; sector_t * model; + PalEntry * flatcolor; int isceiling; int vindex; bool copied; diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 7a660129b..8f465e081 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -276,6 +276,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, sector_t &p, sector_t ("linked_floor", p.e->Linked.Floor.Sectors) ("linked_ceiling", p.e->Linked.Ceiling.Sectors) ("colormap", p.ColorMap, def->ColorMap) + .Array("specialcolors", p.SpecialColors, def->SpecialColors, 5, true) ("gravity", p.gravity, def->gravity) .Terrain("floorterrain", p.terrainnum[0], &def->terrainnum[0]) .Terrain("ceilingterrain", p.terrainnum[1], &def->terrainnum[1]) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index b94e12b9b..e2dee7cf1 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1504,6 +1504,7 @@ void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex) ss->SeqName = NAME_None; ss->nextsec = -1; //jff 2/26/98 add fields to support locking out ss->prevsec = -1; // stair retriggering until build completes + memset(ss->SpecialColors, -1, sizeof(ss->SpecialColors)); ss->SetAlpha(sector_t::floor, 1.); ss->SetAlpha(sector_t::ceiling, 1.); diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index b0c9dbc15..6c732d67f 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1307,6 +1307,7 @@ public: sec->sectornum = index; sec->damageinterval = 32; sec->terrainnum[sector_t::ceiling] = sec->terrainnum[sector_t::floor] = -1; + memset(sec->SpecialColors, -1, sizeof(sec->SpecialColors)); if (floordrop) sec->Flags = SECF_FLOORDROP; // killough 3/7/98: end changes @@ -1459,6 +1460,26 @@ public: fadecolor = CheckInt(key); continue; + case NAME_Color_Floor: + sec->SpecialColors[sector_t::floor] = CheckInt(key) || 0xff000000; + break; + + case NAME_Color_Ceiling: + sec->SpecialColors[sector_t::ceiling] = CheckInt(key) || 0xff000000; + break; + + case NAME_Color_Walltop: + sec->SpecialColors[sector_t::walltop] = CheckInt(key) || 0xff000000; + break; + + case NAME_Color_Wallbottom: + sec->SpecialColors[sector_t::wallbottom] = CheckInt(key) || 0xff000000; + break; + + case NAME_Color_Sprites: + sec->SpecialColors[sector_t::sprites] = CheckInt(key) || 0xff000000; + break; + case NAME_Desaturation: desaturation = int(255*CheckFloat(key)); continue; diff --git a/src/r_defs.h b/src/r_defs.h index 3c38f285d..b888864b4 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -660,10 +660,15 @@ public: FSectorPortal *ValidatePortal(int which); void CheckPortalPlane(int plane); + enum { floor, - ceiling + ceiling, + // only used for specialcolors array + walltop, + wallbottom, + sprites }; struct splane @@ -961,6 +966,7 @@ public: // [RH] give floor and ceiling even more properties FDynamicColormap *ColorMap; // [RH] Per-sector colormap + PalEntry SpecialColors[5]; TObjPtr SoundTarget; diff --git a/src/scripting/codegeneration/codegen.cpp b/src/scripting/codegeneration/codegen.cpp index d090fa6e4..8fd95c411 100644 --- a/src/scripting/codegeneration/codegen.cpp +++ b/src/scripting/codegeneration/codegen.cpp @@ -8202,14 +8202,16 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx) { // only cast implicit-string types for vararg, leave everything else as-is // this was outright copypasted from FxFormat - ArgList[i] = ArgList[i]->Resolve(ctx); - if (ArgList[i]->ValueType == TypeName || - ArgList[i]->ValueType == TypeSound) + x = ArgList[i]->Resolve(ctx); + if (x) { - x = new FxStringCast(ArgList[i]); - x = x->Resolve(ctx); + if (x->ValueType == TypeName || + x->ValueType == TypeSound) + { + x = new FxStringCast(ArgList[i]); + x = x->Resolve(ctx); + } } - else x = ArgList[i]; } else if (!(flag & (VARF_Ref|VARF_Out))) { diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 3d4954ed2..9db885efb 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -1272,7 +1272,7 @@ void DCanvas::FinishSimplePolys() void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, DAngle rotation, - FDynamicColormap *colormap, int lightlevel, int bottomclip) + FDynamicColormap *colormap, PalEntry flatcolor, int lightlevel, int bottomclip) { #ifndef NO_SWRENDER using namespace swrenderer; diff --git a/src/v_video.h b/src/v_video.h index 57d15869c..e9bb1f6a4 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -224,7 +224,7 @@ public: // Fill a simple polygon with a texture virtual void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, DAngle rotation, - struct FDynamicColormap *colormap, int lightlevel, int bottomclip); + struct FDynamicColormap *colormap, PalEntry flatcolor, int lightlevel, int bottomclip); // Set an area to a specified color virtual void Clear (int left, int top, int right, int bottom, int palcolor, uint32 color); diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index 026bbc63b..4d758783e 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -3092,7 +3092,7 @@ void D3DFB::FlatFill(int left, int top, int right, int bottom, FTexture *src, bo void D3DFB::FillSimplePoly(FTexture *texture, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, - DAngle rotation, FDynamicColormap *colormap, int lightlevel, int bottomclip) + DAngle rotation, FDynamicColormap *colormap, PalEntry flatcolor, int lightlevel, int bottomclip) { // Use an equation similar to player sprites to determine shade double fadelevel = clamp((LIGHT2SHADE(lightlevel)/65536. - 12) / NUMCOLORMAPS, 0.0, 1.0); @@ -3113,7 +3113,7 @@ void D3DFB::FillSimplePoly(FTexture *texture, FVector2 *points, int npoints, } if (In2D < 2) { - Super::FillSimplePoly(texture, points, npoints, originx, originy, scalex, scaley, rotation, colormap, lightlevel, bottomclip); + Super::FillSimplePoly(texture, points, npoints, originx, originy, scalex, scaley, rotation, colormap, flatcolor, lightlevel, bottomclip); return; } if (!InScene) diff --git a/src/win32/win32iface.h b/src/win32/win32iface.h index b5262089b..a92672ad7 100644 --- a/src/win32/win32iface.h +++ b/src/win32/win32iface.h @@ -265,7 +265,7 @@ public: void DrawPixel(int x, int y, int palcolor, uint32 rgbcolor); void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, - DAngle rotation, FDynamicColormap *colormap, int lightlevel, int bottomclip) override; + DAngle rotation, FDynamicColormap *colormap, PalEntry flatcolor, int lightlevel, int bottomclip) override; bool WipeStartScreen(int type); void WipeEndScreen(); bool WipeDo(int ticks); diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 145f76964..a6bc6bbd7 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -1,5 +1,5 @@ in vec4 pixelpos; -in vec2 glowdist; +in vec3 glowdist; in vec4 vWorldNormal; in vec4 vEyeNormal; @@ -89,7 +89,8 @@ vec4 getTexel(vec2 st) } break; } - texel *= uObjectColor; + if (uObjectColor2.a == 0) texel *= uObjectColor; + else texel *= mix(uObjectColor, uObjectColor2, glowdist.z); return desaturate(texel); } diff --git a/wadsrc/static/shaders/glsl/main.vp b/wadsrc/static/shaders/glsl/main.vp index 1de8854c0..f66ee7b04 100644 --- a/wadsrc/static/shaders/glsl/main.vp +++ b/wadsrc/static/shaders/glsl/main.vp @@ -6,7 +6,7 @@ in vec4 aColor; in vec4 aVertex2; in vec4 aNormal; out vec4 pixelpos; -out vec2 glowdist; +out vec3 glowdist; out vec4 vWorldNormal; out vec4 vEyeNormal; @@ -50,9 +50,12 @@ void main() pixelpos.xyz = worldcoord.xyz; pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w; - glowdist.x = -((uGlowTopPlane.w + uGlowTopPlane.x * worldcoord.x + uGlowTopPlane.y * worldcoord.z) * uGlowTopPlane.z) - worldcoord.y; - glowdist.y = worldcoord.y + ((uGlowBottomPlane.w + uGlowBottomPlane.x * worldcoord.x + uGlowBottomPlane.y * worldcoord.z) * uGlowBottomPlane.z); - + float topatpoint = -((uGlowTopPlane.w + uGlowTopPlane.x * worldcoord.x + uGlowTopPlane.y * worldcoord.z) * uGlowTopPlane.z); + float bottomatpoint = -((uGlowBottomPlane.w + uGlowBottomPlane.x * worldcoord.x + uGlowBottomPlane.y * worldcoord.z) * uGlowBottomPlane.z); + glowdist.x = topatpoint - worldcoord.y; + glowdist.y = worldcoord.y - bottomatpoint; + glowdist.z = clamp(glowdist.x / (topatpoint - bottomatpoint), 0.0, 1.0); + if (uSplitBottomPlane.z != 0.0) { gl_ClipDistance[3] = -((uSplitTopPlane.w + uSplitTopPlane.x * worldcoord.x + uSplitTopPlane.y * worldcoord.z) * uSplitTopPlane.z) - worldcoord.y; diff --git a/wadsrc/static/shaders/glsl/shaderdefs.i b/wadsrc/static/shaders/glsl/shaderdefs.i index 2099427d5..c109c8524 100644 --- a/wadsrc/static/shaders/glsl/shaderdefs.i +++ b/wadsrc/static/shaders/glsl/shaderdefs.i @@ -15,6 +15,7 @@ uniform float uAlphaThreshold; // colors uniform vec4 uObjectColor; +uniform vec4 uObjectColor2; uniform vec4 uDynLightColor; uniform vec4 uFogColor; uniform float uDesaturationFactor;