diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index eeb3c2a560..e8d4d81f8c 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -224,12 +224,11 @@ 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. (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_floor = ; // Material color of sector's floor. Default is white (0xffffff) + color_ceiling = ; // Material color of sector's ceiling. Default is white (0xffffff) + color_walltop = ; // Material color of top of sector's sidedefs. In OpenGL 2.x and the software renderer 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) + color_sprites = ; // Material color of sprites in sector. Default is white (0xffffff) portal_ceil_blocksound = // ceiling portal blocks sound. diff --git a/src/doomtype.h b/src/doomtype.h index 432fd3dd85..5a4d3f0670 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -124,6 +124,24 @@ struct PalEntry { d = other.d & 0xffffff; } + PalEntry Modulate(PalEntry other) const + { + if (isWhite()) + { + return other; + } + else if (other.isWhite()) + { + return *this; + } + else + { + other.r = (r * other.r) / 255; + other.g = (g * other.g) / 255; + other.b = (b * other.b) / 255; + return other; + } + } bool isBlack() const { return (d & 0xffffff) == 0; diff --git a/src/polyrenderer/scene/poly_plane.cpp b/src/polyrenderer/scene/poly_plane.cpp index a897f7c693..dd17be5ebf 100644 --- a/src/polyrenderer/scene/poly_plane.cpp +++ b/src/polyrenderer/scene/poly_plane.cpp @@ -345,7 +345,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const Vec4f &clipPlan args.ccw = ccw; args.stenciltestvalue = stencilValue; args.stencilwritevalue = stencilValue + 1; - args.SetColormap(GetColorTable(frontsector->Colormap)); + args.SetColormap(GetColorTable(frontsector->Colormap, frontsector->SpecialColors[ceiling])); args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w); if (!isSky) diff --git a/src/polyrenderer/scene/poly_playersprite.cpp b/src/polyrenderer/scene/poly_playersprite.cpp index 851c57a640..78e7aa61c6 100644 --- a/src/polyrenderer/scene/poly_playersprite.cpp +++ b/src/polyrenderer/scene/poly_playersprite.cpp @@ -215,7 +215,7 @@ void RenderPolyPlayerSprites::RenderSprite(DPSprite *sprite, AActor *owner, floa bool noaccel = false; - FDynamicColormap *basecolormap = GetColorTable(viewpoint.sector->Colormap); + FDynamicColormap *basecolormap = GetColorTable(viewpoint.sector->Colormap, viewpoint.sector->SpecialColors[sector_t::sprites]); FDynamicColormap *colormap_to_use = basecolormap; int ColormapNum = 0; diff --git a/src/polyrenderer/scene/poly_sprite.cpp b/src/polyrenderer/scene/poly_sprite.cpp index 0cdb6192ed..7dd3603f19 100644 --- a/src/polyrenderer/scene/poly_sprite.cpp +++ b/src/polyrenderer/scene/poly_sprite.cpp @@ -162,7 +162,7 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, const Vec4f &clipPla args.stenciltestvalue = stencilValue; args.stencilwritevalue = stencilValue; args.SetTexture(tex, thing->Translation); - args.SetColormap(GetColorTable(sub->sector->Colormap)); + args.SetColormap(GetColorTable(sub->sector->Colormap, sub->sector->SpecialColors[sector_t::sprites])); args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w); TriBlendMode blendmode; diff --git a/src/polyrenderer/scene/poly_wall.cpp b/src/polyrenderer/scene/poly_wall.cpp index bda5f2aa8a..49c3c6b54a 100644 --- a/src/polyrenderer/scene/poly_wall.cpp +++ b/src/polyrenderer/scene/poly_wall.cpp @@ -73,7 +73,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const Vec4f &clipP wall.LineSeg = line; wall.Line = line->linedef; wall.Side = line->sidedef; - wall.Colormap = GetColorTable(frontsector->Colormap); + wall.Colormap = GetColorTable(frontsector->Colormap, frontsector->SpecialColors[sector_t::walltop]); wall.Masked = false; wall.SubsectorDepth = subsectorDepth; wall.StencilValue = stencilValue; @@ -175,7 +175,7 @@ void RenderPolyWall::Render3DFloorLine(const TriMatrix &worldToClip, const Vec4f wall.LineSeg = line; wall.Line = fakeFloor->master; wall.Side = fakeFloor->master->sidedef[0]; - wall.Colormap = GetColorTable(frontsector->Colormap); + wall.Colormap = GetColorTable(frontsector->Colormap, frontsector->SpecialColors[sector_t::walltop]); wall.Masked = false; wall.SubsectorDepth = subsectorDepth; wall.StencilValue = stencilValue; @@ -262,7 +262,7 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane args.stencilwritevalue = StencilValue + 1; if (tex) args.SetTexture(tex); - args.SetColormap(GetColorTable(Line->frontsector->Colormap)); + args.SetColormap(GetColorTable(Line->frontsector->Colormap, Line->frontsector->SpecialColors[sector_t::walltop])); args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w); //if (Side && Side->lighthead) diff --git a/src/polyrenderer/scene/poly_wallsprite.cpp b/src/polyrenderer/scene/poly_wallsprite.cpp index a5152e2bc6..294664ab34 100644 --- a/src/polyrenderer/scene/poly_wallsprite.cpp +++ b/src/polyrenderer/scene/poly_wallsprite.cpp @@ -123,7 +123,7 @@ void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, const Vec4f &cli args.stenciltestvalue = stencilValue; args.stencilwritevalue = stencilValue; args.SetTexture(tex); - args.SetColormap(GetColorTable(sub->sector->Colormap)); + args.SetColormap(GetColorTable(sub->sector->Colormap, sub->sector->SpecialColors[sector_t::sprites])); args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w); args.subsectorTest = true; args.writeSubsector = false; diff --git a/src/swrenderer/line/r_renderdrawsegment.cpp b/src/swrenderer/line/r_renderdrawsegment.cpp index a4b52bac00..9ccf388b43 100644 --- a/src/swrenderer/line/r_renderdrawsegment.cpp +++ b/src/swrenderer/line/r_renderdrawsegment.cpp @@ -105,7 +105,7 @@ namespace swrenderer // killough 4/13/98: get correct lightlevel for 2s normal textures sec = Thread->OpaquePass->FakeFlat(frontsector, &tempsec, nullptr, nullptr, nullptr, 0, 0, 0, 0); - FDynamicColormap *basecolormap = GetColorTable(sec->Colormap); // [RH] Set basecolormap + FDynamicColormap *basecolormap = GetColorTable(sec->Colormap, sec->SpecialColors[sector_t::walltop]); // [RH] Set basecolormap int wallshade = ds->shade; rw_lightstep = ds->lightstep; @@ -125,7 +125,7 @@ namespace swrenderer if (clip3d->sclipTop <= frontsector->e->XFloor.lightlist[i].plane.Zat0()) { lightlist_t *lit = &frontsector->e->XFloor.lightlist[i]; - basecolormap = GetColorTable(lit->extra_colormap); + basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr) + LightVisibility::ActualExtraLight(ds->foggy, viewport), foggy); break; @@ -703,7 +703,7 @@ namespace swrenderer if (clip3d->sclipTop <= backsector->e->XFloor.lightlist[j].plane.Zat0()) { lightlist_t *lit = &backsector->e->XFloor.lightlist[j]; - basecolormap = GetColorTable(lit->extra_colormap); + basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr) + LightVisibility::ActualExtraLight(ds->foggy, Thread->Viewport.get()), foggy); break; @@ -717,7 +717,7 @@ namespace swrenderer if (clip3d->sclipTop <= frontsector->e->XFloor.lightlist[j].plane.Zat0()) { lightlist_t *lit = &frontsector->e->XFloor.lightlist[j]; - basecolormap = GetColorTable(lit->extra_colormap); + basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr) + LightVisibility::ActualExtraLight(ds->foggy, Thread->Viewport.get()), foggy); break; @@ -725,7 +725,7 @@ namespace swrenderer } } } - if (basecolormap == nullptr) basecolormap = GetColorTable(frontsector->Colormap); + if (basecolormap == nullptr) basecolormap = GetColorTable(frontsector->Colormap, frontsector->SpecialColors[sector_t::walltop]); if (rw_pic != DONT_DRAW) { @@ -882,7 +882,7 @@ namespace swrenderer if (clip3d->sclipTop <= backsector->e->XFloor.lightlist[j].plane.Zat0()) { lightlist_t *lit = &backsector->e->XFloor.lightlist[j]; - basecolormap = GetColorTable(lit->extra_colormap); + basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr) + LightVisibility::ActualExtraLight(ds->foggy, Thread->Viewport.get()), foggy); break; @@ -896,7 +896,7 @@ namespace swrenderer if (clip3d->sclipTop <= frontsector->e->XFloor.lightlist[j].plane.Zat0()) { lightlist_t *lit = &frontsector->e->XFloor.lightlist[j]; - basecolormap = GetColorTable(lit->extra_colormap); + basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr) + LightVisibility::ActualExtraLight(ds->foggy, Thread->Viewport.get()), foggy); break; @@ -904,7 +904,7 @@ namespace swrenderer } } } - if (basecolormap == nullptr) basecolormap = GetColorTable(frontsector->Colormap); + if (basecolormap == nullptr) basecolormap = GetColorTable(frontsector->Colormap, frontsector->SpecialColors[sector_t::walltop]); if (rw_pic != DONT_DRAW) { diff --git a/src/swrenderer/line/r_walldraw.cpp b/src/swrenderer/line/r_walldraw.cpp index c1f4f293d7..8e3c73a173 100644 --- a/src/swrenderer/line/r_walldraw.cpp +++ b/src/swrenderer/line/r_walldraw.cpp @@ -394,7 +394,7 @@ namespace swrenderer } lightlist_t *lit = &frontsector->e->XFloor.lightlist[i]; - basecolormap = GetColorTable(lit->extra_colormap); + basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(foggy, *lit->p_lightlevel, lit->lightsource != NULL) + LightVisibility::ActualExtraLight(foggy, Thread->Viewport.get()), foggy); } diff --git a/src/swrenderer/r_swcolormaps.h b/src/swrenderer/r_swcolormaps.h index 4b2e136044..adb03c2353 100644 --- a/src/swrenderer/r_swcolormaps.h +++ b/src/swrenderer/r_swcolormaps.h @@ -46,15 +46,16 @@ void SetDefaultColormap (const char *name); #endif // MSVC needs the forceinline here. -FORCEINLINE FDynamicColormap *GetColorTable(const FColormap &cm) +FORCEINLINE FDynamicColormap *GetColorTable(const FColormap &cm, PalEntry SpecialColor = 0xffffff) { + auto c = SpecialColor.Modulate(cm.LightColor); auto p = &NormalLight; - if (cm.LightColor == p->Color && + if (c == p->Color && cm.FadeColor == p->Fade && cm.Desaturation == p->Desaturate) { return p; } - return GetSpecialLights(cm.LightColor, cm.FadeColor, cm.Desaturation); + return GetSpecialLights(c, cm.FadeColor, cm.Desaturation); } diff --git a/src/swrenderer/scene/r_opaque_pass.cpp b/src/swrenderer/scene/r_opaque_pass.cpp index 17755bf110..1b16d7c6a3 100644 --- a/src/swrenderer/scene/r_opaque_pass.cpp +++ b/src/swrenderer/scene/r_opaque_pass.cpp @@ -485,7 +485,7 @@ namespace swrenderer if (cameraLight->FixedLightLevel() < 0 && frontsector->e && frontsector->e->XFloor.lightlist.Size()) { light = P_GetPlaneLight(frontsector, &frontsector->ceilingplane, false); - basecolormap = GetColorTable(light->extra_colormap); + basecolormap = GetColorTable(light->extra_colormap, frontsector->SpecialColors[sector_t::ceiling]); // If this is the real ceiling, don't discard plane lighting R_FakeFlat() // accounted for. if (light->p_lightlevel != &frontsector->lightlevel) @@ -495,7 +495,7 @@ namespace swrenderer } else { - basecolormap = (r_fullbrightignoresectorcolor && cameraLight->FixedLightLevel() >= 0) ? &FullNormalLight : GetColorTable(frontsector->Colormap); + basecolormap = (r_fullbrightignoresectorcolor && cameraLight->FixedLightLevel() >= 0) ? &FullNormalLight : GetColorTable(frontsector->Colormap, frontsector->SpecialColors[sector_t::ceiling]); } portal = frontsector->ValidatePortal(sector_t::ceiling); @@ -523,7 +523,7 @@ namespace swrenderer if (cameraLight->FixedLightLevel() < 0 && frontsector->e && frontsector->e->XFloor.lightlist.Size()) { light = P_GetPlaneLight(frontsector, &frontsector->floorplane, false); - basecolormap = GetColorTable(light->extra_colormap); + basecolormap = GetColorTable(light->extra_colormap, frontsector->SpecialColors[sector_t::floor]); // If this is the real floor, don't discard plane lighting R_FakeFlat() // accounted for. if (light->p_lightlevel != &frontsector->lightlevel) @@ -533,7 +533,7 @@ namespace swrenderer } else { - basecolormap = (r_fullbrightignoresectorcolor && cameraLight->FixedLightLevel() >= 0) ? &FullNormalLight : GetColorTable(frontsector->Colormap); + basecolormap = (r_fullbrightignoresectorcolor && cameraLight->FixedLightLevel() >= 0) ? &FullNormalLight : GetColorTable(frontsector->Colormap, frontsector->SpecialColors[sector_t::floor]); } // killough 3/7/98: Add (x,y) offsets to flats, add deep water check @@ -702,7 +702,7 @@ namespace swrenderer ceilingplane = backupcp; } - basecolormap = GetColorTable(frontsector->Colormap); + basecolormap = GetColorTable(frontsector->Colormap, frontsector->SpecialColors[sector_t::sprites]); floorlightlevel = fll; ceilinglightlevel = cll; @@ -726,6 +726,7 @@ namespace swrenderer count = sub->numlines; line = sub->firstline; + basecolormap = GetColorTable(frontsector->Colormap, frontsector->SpecialColors[sector_t::walltop]); while (count--) { if (!outersubsector || line->sidedef == nullptr || !(line->sidedef->Flags & WALLF_POLYOBJ)) @@ -885,7 +886,7 @@ namespace swrenderer { int lightlevel = thing->Sector->GetTexture(sector_t::ceiling) == skyflatnum ? thing->Sector->GetCeilingLight() : thing->Sector->GetFloorLight(); thingShade = LightVisibility::LightLevelToShade(lightlevel + LightVisibility::ActualExtraLight(foggy, Thread->Viewport.get()), foggy); - thingColormap = GetColorTable(thing->Sector->Colormap); + thingColormap = GetColorTable(thing->Sector->Colormap, thing->Sector->SpecialColors[sector_t::sprites]); } if ((sprite.renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE) diff --git a/src/swrenderer/things/r_particle.cpp b/src/swrenderer/things/r_particle.cpp index 5924dee3b6..659935c532 100644 --- a/src/swrenderer/things/r_particle.cpp +++ b/src/swrenderer/things/r_particle.cpp @@ -148,7 +148,7 @@ namespace swrenderer botplane = &heightsec->ceilingplane; toppic = sector->GetTexture(sector_t::ceiling); botpic = heightsec->GetTexture(sector_t::ceiling); - map = GetColorTable(heightsec->Colormap); + map = GetColorTable(heightsec->Colormap, heightsec->SpecialColors[sector_t::sprites]); } else if (fakeside == WaterFakeSide::BelowFloor) { @@ -156,7 +156,7 @@ namespace swrenderer botplane = §or->floorplane; toppic = heightsec->GetTexture(sector_t::floor); botpic = sector->GetTexture(sector_t::floor); - map = GetColorTable(heightsec->Colormap); + map = GetColorTable(heightsec->Colormap, heightsec->SpecialColors[sector_t::sprites]); } else { @@ -164,7 +164,7 @@ namespace swrenderer botplane = &heightsec->floorplane; toppic = heightsec->GetTexture(sector_t::ceiling); botpic = heightsec->GetTexture(sector_t::floor); - map = GetColorTable(sector->Colormap); + map = GetColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites]); } } else @@ -173,7 +173,7 @@ namespace swrenderer botplane = §or->floorplane; toppic = sector->GetTexture(sector_t::ceiling); botpic = sector->GetTexture(sector_t::floor); - map = GetColorTable(sector->Colormap); + map = GetColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites]); } if (botpic != skyflatnum && particle->Pos.Z < botplane->ZatPoint(particle->Pos)) diff --git a/src/swrenderer/things/r_playersprite.cpp b/src/swrenderer/things/r_playersprite.cpp index 0a356f2bba..c7e80c8a0a 100644 --- a/src/swrenderer/things/r_playersprite.cpp +++ b/src/swrenderer/things/r_playersprite.cpp @@ -103,9 +103,9 @@ namespace swrenderer break; sec = rover->model; if (rover->flags & FF_FADEWALLS) - basecolormap = GetColorTable(sec->Colormap); + basecolormap = GetColorTable(sec->Colormap, sec->SpecialColors[sector_t::sprites]); else - basecolormap = GetColorTable(Thread->Viewport->viewpoint.sector->e->XFloor.lightlist[i].extra_colormap); + basecolormap = GetColorTable(Thread->Viewport->viewpoint.sector->e->XFloor.lightlist[i].extra_colormap, sec->SpecialColors[sector_t::sprites]); } break; } @@ -113,7 +113,7 @@ namespace swrenderer if (!sec) { sec = Thread->Viewport->viewpoint.sector; - basecolormap = GetColorTable(sec->Colormap); + basecolormap = GetColorTable(sec->Colormap, sec->SpecialColors[sector_t::sprites]); } floorlight = ceilinglight = sec->lightlevel; } @@ -123,7 +123,7 @@ namespace swrenderer sec = Thread->OpaquePass->FakeFlat(Thread->Viewport->viewpoint.sector, &tempsec, &floorlight, &ceilinglight, nullptr, 0, 0, 0, 0); // [RH] set basecolormap - basecolormap = GetColorTable(sec->Colormap); + basecolormap = GetColorTable(sec->Colormap, sec->SpecialColors[sector_t::sprites]); } // [RH] set foggy flag diff --git a/src/swrenderer/things/r_visiblesprite.cpp b/src/swrenderer/things/r_visiblesprite.cpp index d51a5bd79b..1a97641b47 100644 --- a/src/swrenderer/things/r_visiblesprite.cpp +++ b/src/swrenderer/things/r_visiblesprite.cpp @@ -113,11 +113,11 @@ namespace swrenderer sec = rover->model; if (rover->flags & FF_FADEWALLS) { - mybasecolormap = GetColorTable(sec->Colormap); + mybasecolormap = GetColorTable(sec->Colormap, spr->sector->SpecialColors[sector_t::sprites]); } else { - mybasecolormap = GetColorTable(spr->sector->e->XFloor.lightlist[i].extra_colormap); + mybasecolormap = GetColorTable(spr->sector->e->XFloor.lightlist[i].extra_colormap, spr->sector->SpecialColors[sector_t::sprites]); } } break;