Skymist is a third sky layer with transparency, and adopts the fade color and skyfog density. Size not connected to SKY1 or SKY2. Works with 6-sided skyboxes. Three template pngs (skymist1, 2, & 3) all 1x544 pixels, 8-bit grayscale with transparency are part of gzdoom.pk3 for general usage. Can supply custom lump through mapinfo. Console command 'skymisttoggle' shows the effect (make sure fade has a non-zero color in mapinfo and skyfog has non-zero density). Oh, and skyfog now works with 6-sided skyboxes.

This commit is contained in:
Dileep V. Reddy 2025-04-26 09:11:58 -06:00 committed by Ricardo Luís Vaz Silva
commit e9a067dd65
14 changed files with 80 additions and 12 deletions

View file

@ -488,7 +488,7 @@ void FSkyVertexBuffer::DoRenderDome(FRenderState& state, FGameTexture* tex, int
RenderRow(state, DT_TriangleFan, rc, primStart);
state.EnableTexture(true);
}
state.SetObjectColor(0xffffffff);
state.SetObjectColor(color);
for (int i = 1; i <= mRows; i++)
{
RenderRow(state, DT_TriangleStrip, i, primStart, i == 1);

View file

@ -942,6 +942,16 @@ CCMD(changesky)
InitSkyMap (primaryLevel);
}
//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
CCMD(skymisttoggle)
{
primaryLevel->flags3 ^= LEVEL3_SKYMIST;
}
//-----------------------------------------------------------------------------
//
//

View file

@ -1835,8 +1835,10 @@ void FLevelLocals::Init()
skyspeed1 = info->skyspeed1;
skyspeed2 = info->skyspeed2;
skymistspeed = info->skymistspeed;
skytexture1 = TexMan.GetTextureID(info->SkyPic1.GetChars(), ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst);
skytexture2 = TexMan.GetTextureID(info->SkyPic2.GetChars(), ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst);
skymisttexture = TexMan.GetTextureID(info->SkyMistPic.GetChars(), ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst);
fadeto = info->fadeto;
cdtrack = info->cdtrack;
cdid = info->cdid;

View file

@ -687,12 +687,14 @@ public:
unsigned int cdid;
FTextureID skytexture1;
FTextureID skytexture2;
FTextureID skymisttexture;
float skyspeed1; // Scrolling speed of sky textures, in pixels per ms
float skyspeed2;
float skymistspeed;
double sky1pos, sky2pos;
float hw_sky1pos, hw_sky2pos;
float hw_sky1pos, hw_sky2pos, hw_skymistpos;
bool skystretch;
uint32_t globalcolormap;

View file

@ -97,6 +97,7 @@ level_info_t *FindLevelInfo (const char *mapname, bool allowdefault)
if (TheDefaultLevelInfo.LevelName.IsEmpty())
{
TheDefaultLevelInfo.SkyPic2 = TheDefaultLevelInfo.SkyPic1 = "SKY1";
TheDefaultLevelInfo.SkyMistPic = "SKYMIST1";
TheDefaultLevelInfo.LevelName = "Unnamed";
}
return &TheDefaultLevelInfo;
@ -255,6 +256,7 @@ void level_info_t::Reset()
NextMap = "";
NextSecretMap = "";
SkyPic1 = SkyPic2 = "-NOFLAT-";
SkyMistPic = "SKYMIST1";
cluster = 0;
partime = 0;
sucktime = 0;
@ -277,7 +279,7 @@ void level_info_t::Reset()
musicorder = 0;
Snapshot = { 0,0,0,0,0,nullptr };
deferred.Clear();
skyspeed1 = skyspeed2 = 0.f;
skyspeed1 = skyspeed2 = skymistspeed = 0.f;
fadeto = 0;
outsidefog = 0xff000000;
cdtrack = 0;
@ -1099,6 +1101,20 @@ DEFINE_MAP_OPTION(sky2, true)
}
}
DEFINE_MAP_OPTION(skymist, true)
{
parse.ParseAssign();
parse.ParseLumpOrTextureName(info->SkyMistPic);
if (parse.CheckFloat())
{
if (parse.HexenHack)
{
parse.sc.Float /= 256;
}
info->skymistspeed = float(parse.sc.Float * (TICRATE / 1000.));
}
}
// Vavoom compatibility
DEFINE_MAP_OPTION(skybox, true)
{
@ -1857,7 +1873,8 @@ MapFlagHandlers[] =
{ "disableskyboxao", MITYPE_CLRFLAG3, LEVEL3_SKYBOXAO, 0 },
{ "avoidmelee", MITYPE_SETFLAG3, LEVEL3_AVOIDMELEE, 0 },
{ "attenuatelights", MITYPE_SETFLAG3, LEVEL3_ATTENUATE, 0 },
{ "nofogofwar", MITYPE_SETFLAG3, LEVEL3_NOFOGOFWAR, 0 },
{ "nofogofwar", MITYPE_SETFLAG3, LEVEL3_NOFOGOFWAR, 0 },
{ "useskymist", MITYPE_SETFLAG3, LEVEL3_SKYMIST, 0 },
{ "nobotnodes", MITYPE_IGNORE, 0, 0 }, // Skulltag option: nobotnodes
{ "nopassover", MITYPE_COMPATFLAG, COMPATF_NO_PASSMOBJ, 0 },
{ "passover", MITYPE_CLRCOMPATFLAG, COMPATF_NO_PASSMOBJ, 0 },

View file

@ -274,6 +274,7 @@ enum ELevelFlags : unsigned int
LEVEL3_LIGHTCREATED = 0x00080000, // a light had been created in the last frame
LEVEL3_NOFOGOFWAR = 0x00100000, // disables effect of r_radarclipper CVAR on this map
LEVEL3_SECRET = 0x00200000, // level is a secret level
LEVEL3_SKYMIST = 0x00400000, // level skyfog uses the skymist texture
};
@ -333,6 +334,7 @@ struct level_info_t
FString PName;
FString SkyPic1;
FString SkyPic2;
FString SkyMistPic;
FString FadeTable;
FString CustomColorMap;
FString F1Pic;
@ -359,6 +361,7 @@ struct level_info_t
TArray<acsdefered_t> deferred;
float skyspeed1;
float skyspeed2;
float skymistspeed;
uint32_t fadeto;
uint32_t outsidefog;
int cdtrack;

