mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 06:42:12 +00:00
- hooked up the colorization feature.
It can now be used from UDMF and ZScript. To avoid clutter it doesn't allow setting the values individually but requires definition of a data record in TEXTURES. colorization { DesaturationFactor <float> Invert AddColor <color> ModulateColor <color> BlendColor <color>, <mode> [, <alpha>] } Mode for BlendColor can be Alpha (normal translucent blending), as well as 3 special values taken from Build engine games: Screen, Overlay and HardLight.
This commit is contained in:
parent
f9d2dc51d0
commit
9b9fd35107
10 changed files with 265 additions and 79 deletions
|
@ -210,6 +210,9 @@ Note: All <bool> fields default to false unless mentioned otherwise.
|
|||
coloradd_top = <int>; // Additive material color to apply to top section of sidedef. Default is black (0x000000)
|
||||
coloradd_mid = <int>; // Additive material color to apply to middle section of sidedef. Default is black (0x000000)
|
||||
coloradd_bottom = <int>; // Additive material color to apply to bottom section of sidedef. Default is black (0x000000)
|
||||
colorization_top = <int>; // Sets a colorization record for the upper texture. Colorization records must be defined in TEXTURES.
|
||||
colorization_mid = <int>; // Sets a colorization record for the middle texture. Colorization records must be defined in TEXTURES.
|
||||
colorization_bottom = <int>; // Sets a colorization record for the lower texture. Colorization records must be defined in TEXTURES.
|
||||
}
|
||||
|
||||
sector
|
||||
|
@ -288,6 +291,9 @@ Note: All <bool> fields default to false unless mentioned otherwise.
|
|||
coloradd_sprites = <int>; // Additive material color applied to sprites within the sector. Default is black (0x000000)
|
||||
coloradd_walls = <int>; // Additive material color applied to walls within the sector. Default is black (0x000000)
|
||||
|
||||
colorization_floor = <int>; // Sets a colorization record for the floor texture. Colorization records must be defined in TEXTURES.
|
||||
colorization_ceiling = <int>; // Sets a colorization record for the ceiling texture. Colorization records must be defined in TEXTURES.
|
||||
|
||||
portal_ceil_blocksound = <bool>; // ceiling portal blocks sound.
|
||||
portal_ceil_disabled = <bool>; // ceiling portal disabled.
|
||||
portal_ceil_nopass = <bool>; // ceiling portal blocks movement if true.
|
||||
|
@ -495,6 +501,9 @@ arg0str in dynamic lights.
|
|||
Added automapstyle and revealed linedef properties.
|
||||
Replaced tabs with spaces.
|
||||
|
||||
1.31 22.12.2019
|
||||
Coloriation options added
|
||||
|
||||
===============================================================================
|
||||
EOF
|
||||
===============================================================================
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "templates.h"
|
||||
#include "m_bbox.h"
|
||||
#include "dobjgc.h"
|
||||
#include "r_data/r_translate.h"
|
||||
|
||||
// Some more or less basic data types
|
||||
// we depend on.
|
||||
|
@ -601,76 +602,6 @@ FSerializer &Serialize(FSerializer &arc, const char *key, secspecial_t &spec, se
|
|||
|
||||
enum class EMoveResult { ok, crushed, pastdest };
|
||||
|
||||
struct TextureManipulation
|
||||
{
|
||||
enum
|
||||
{
|
||||
BlendNone = 0,
|
||||
BlendAlpha = 1,
|
||||
BlendScreen = 2,
|
||||
BlendOverlay = 3,
|
||||
BlendHardLight = 4,
|
||||
BlendMask = 7,
|
||||
InvertBit = 8,
|
||||
ActiveBit = 16, // Must be set for the shader to do something
|
||||
};
|
||||
PalEntry AddColor; // Alpha contains the blend flags
|
||||
PalEntry ModulateColor; // Alpha may contain a multiplier to get higher values than 1.0 without promoting this to 4 full floats.
|
||||
PalEntry BlendColor;
|
||||
float DesaturationFactor;
|
||||
|
||||
bool CheckIfEnabled() // check if this manipulation is doing something. NoOps do not need to be preserved, unless they override older setttings.
|
||||
{
|
||||
if (AddColor != 0 || // this includes a check for the blend mode without which BlendColor is not active
|
||||
ModulateColor != 0x01ffffff || // 1 in alpha must be the default for a no-op.
|
||||
DesaturationFactor != 0)
|
||||
{
|
||||
AddColor.a |= ActiveBit; // mark as active for the shader's benefit.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetTextureModulateColor(int slot, PalEntry rgb)
|
||||
{
|
||||
rgb.a = ModulateColor.a;
|
||||
ModulateColor = rgb;
|
||||
}
|
||||
|
||||
void SetTextureModulateScaleFactor(int slot, int fac)
|
||||
{
|
||||
ModulateColor.a = (uint8_t)fac;
|
||||
}
|
||||
|
||||
void SetTextureAdditiveColor(int slot, PalEntry rgb)
|
||||
{
|
||||
rgb.a = AddColor.a;
|
||||
AddColor = rgb;
|
||||
}
|
||||
|
||||
void SetTextureBlendColor(int slot, PalEntry rgb)
|
||||
{
|
||||
BlendColor = rgb;
|
||||
}
|
||||
|
||||
void SetTextureDesaturationFactor(int slot, double fac)
|
||||
{
|
||||
DesaturationFactor = (float)fac;
|
||||
}
|
||||
|
||||
void SetTextureBlendMode(int slot, int mode)
|
||||
{
|
||||
AddColor.a = (AddColor.a & ~TextureManipulation::BlendMask) | (mode & TextureManipulation::BlendMask);
|
||||
}
|
||||
|
||||
void SetTextureInvert(bool on)
|
||||
{
|
||||
AddColor.a |= TextureManipulation::InvertBit;
|
||||
AddColor.a &= ~TextureManipulation::InvertBit;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct sector_t
|
||||
{
|
||||
|
||||
|
@ -1129,9 +1060,10 @@ public:
|
|||
|
||||
// TextureFX parameters
|
||||
|
||||
void SetTextureFx(int slot, const TextureManipulation &tm)
|
||||
void SetTextureFx(int slot, const TextureManipulation *tm)
|
||||
{
|
||||
planes[slot].TextureFx = tm; // this is for getting the data from a texture.
|
||||
if (tm) planes[slot].TextureFx = *tm; // this is for getting the data from a texture.
|
||||
else planes[slot].TextureFx = {};
|
||||
}
|
||||
|
||||
|
||||
|
@ -1429,10 +1361,17 @@ struct side_t
|
|||
textures[which].AdditiveColor = rgb;
|
||||
}
|
||||
|
||||
void SetTextureFx(int slot, const TextureManipulation& tm)
|
||||
void SetTextureFx(int slot, const TextureManipulation* tm)
|
||||
{
|
||||
textures[slot].TextureFx = tm; // this is for getting the data from a texture.
|
||||
if (tm.AddColor.a) Flags |= WALLF_EXTCOLOR;
|
||||
if (tm)
|
||||
{
|
||||
textures[slot].TextureFx = *tm; // this is for getting the data from a texture.
|
||||
if (tm->AddColor.a) Flags |= WALLF_EXTCOLOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
textures[slot].TextureFx = {};
|
||||
}
|
||||
}
|
||||
|
||||
PalEntry GetAdditiveColor(int which, sector_t *frontsector) const
|
||||
|
|
|
@ -141,6 +141,7 @@ void FTextureManager::DeleteAll()
|
|||
}
|
||||
mAnimatedDoors.Clear();
|
||||
BuildTileData.Clear();
|
||||
tmanips.Clear();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -688,6 +689,69 @@ void FTextureManager::AddHiresTextures (int wadnum)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FTextureManager::ParseColorization(FScanner& sc)
|
||||
{
|
||||
TextureManipulation tm = {};
|
||||
sc.MustGetString();
|
||||
FName cname = sc.String;
|
||||
sc.MustGetToken('{');
|
||||
while (!sc.CheckToken('}'))
|
||||
{
|
||||
if (sc.Compare("desaturation"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
tm.DesaturationFactor = sc.Float;
|
||||
}
|
||||
else if (sc.Compare("AddColor"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
tm.AddColor = (tm.AddColor & 0xff000000) | (V_GetColor(NULL, sc) & 0xffffff);
|
||||
}
|
||||
else if (sc.Compare("ModulateColor"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
tm.ModulateColor = V_GetColor(NULL, sc) & 0xffffff;
|
||||
if (sc.CheckToken(','))
|
||||
{
|
||||
sc.MustGetNumber();
|
||||
tm.ModulateColor.a = sc.Number;
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("BlendColor"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
tm.BlendColor = V_GetColor(NULL, sc) & 0xffffff;
|
||||
sc.MustGetToken(',');
|
||||
sc.MustGetString();
|
||||
static const char* opts[] = {"none", "alpha", "screen", "overlay", "hardlight", nullptr};
|
||||
tm.AddColor.a = (tm.AddColor.a & ~TextureManipulation::BlendMask) | sc.MustMatchString(opts);
|
||||
if (sc.CheckToken(','))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
tm.BlendColor.a = clamp(sc.Float, 0., 1.) * 255;
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("invert"))
|
||||
{
|
||||
tm.AddColor.a |= TextureManipulation::InvertBit;
|
||||
}
|
||||
}
|
||||
if (tm.CheckIfEnabled())
|
||||
{
|
||||
tmanips.Insert(cname, tm);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmanips.Remove(cname);
|
||||
}
|
||||
|
||||
}
|
||||
//==========================================================================
|
||||
//
|
||||
// Loads the HIRESTEX lumps
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FTextureManager::LoadTextureDefs(int wadnum, const char *lumpname, FMultipatchTextureBuilder &build)
|
||||
{
|
||||
int remapLump, lastLump;
|
||||
|
@ -838,6 +902,10 @@ void FTextureManager::ParseTextureDef(int lump, FMultipatchTextureBuilder &build
|
|||
{
|
||||
build.ParseTexture(sc, ETextureType::MiscPatch);
|
||||
}
|
||||
else if (sc.Compare("colorization"))
|
||||
{
|
||||
ParseColorization(sc);
|
||||
}
|
||||
else if (sc.Compare("#include"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
|
|
|
@ -601,6 +601,7 @@ public:
|
|||
void AddPatches (int lumpnum);
|
||||
void AddHiresTextures (int wadnum);
|
||||
void LoadTextureDefs(int wadnum, const char *lumpname, FMultipatchTextureBuilder &build);
|
||||
void ParseColorization(FScanner& sc);
|
||||
void ParseTextureDef(int remapLump, FMultipatchTextureBuilder &build);
|
||||
void SortTexturesByType(int start, int end);
|
||||
bool AreTexturesCompatible (FTextureID picnum1, FTextureID picnum2);
|
||||
|
@ -626,6 +627,12 @@ public:
|
|||
FSwitchDef *FindSwitch (FTextureID texture);
|
||||
FDoorAnimation *FindAnimatedDoor (FTextureID picnum);
|
||||
|
||||
TextureManipulation* GetTextureManipulation(FName name)
|
||||
{
|
||||
return tmanips.CheckKey(name);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// texture counting
|
||||
|
@ -683,6 +690,7 @@ private:
|
|||
|
||||
TArray<FSwitchDef *> mSwitchDefs;
|
||||
TArray<FDoorAnimation> mAnimatedDoors;
|
||||
TMap<FName, TextureManipulation> tmanips;
|
||||
|
||||
public:
|
||||
TArray<FAnimDef *> mAnimations;
|
||||
|
|
|
@ -1295,6 +1295,18 @@ public:
|
|||
Flag(sd->Flags, WALLF_NOAUTODECALS, key);
|
||||
continue;
|
||||
|
||||
case NAME_colorization_top:
|
||||
sd->SetTextureFx(side_t::top, TexMan.GetTextureManipulation(CheckString(key)));
|
||||
break;
|
||||
|
||||
case NAME_colorization_mid:
|
||||
sd->SetTextureFx(side_t::mid, TexMan.GetTextureManipulation(CheckString(key)));
|
||||
break;
|
||||
|
||||
case NAME_colorization_bottom:
|
||||
sd->SetTextureFx(side_t::bottom, TexMan.GetTextureManipulation(CheckString(key)));
|
||||
break;
|
||||
|
||||
case NAME_nogradient_top:
|
||||
Flag(sd->textures[side_t::top].flags, side_t::part::NoGradient, key);
|
||||
break;
|
||||
|
@ -1650,6 +1662,14 @@ public:
|
|||
sec->AdditiveColors[sector_t::sprites] = CheckInt(key) | 0xff000000;
|
||||
break;
|
||||
|
||||
case NAME_colorization_floor:
|
||||
sec->SetTextureFx(sector_t::floor, TexMan.GetTextureManipulation(CheckString(key)));
|
||||
break;
|
||||
|
||||
case NAME_colorization_ceiling:
|
||||
sec->SetTextureFx(sector_t::ceiling, TexMan.GetTextureManipulation(CheckString(key)));
|
||||
break;
|
||||
|
||||
case NAME_Desaturation:
|
||||
desaturation = int(255*CheckFloat(key) + FLT_EPSILON); // FLT_EPSILON to avoid rounding errors with numbers slightly below a full integer.
|
||||
continue;
|
||||
|
|
|
@ -89,6 +89,31 @@ FSerializer &Serialize(FSerializer &arc, const char *key, line_t &line, line_t *
|
|||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FSerializer& Serialize(FSerializer& arc, const char* key, TextureManipulation& part, TextureManipulation *def)
|
||||
{
|
||||
if (arc.canSkip() && def != nullptr && !memcmp(&part, def, sizeof(part)))
|
||||
{
|
||||
return arc;
|
||||
}
|
||||
|
||||
if (arc.BeginObject(key))
|
||||
{
|
||||
arc("addcolor", part.AddColor, def->AddColor)
|
||||
("yoffset", part.ModulateColor, def->ModulateColor)
|
||||
("xscale", part.BlendColor, def->BlendColor)
|
||||
("yscale", part.DesaturationFactor, def->DesaturationFactor)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -114,6 +139,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, side_t::part &part, si
|
|||
("color1", part.SpecialColors[0], def->SpecialColors[0])
|
||||
("color2", part.SpecialColors[1], def->SpecialColors[1])
|
||||
("addcolor", part.AdditiveColor, def->AdditiveColor)
|
||||
("texturefx", part.TextureFx, def->TextureFx)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
|
@ -212,6 +238,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, sector_t::splane &p, s
|
|||
("alpha", p.alpha, def->alpha)
|
||||
("glowcolor", p.GlowColor, def->GlowColor)
|
||||
("glowheight", p.GlowHeight, def->GlowHeight)
|
||||
("texturefx", p.TextureFx, def->TextureFx)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
|
|
|
@ -147,6 +147,77 @@ int CreateBloodTranslation(PalEntry color);
|
|||
int R_FindCustomTranslation(FName name);
|
||||
void R_ParseTrnslate();
|
||||
|
||||
struct TextureManipulation
|
||||
{
|
||||
enum
|
||||
{
|
||||
BlendNone = 0,
|
||||
BlendAlpha = 1,
|
||||
BlendScreen = 2,
|
||||
BlendOverlay = 3,
|
||||
BlendHardLight = 4,
|
||||
BlendMask = 7,
|
||||
InvertBit = 8,
|
||||
ActiveBit = 16, // Must be set for the shader to do something
|
||||
};
|
||||
PalEntry AddColor; // Alpha contains the blend flags
|
||||
PalEntry ModulateColor; // Alpha may contain a multiplier to get higher values than 1.0 without promoting this to 4 full floats.
|
||||
PalEntry BlendColor;
|
||||
float DesaturationFactor;
|
||||
|
||||
bool CheckIfEnabled() // check if this manipulation is doing something. NoOps do not need to be preserved, unless they override older setttings.
|
||||
{
|
||||
if (AddColor != 0 || // this includes a check for the blend mode without which BlendColor is not active
|
||||
ModulateColor != 0x01ffffff || // 1 in alpha must be the default for a no-op.
|
||||
DesaturationFactor != 0)
|
||||
{
|
||||
AddColor.a |= ActiveBit; // mark as active for the shader's benefit.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetTextureModulateColor(int slot, PalEntry rgb)
|
||||
{
|
||||
rgb.a = ModulateColor.a;
|
||||
ModulateColor = rgb;
|
||||
}
|
||||
|
||||
void SetTextureModulateScaleFactor(int slot, int fac)
|
||||
{
|
||||
ModulateColor.a = (uint8_t)fac;
|
||||
}
|
||||
|
||||
void SetTextureAdditiveColor(int slot, PalEntry rgb)
|
||||
{
|
||||
rgb.a = AddColor.a;
|
||||
AddColor = rgb;
|
||||
}
|
||||
|
||||
void SetTextureBlendColor(int slot, PalEntry rgb)
|
||||
{
|
||||
BlendColor = rgb;
|
||||
}
|
||||
|
||||
void SetTextureDesaturationFactor(int slot, double fac)
|
||||
{
|
||||
DesaturationFactor = (float)fac;
|
||||
}
|
||||
|
||||
void SetTextureBlendMode(int slot, int mode)
|
||||
{
|
||||
AddColor.a = (AddColor.a & ~TextureManipulation::BlendMask) | (mode & TextureManipulation::BlendMask);
|
||||
}
|
||||
|
||||
void SetTextureInvert(bool on)
|
||||
{
|
||||
AddColor.a |= TextureManipulation::InvertBit;
|
||||
AddColor.a &= ~TextureManipulation::InvertBit;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // __R_TRANSLATE_H
|
||||
|
|
|
@ -652,6 +652,24 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetAdditiveColor, SetAdditiveColor)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void SetColorization(sector_t* self, int pos, int cname)
|
||||
{
|
||||
if (pos >= 0 && pos < 2)
|
||||
{
|
||||
self->SetTextureFx(pos, TexMan.GetTextureManipulation(ENamedName(cname)));
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetColorization, SetColorization)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(sector_t);
|
||||
PARAM_INT(pos);
|
||||
PARAM_INT(color);
|
||||
SetColorization(self, pos, color);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void SetFogDensity(sector_t *self, int dens)
|
||||
{
|
||||
self->Colormap.FogDensity = dens;
|
||||
|
@ -1749,6 +1767,25 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetXOffset, SetXOffset)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void SetWallColorization(side_t* self, int pos, int cname)
|
||||
{
|
||||
if (pos >= 0 && pos < 2)
|
||||
{
|
||||
self->SetTextureFx(pos, TexMan.GetTextureManipulation(ENamedName(cname)));
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(_Side, SetColorization, SetWallColorization)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(side_t);
|
||||
PARAM_INT(pos);
|
||||
PARAM_INT(color);
|
||||
SetWallColorization(self, pos, color);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int SideIndex(side_t *self)
|
||||
{
|
||||
return self->Index();
|
||||
|
|
|
@ -671,6 +671,11 @@ xx(useowncoloradd_mid)
|
|||
xx(coloradd_mid)
|
||||
xx(useowncoloradd_bottom)
|
||||
xx(coloradd_bottom)
|
||||
xx(colorization_top)
|
||||
xx(colorization_mid)
|
||||
xx(colorization_bottom)
|
||||
xx(colorization_floor)
|
||||
xx(colorization_ceiling)
|
||||
|
||||
xx(Renderstyle)
|
||||
|
||||
|
|
|
@ -87,6 +87,7 @@ struct Side native play
|
|||
native Color GetAdditiveColor(int tier);
|
||||
native void SetAdditiveColor(int tier, Color color);
|
||||
native void EnableAdditiveColor(int tier, bool enable);
|
||||
native void SetColorization(int tier, Name cname);
|
||||
//native DInterpolation *SetInterpolation(int position);
|
||||
//native void StopInterpolation(int position);
|
||||
|
||||
|
@ -469,6 +470,7 @@ struct Sector native play
|
|||
native void SetGlowColor(int pos, color color);
|
||||
native void SetSpecialColor(int pos, color color);
|
||||
native void SetAdditiveColor(int pos, Color color);
|
||||
native void SetColorization(int tier, Name cname);
|
||||
|
||||
native TextureID GetTexture(int pos);
|
||||
native void SetTexture(int pos, TextureID tex, bool floorclip = true);
|
||||
|
|
Loading…
Reference in a new issue