View file

@ -964,6 +964,7 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload)
("fadeto", fadeto)
("skyspeed1", skyspeed1)
("skyspeed2", skyspeed2)
("skymistspeed", skymistspeed)
("found_secrets", found_secrets)
("found_items", found_items)
("killed_monsters", killed_monsters)
@ -977,6 +978,7 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload)
("totaltime", i)
("skytexture1", skytexture1)
("skytexture2", skytexture2)
("skymisttexture", skymisttexture)
("fogdensity", fogdensity)
("outsidefogdensity", outsidefogdensity)
("skyfog", skyfog)

View file

@ -212,6 +212,10 @@ static void PrecacheLevel(FLevelLocals *Level)
{
AddToList(hitlist.Data(), Level->skytexture2, FTextureManager::HIT_Sky);
}
if (Level->skymisttexture.isValid())
{
AddToList(hitlist.Data(), Level->skymisttexture, FTextureManager::HIT_Sky);
}
static const BITFIELD checkForTextureFlags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny | FTextureManager::TEXMAN_ReturnFirst | FTextureManager::TEXMAN_DontCreate;

View file

@ -5545,6 +5545,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, int32_t *args, int &
{
if (args[0] == 1) Level->skyspeed1 = ACSToFloat(args[1]);
else if (args[0] == 2) Level->skyspeed2 = ACSToFloat(args[1]);
else if (args[0] == 3) Level->skymistspeed = ACSToFloat(args[1]);
return 1;
}

View file

@ -13,9 +13,9 @@ class FSkyBox;
struct HWSkyInfo
{
float x_offset[2];
float x_offset[3];
float y_offset; // doubleskies don't have a y-offset
FGameTexture * texture[2];
FGameTexture * texture[3];
FTextureID skytexno1;
bool mirrored;
bool doublesky;
@ -351,7 +351,6 @@ public:
};
struct HWSkyPortal : public HWPortal
{
HWSkyInfo * origin;

View file

@ -118,6 +118,9 @@ void HWSkyInfo::init(HWDrawInfo *di, sector_t* sec, int skypos, int sky1, PalEnt
}
else fadecolor = 0;
texture[2] = TexMan.GetGameTexture(di->Level->skymisttexture);
x_offset[2] = di->Level->hw_skymistpos;
}

View file

@ -74,19 +74,26 @@ void HWSkyPortal::DrawContents(HWDrawInfo *di, FRenderState &state)
vertexBuffer->RenderDome(state, origin->texture[0], origin->x_offset[0], origin->y_offset, origin->mirrored, FSkyVertexBuffer::SKYMODE_MAINLAYER, !!(di->Level->flags & LEVEL_FORCETILEDSKY));
state.SetTextureMode(TM_NORMAL);
}
state.AlphaFunc(Alpha_Greater, 0.f);
if (origin->doublesky && origin->texture[1])
{
vertexBuffer->RenderDome(state, origin->texture[1], origin->x_offset[1], origin->y_offset, false, FSkyVertexBuffer::SKYMODE_SECONDLAYER, !!(di->Level->flags & LEVEL_FORCETILEDSKY));
}
}
if (di->Level->skyfog>0 && !di->isFullbrightScene() && (origin->fadecolor & 0xffffff) != 0)
if (di->Level->skyfog>0 && (origin->fadecolor & 0xffffff) != 0)
{
PalEntry FadeColor = origin->fadecolor;
FadeColor.a = clamp<int>(di->Level->skyfog, 0, 255);
if (di->Level->flags3 & LEVEL3_SKYMIST && origin->texture[2])
{
vertexBuffer->RenderDome(state, origin->texture[2], origin->x_offset[2], 0.f, false, FSkyVertexBuffer::SKYMODE_FOGLAYER, !!(di->Level->flags & LEVEL_FORCETILEDSKY), 0, 0, FadeColor);
}
else if (!di->isFullbrightScene())
{
PalEntry FadeColor = origin->fadecolor;
FadeColor.a = clamp<int>(di->Level->skyfog, 0, 255);
state.EnableTexture(false);
state.SetObjectColor(FadeColor);
state.Draw(DT_Triangles, 0, 12);

View file

@ -79,6 +79,10 @@ void InitSkyMap(FLevelLocals *Level)
{
Level->skytexture1 = TexMan.GetFrontSkyLayer(Level->skytexture1);
}
if (Level->skymisttexture.isNull())
{
Level->skymisttexture = TexMan.CheckForTexture("skymist1", ETextureType::Any);
}
skytex1 = TexMan.GetGameTexture(Level->skytexture1, false);
skytex2 = TexMan.GetGameTexture(Level->skytexture2, false);
@ -143,6 +147,7 @@ void R_UpdateSky (uint64_t mstime)
// The hardware renderer uses a different value range and clamps it to a single rotation
Level->hw_sky1pos = (float)(fmod((double(mstime) * Level->skyspeed1), 1024.) * (90. / 256.));
Level->hw_sky2pos = (float)(fmod((double(mstime) * Level->skyspeed2), 1024.) * (90. / 256.));
Level->hw_skymistpos = (float)(fmod((double(mstime) * Level->skymistspeed), 1024.) * (90. / 256.));
}
}

View file

@ -1738,6 +1738,15 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetXOffset, SetXOffset)
return 0;
}
DEFINE_ACTION_FUNCTION(FLevelLocals, ChangeSkyMist)
{
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
PARAM_INT(skymist);
self->skymisttexture = FSetTextureID(skymist);
InitSkyMap(self);
return 0;
}
DEFINE_ACTION_FUNCTION(FLevelLocals, StartIntermission)
{
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
@ -2802,6 +2811,7 @@ DEFINE_FIELD_X(LevelInfo, level_info_t, NextMap)
DEFINE_FIELD_X(LevelInfo, level_info_t, NextSecretMap)
DEFINE_FIELD_X(LevelInfo, level_info_t, SkyPic1)
DEFINE_FIELD_X(LevelInfo, level_info_t, SkyPic2)
DEFINE_FIELD_X(LevelInfo, level_info_t, SkyMistPic)
DEFINE_FIELD_X(LevelInfo, level_info_t, F1Pic)
DEFINE_FIELD_X(LevelInfo, level_info_t, cluster)
DEFINE_FIELD_X(LevelInfo, level_info_t, partime)
@ -2817,6 +2827,7 @@ DEFINE_FIELD_X(LevelInfo, level_info_t, MapLabel)
DEFINE_FIELD_X(LevelInfo, level_info_t, musicorder)
DEFINE_FIELD_X(LevelInfo, level_info_t, skyspeed1)
DEFINE_FIELD_X(LevelInfo, level_info_t, skyspeed2)
DEFINE_FIELD_X(LevelInfo, level_info_t, skymistspeed)
DEFINE_FIELD_X(LevelInfo, level_info_t, cdtrack)
DEFINE_FIELD_X(LevelInfo, level_info_t, gravity)
DEFINE_FIELD_X(LevelInfo, level_info_t, aircontrol)
@ -2860,8 +2871,10 @@ DEFINE_FIELD(FLevelLocals, Music)
DEFINE_FIELD(FLevelLocals, musicorder)
DEFINE_FIELD(FLevelLocals, skytexture1)
DEFINE_FIELD(FLevelLocals, skytexture2)
DEFINE_FIELD(FLevelLocals, skymisttexture)
DEFINE_FIELD(FLevelLocals, skyspeed1)
DEFINE_FIELD(FLevelLocals, skyspeed2)
DEFINE_FIELD(FLevelLocals, skymistspeed)
DEFINE_FIELD(FLevelLocals, total_secrets)
DEFINE_FIELD(FLevelLocals, found_secrets)
DEFINE_FIELD(FLevelLocals, total_items)