mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-03-10 11:11:51 +00:00
This commit is contained in:
parent
c630fd9b25
commit
b6f0bc0da3
27 changed files with 226 additions and 5 deletions
|
@ -1629,3 +1629,8 @@ FSerializer& Serialize(FSerializer& arc, const char* key, FRenderStyle& style, F
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveRecords saveRecords;
|
SaveRecords saveRecords;
|
||||||
|
|
||||||
|
FSerializer &Serialize(FSerializer &arc, const char *key, FVector4 &value, FVector4 *defval)
|
||||||
|
{
|
||||||
|
return arc.Array<float>(key, &value[0], defval ? &(*defval)[0] : nullptr, 4, true);
|
||||||
|
}
|
||||||
|
|
|
@ -234,6 +234,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FName &value, FName *d
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, FSoundID &sid, FSoundID *def);
|
FSerializer &Serialize(FSerializer &arc, const char *key, FSoundID &sid, FSoundID *def);
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, FString &sid, FString *def);
|
FSerializer &Serialize(FSerializer &arc, const char *key, FString &sid, FString *def);
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, NumericValue &sid, NumericValue *def);
|
FSerializer &Serialize(FSerializer &arc, const char *key, NumericValue &sid, NumericValue *def);
|
||||||
|
FSerializer &Serialize(FSerializer &arc, const char *key, FVector4 &value, FVector4 *defval);
|
||||||
|
|
||||||
template <typename T/*, typename = std::enable_if_t<std::is_base_of_v<DObject, T>>*/>
|
template <typename T/*, typename = std::enable_if_t<std::is_base_of_v<DObject, T>>*/>
|
||||||
FSerializer &Serialize(FSerializer &arc, const char *key, T *&value, T **)
|
FSerializer &Serialize(FSerializer &arc, const char *key, T *&value, T **)
|
||||||
|
|
|
@ -17,7 +17,7 @@ public:
|
||||||
|
|
||||||
virtual VSMatrix GetViewToWorldMatrix() = 0;
|
virtual VSMatrix GetViewToWorldMatrix() = 0;
|
||||||
|
|
||||||
virtual void BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored) = 0;
|
virtual void BeginDrawHUDModel(FRenderStyle style, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored) = 0;
|
||||||
virtual void EndDrawHUDModel(FRenderStyle style) = 0;
|
virtual void EndDrawHUDModel(FRenderStyle style) = 0;
|
||||||
|
|
||||||
virtual void SetInterpolation(double interpolation) = 0;
|
virtual void SetInterpolation(double interpolation) = 0;
|
||||||
|
|
|
@ -140,6 +140,7 @@ bool FGLRenderState::ApplyShader()
|
||||||
activeShader->muTextureModulateColor.Set(mStreamData.uTextureModulateColor);
|
activeShader->muTextureModulateColor.Set(mStreamData.uTextureModulateColor);
|
||||||
activeShader->muTextureBlendColor.Set(mStreamData.uTextureBlendColor);
|
activeShader->muTextureBlendColor.Set(mStreamData.uTextureBlendColor);
|
||||||
activeShader->muDetailParms.Set(&mStreamData.uDetailParms.X);
|
activeShader->muDetailParms.Set(&mStreamData.uDetailParms.X);
|
||||||
|
activeShader->muDirectionalLight.Set(&mStreamData.uDirectionalLight.X);
|
||||||
#ifdef NPOT_EMULATION
|
#ifdef NPOT_EMULATION
|
||||||
activeShader->muNpotEmulation.Set(&mStreamData.uNpotEmulation.X);
|
activeShader->muNpotEmulation.Set(&mStreamData.uNpotEmulation.X);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -284,6 +284,9 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
||||||
uniform mat4 NormalModelMatrix;
|
uniform mat4 NormalModelMatrix;
|
||||||
uniform mat4 TextureMatrix;
|
uniform mat4 TextureMatrix;
|
||||||
|
|
||||||
|
// directional light
|
||||||
|
uniform vec4 uDirectionalLight;
|
||||||
|
|
||||||
// light buffers
|
// light buffers
|
||||||
#ifdef SHADER_STORAGE_LIGHTS
|
#ifdef SHADER_STORAGE_LIGHTS
|
||||||
layout(std430, binding = 1) buffer LightBufferSSO
|
layout(std430, binding = 1) buffer LightBufferSSO
|
||||||
|
@ -600,6 +603,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
||||||
muTextureModulateColor.Init(hShader, "uTextureModulateColor");
|
muTextureModulateColor.Init(hShader, "uTextureModulateColor");
|
||||||
muTextureBlendColor.Init(hShader, "uTextureBlendColor");
|
muTextureBlendColor.Init(hShader, "uTextureBlendColor");
|
||||||
muTimer.Init(hShader, "timer");
|
muTimer.Init(hShader, "timer");
|
||||||
|
muDirectionalLight.Init(hShader, "uDirectionalLight");
|
||||||
|
|
||||||
lights_index = glGetUniformLocation(hShader, "lights");
|
lights_index = glGetUniformLocation(hShader, "lights");
|
||||||
modelmatrix_index = glGetUniformLocation(hShader, "ModelMatrix");
|
modelmatrix_index = glGetUniformLocation(hShader, "ModelMatrix");
|
||||||
|
|
|
@ -266,6 +266,7 @@ class FShader
|
||||||
FBufferedUniform2f muNpotEmulation;
|
FBufferedUniform2f muNpotEmulation;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
FUniform4f muDirectionalLight;
|
||||||
int lights_index;
|
int lights_index;
|
||||||
int modelmatrix_index;
|
int modelmatrix_index;
|
||||||
int normalmodelmatrix_index;
|
int normalmodelmatrix_index;
|
||||||
|
|
|
@ -202,6 +202,8 @@ struct StreamData
|
||||||
FVector4 uDetailParms;
|
FVector4 uDetailParms;
|
||||||
FVector4 uNpotEmulation;
|
FVector4 uNpotEmulation;
|
||||||
FVector4 padding1, padding2, padding3;
|
FVector4 padding1, padding2, padding3;
|
||||||
|
|
||||||
|
FVector4 uDirectionalLight;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FRenderState
|
class FRenderState
|
||||||
|
@ -305,6 +307,7 @@ public:
|
||||||
#ifdef NPOT_EMULATION
|
#ifdef NPOT_EMULATION
|
||||||
mStreamData.uNpotEmulation = { 0,0,0,0 };
|
mStreamData.uNpotEmulation = { 0,0,0,0 };
|
||||||
#endif
|
#endif
|
||||||
|
mStreamData.uDirectionalLight = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||||
mModelMatrix.loadIdentity();
|
mModelMatrix.loadIdentity();
|
||||||
mTextureMatrix.loadIdentity();
|
mTextureMatrix.loadIdentity();
|
||||||
ClearClipSplit();
|
ClearClipSplit();
|
||||||
|
@ -488,6 +491,11 @@ public:
|
||||||
mStreamData.uDynLightColor.Z = b;
|
mStreamData.uDynLightColor.Z = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetDirectionalLight(FVector4 dl)
|
||||||
|
{
|
||||||
|
mStreamData.uDirectionalLight = { dl.X, dl.Y, dl.Z, dl.W };
|
||||||
|
}
|
||||||
|
|
||||||
void SetScreenFade(float f)
|
void SetScreenFade(float f)
|
||||||
{
|
{
|
||||||
// This component is otherwise unused.
|
// This component is otherwise unused.
|
||||||
|
|
|
@ -208,6 +208,8 @@ static const char *shaderBindings = R"(
|
||||||
vec4 uDetailParms;
|
vec4 uDetailParms;
|
||||||
vec4 uNpotEmulation;
|
vec4 uNpotEmulation;
|
||||||
vec4 padding1, padding2, padding3;
|
vec4 padding1, padding2, padding3;
|
||||||
|
|
||||||
|
vec4 uDirectionalLight;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(set = 0, binding = 3, std140) uniform StreamUBO {
|
layout(set = 0, binding = 3, std140) uniform StreamUBO {
|
||||||
|
@ -299,6 +301,7 @@ static const char *shaderBindings = R"(
|
||||||
#define uSplitBottomPlane data[uDataIndex].uSplitBottomPlane
|
#define uSplitBottomPlane data[uDataIndex].uSplitBottomPlane
|
||||||
#define uDetailParms data[uDataIndex].uDetailParms
|
#define uDetailParms data[uDataIndex].uDetailParms
|
||||||
#define uNpotEmulation data[uDataIndex].uNpotEmulation
|
#define uNpotEmulation data[uDataIndex].uNpotEmulation
|
||||||
|
#define uDirectionalLight data[uDataIndex].uDirectionalLight
|
||||||
|
|
||||||
#define SUPPORTS_SHADOWMAPS
|
#define SUPPORTS_SHADOWMAPS
|
||||||
#define VULKAN_COORDINATE_SYSTEM
|
#define VULKAN_COORDINATE_SYSTEM
|
||||||
|
|
|
@ -1757,6 +1757,9 @@ void FLevelLocals::Init()
|
||||||
|
|
||||||
pixelstretch = info->pixelstretch;
|
pixelstretch = info->pixelstretch;
|
||||||
|
|
||||||
|
DirectionalLightMode = info->DirectionalLightMode;
|
||||||
|
DirectionalLight = info->DirectionalLight;
|
||||||
|
|
||||||
compatflags.Callback();
|
compatflags.Callback();
|
||||||
compatflags2.Callback();
|
compatflags2.Callback();
|
||||||
|
|
||||||
|
|
|
@ -685,6 +685,8 @@ public:
|
||||||
bool lightadditivesurfaces;
|
bool lightadditivesurfaces;
|
||||||
bool notexturefill;
|
bool notexturefill;
|
||||||
int ImpactDecalCount;
|
int ImpactDecalCount;
|
||||||
|
int8_t DirectionalLightMode;
|
||||||
|
FVector4 DirectionalLight;
|
||||||
|
|
||||||
FDynamicLight *lights;
|
FDynamicLight *lights;
|
||||||
|
|
||||||
|
|
|
@ -290,6 +290,8 @@ void level_info_t::Reset()
|
||||||
outsidefogdensity = 0;
|
outsidefogdensity = 0;
|
||||||
skyfog = 0;
|
skyfog = 0;
|
||||||
pixelstretch = 1.2f;
|
pixelstretch = 1.2f;
|
||||||
|
DirectionalLightMode = 0;
|
||||||
|
DirectionalLight = FVector4(0, 0, 0, 0);
|
||||||
|
|
||||||
specialactions.Clear();
|
specialactions.Clear();
|
||||||
DefaultEnvironment = 0;
|
DefaultEnvironment = 0;
|
||||||
|
@ -1436,6 +1438,29 @@ DEFINE_MAP_OPTION(pixelratio, false)
|
||||||
info->pixelstretch = (float)parse.sc.Float;
|
info->pixelstretch = (float)parse.sc.Float;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_MAP_OPTION(DirectionalLightMode, false)
|
||||||
|
{
|
||||||
|
parse.ParseAssign();
|
||||||
|
parse.sc.MustGetNumber();
|
||||||
|
info->DirectionalLightMode = (int8_t)clamp(parse.sc.Number, 0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_MAP_OPTION(DirectionalLight, true)
|
||||||
|
{
|
||||||
|
parse.ParseAssign();
|
||||||
|
parse.sc.MustGetFloat();
|
||||||
|
info->DirectionalLight.X = (float)parse.sc.Float;
|
||||||
|
if (parse.format_type == FMapInfoParser::FMT_New) parse.sc.MustGetStringName(",");
|
||||||
|
parse.sc.MustGetFloat();
|
||||||
|
info->DirectionalLight.Y = (float)parse.sc.Float;
|
||||||
|
if (parse.format_type == FMapInfoParser::FMT_New) parse.sc.MustGetStringName(",");
|
||||||
|
parse.sc.MustGetFloat();
|
||||||
|
info->DirectionalLight.Z = (float)parse.sc.Float;
|
||||||
|
info->DirectionalLight.MakeUnit();
|
||||||
|
if (parse.format_type == FMapInfoParser::FMT_New) parse.sc.MustGetStringName(",");
|
||||||
|
parse.sc.MustGetFloat();
|
||||||
|
info->DirectionalLight.W = (float)parse.sc.Float;
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_MAP_OPTION(brightfog, false)
|
DEFINE_MAP_OPTION(brightfog, false)
|
||||||
{
|
{
|
||||||
|
|
|
@ -364,6 +364,8 @@ struct level_info_t
|
||||||
int outsidefogdensity;
|
int outsidefogdensity;
|
||||||
int skyfog;
|
int skyfog;
|
||||||
float pixelstretch;
|
float pixelstretch;
|
||||||
|
int8_t DirectionalLightMode;
|
||||||
|
FVector4 DirectionalLight;
|
||||||
|
|
||||||
// Redirection: If any player is carrying the specified item, then
|
// Redirection: If any player is carrying the specified item, then
|
||||||
// you go to the RedirectMap instead of this one.
|
// you go to the RedirectMap instead of this one.
|
||||||
|
|
|
@ -996,7 +996,8 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload)
|
||||||
("scrolls", Scrolls)
|
("scrolls", Scrolls)
|
||||||
("automap", automap)
|
("automap", automap)
|
||||||
("interpolator", interpolator)
|
("interpolator", interpolator)
|
||||||
("frozenstate", frozenstate);
|
("frozenstate", frozenstate)
|
||||||
|
("directionallight", DirectionalLight);
|
||||||
|
|
||||||
|
|
||||||
// Hub transitions must keep the current total time
|
// Hub transitions must keep the current total time
|
||||||
|
|
|
@ -221,7 +221,7 @@ void RenderHUDModel(FModelRenderer *renderer, DPSprite *psp, float ofsX, float o
|
||||||
|
|
||||||
float orientation = smf->xscale * smf->yscale * smf->zscale;
|
float orientation = smf->xscale * smf->yscale * smf->zscale;
|
||||||
|
|
||||||
renderer->BeginDrawHUDModel(playermo->RenderStyle, objectToWorldMatrix, orientation < 0);
|
renderer->BeginDrawHUDModel(playermo->RenderStyle, smf, objectToWorldMatrix, orientation < 0);
|
||||||
uint32_t trans = psp->GetTranslation() != 0 ? psp->GetTranslation() : 0;
|
uint32_t trans = psp->GetTranslation() != 0 ? psp->GetTranslation() : 0;
|
||||||
if ((psp->Flags & PSPF_PLAYERTRANSLATED)) trans = psp->Owner->mo->Translation;
|
if ((psp->Flags & PSPF_PLAYERTRANSLATED)) trans = psp->Owner->mo->Translation;
|
||||||
RenderFrameModels(renderer, playermo->Level, smf, psp->GetState(), psp->GetTics(), psp->Caller->GetClass(), trans);
|
RenderFrameModels(renderer, playermo->Level, smf, psp->GetState(), psp->GetTics(), psp->Caller->GetClass(), trans);
|
||||||
|
@ -783,6 +783,10 @@ static void ParseModelDefLump(int Lump)
|
||||||
smf.rotationCenterY = 0.;
|
smf.rotationCenterY = 0.;
|
||||||
smf.rotationCenterZ = 0.;
|
smf.rotationCenterZ = 0.;
|
||||||
}
|
}
|
||||||
|
else if (sc.Compare("nodirectionallight"))
|
||||||
|
{
|
||||||
|
smf.flags |= MDL_NODIRECTIONALLIGHT;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sc.ScriptMessage("Unrecognized string \"%s\"", sc.String);
|
sc.ScriptMessage("Unrecognized string \"%s\"", sc.String);
|
||||||
|
|
|
@ -57,6 +57,7 @@ enum
|
||||||
MDL_USEROTATIONCENTER = 512,
|
MDL_USEROTATIONCENTER = 512,
|
||||||
MDL_NOPERPIXELLIGHTING = 1024, // forces a model to not use per-pixel lighting. useful for voxel-converted-to-model objects.
|
MDL_NOPERPIXELLIGHTING = 1024, // forces a model to not use per-pixel lighting. useful for voxel-converted-to-model objects.
|
||||||
MDL_SCALEWEAPONFOV = 2048, // scale weapon view model with higher user FOVs
|
MDL_SCALEWEAPONFOV = 2048, // scale weapon view model with higher user FOVs
|
||||||
|
MDL_NODIRECTIONALLIGHT = 4096, // disables directional light shading
|
||||||
};
|
};
|
||||||
|
|
||||||
FSpriteModelFrame * FindModelFrame(const PClass * ti, int sprite, int frame, bool dropped);
|
FSpriteModelFrame * FindModelFrame(const PClass * ti, int sprite, int frame, bool dropped);
|
||||||
|
|
|
@ -67,17 +67,23 @@ void FHWModelRenderer::BeginDrawModel(FRenderStyle style, FSpriteModelFrame *smf
|
||||||
|
|
||||||
state.mModelMatrix = objectToWorldMatrix;
|
state.mModelMatrix = objectToWorldMatrix;
|
||||||
state.EnableModelMatrix(true);
|
state.EnableModelMatrix(true);
|
||||||
|
|
||||||
|
if (level.info->DirectionalLightMode >= 1 && !(smf->flags & MDL_NODIRECTIONALLIGHT))
|
||||||
|
{
|
||||||
|
state.SetDirectionalLight(di->GetDirectionalLight());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FHWModelRenderer::EndDrawModel(FRenderStyle style, FSpriteModelFrame *smf)
|
void FHWModelRenderer::EndDrawModel(FRenderStyle style, FSpriteModelFrame *smf)
|
||||||
{
|
{
|
||||||
|
state.SetDirectionalLight(FVector4(0.f, 0.f, 0.f, 0.f));
|
||||||
state.EnableModelMatrix(false);
|
state.EnableModelMatrix(false);
|
||||||
state.SetDepthFunc(DF_Less);
|
state.SetDepthFunc(DF_Less);
|
||||||
if (!(style == DefaultRenderStyle()) && !(smf->flags & MDL_DONTCULLBACKFACES))
|
if (!(style == DefaultRenderStyle()) && !(smf->flags & MDL_DONTCULLBACKFACES))
|
||||||
state.SetCulling(Cull_None);
|
state.SetCulling(Cull_None);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FHWModelRenderer::BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored)
|
void FHWModelRenderer::BeginDrawHUDModel(FRenderStyle style, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored)
|
||||||
{
|
{
|
||||||
state.SetDepthFunc(DF_LEqual);
|
state.SetDepthFunc(DF_LEqual);
|
||||||
|
|
||||||
|
@ -91,10 +97,16 @@ void FHWModelRenderer::BeginDrawHUDModel(FRenderStyle style, const VSMatrix &obj
|
||||||
|
|
||||||
state.mModelMatrix = objectToWorldMatrix;
|
state.mModelMatrix = objectToWorldMatrix;
|
||||||
state.EnableModelMatrix(true);
|
state.EnableModelMatrix(true);
|
||||||
|
|
||||||
|
if (level.info->DirectionalLightMode >= 1 && !(smf->flags & MDL_NODIRECTIONALLIGHT))
|
||||||
|
{
|
||||||
|
state.SetDirectionalLight(di->GetDirectionalLight());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FHWModelRenderer::EndDrawHUDModel(FRenderStyle style)
|
void FHWModelRenderer::EndDrawHUDModel(FRenderStyle style)
|
||||||
{
|
{
|
||||||
|
state.SetDirectionalLight(FVector4(0.f, 0.f, 0.f, 0.f));
|
||||||
state.EnableModelMatrix(false);
|
state.EnableModelMatrix(false);
|
||||||
|
|
||||||
state.SetDepthFunc(DF_Less);
|
state.SetDepthFunc(DF_Less);
|
||||||
|
|
|
@ -49,7 +49,7 @@ public:
|
||||||
void EndDrawModel(FRenderStyle style, FSpriteModelFrame *smf) override;
|
void EndDrawModel(FRenderStyle style, FSpriteModelFrame *smf) override;
|
||||||
IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) override;
|
IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) override;
|
||||||
VSMatrix GetViewToWorldMatrix() override;
|
VSMatrix GetViewToWorldMatrix() override;
|
||||||
void BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored) override;
|
void BeginDrawHUDModel(FRenderStyle style, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix, bool mirrored) override;
|
||||||
void EndDrawHUDModel(FRenderStyle style) override;
|
void EndDrawHUDModel(FRenderStyle style) override;
|
||||||
void SetInterpolation(double interpolation) override;
|
void SetInterpolation(double interpolation) override;
|
||||||
void SetMaterial(FGameTexture *skin, bool clampNoFilter, int translation) override;
|
void SetMaterial(FGameTexture *skin, bool clampNoFilter, int translation) override;
|
||||||
|
|
|
@ -78,6 +78,13 @@ void HWDecal::DrawDecal(HWDrawInfo *di, FRenderState &state)
|
||||||
state.SetRenderStyle(decal->RenderStyle);
|
state.SetRenderStyle(decal->RenderStyle);
|
||||||
state.SetMaterial(texture, UF_Sprite, 0, CLAMP_XY, decal->Translation, -1);
|
state.SetMaterial(texture, UF_Sprite, 0, CLAMP_XY, decal->Translation, -1);
|
||||||
|
|
||||||
|
// only enable directional lighting if the DL mode is enabled for the entire map.
|
||||||
|
// IMO it doesn't make sense to enable DL on decals if the DL mode is set to "models only".
|
||||||
|
if (level.info->DirectionalLightMode == 2)
|
||||||
|
{
|
||||||
|
state.SetDirectionalLight(di->GetDirectionalLight());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// If srcalpha is one it looks better with a higher alpha threshold
|
// If srcalpha is one it looks better with a higher alpha threshold
|
||||||
if (decal->RenderStyle.SrcAlpha == STYLEALPHA_One) state.AlphaFunc(Alpha_GEqual, gl_mask_sprite_threshold);
|
if (decal->RenderStyle.SrcAlpha == STYLEALPHA_One) state.AlphaFunc(Alpha_GEqual, gl_mask_sprite_threshold);
|
||||||
|
@ -131,6 +138,7 @@ void HWDecal::DrawDecal(HWDrawInfo *di, FRenderState &state)
|
||||||
state.SetObjectColor(0xffffffff);
|
state.SetObjectColor(0xffffffff);
|
||||||
state.SetFog(fc, -1);
|
state.SetFog(fc, -1);
|
||||||
state.SetDynLight(0, 0, 0);
|
state.SetDynLight(0, 0, 0);
|
||||||
|
state.SetDirectionalLight(FVector4(0.f, 0.f, 0.f, 0.f));
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -212,6 +212,7 @@ private:
|
||||||
PalEntry CalcLightColor(int light, PalEntry pe, int blendfactor);
|
PalEntry CalcLightColor(int light, PalEntry pe, int blendfactor);
|
||||||
float GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity, int blendfactor);
|
float GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity, int blendfactor);
|
||||||
bool CheckFog(sector_t *frontsector, sector_t *backsector);
|
bool CheckFog(sector_t *frontsector, sector_t *backsector);
|
||||||
|
FVector4 GetDirectionalLight(void);
|
||||||
WeaponLighting GetWeaponLighting(sector_t *viewsector, const DVector3 &pos, int cm, area_t in_area, const DVector3 &playerpos);
|
WeaponLighting GetWeaponLighting(sector_t *viewsector, const DVector3 &pos, int cm, area_t in_area, const DVector3 &playerpos);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -334,6 +334,10 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
|
||||||
{
|
{
|
||||||
if (sector->special != GLSector_Skybox)
|
if (sector->special != GLSector_Skybox)
|
||||||
{
|
{
|
||||||
|
if (level.info->DirectionalLightMode == 2)
|
||||||
|
{
|
||||||
|
state.SetDirectionalLight(di->GetDirectionalLight());
|
||||||
|
}
|
||||||
state.SetMaterial(texture, UF_Texture, 0, CLAMP_NONE, 0, -1);
|
state.SetMaterial(texture, UF_Texture, 0, CLAMP_NONE, 0, -1);
|
||||||
SetPlaneTextureRotation(state, &plane, texture);
|
SetPlaneTextureRotation(state, &plane, texture);
|
||||||
DrawSubsectors(di, state);
|
DrawSubsectors(di, state);
|
||||||
|
@ -362,6 +366,10 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
|
||||||
{
|
{
|
||||||
if (!texture->GetTranslucency()) state.AlphaFunc(Alpha_GEqual, gl_mask_threshold);
|
if (!texture->GetTranslucency()) state.AlphaFunc(Alpha_GEqual, gl_mask_threshold);
|
||||||
else state.AlphaFunc(Alpha_GEqual, 0.f);
|
else state.AlphaFunc(Alpha_GEqual, 0.f);
|
||||||
|
if (level.info->DirectionalLightMode == 2)
|
||||||
|
{
|
||||||
|
state.SetDirectionalLight(di->GetDirectionalLight());
|
||||||
|
}
|
||||||
state.SetMaterial(texture, UF_Texture, 0, CLAMP_NONE, 0, -1);
|
state.SetMaterial(texture, UF_Texture, 0, CLAMP_NONE, 0, -1);
|
||||||
SetPlaneTextureRotation(state, &plane, texture);
|
SetPlaneTextureRotation(state, &plane, texture);
|
||||||
DrawSubsectors(di, state);
|
DrawSubsectors(di, state);
|
||||||
|
@ -369,6 +377,7 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
|
||||||
}
|
}
|
||||||
state.SetRenderStyle(DefaultRenderStyle());
|
state.SetRenderStyle(DefaultRenderStyle());
|
||||||
}
|
}
|
||||||
|
state.SetDirectionalLight(FVector4(0.f, 0.f, 0.f, 0.f));
|
||||||
state.SetObjectColor(0xffffffff);
|
state.SetObjectColor(0xffffffff);
|
||||||
state.SetAddColor(0);
|
state.SetAddColor(0);
|
||||||
state.ApplyTextureManipulation(nullptr);
|
state.ApplyTextureManipulation(nullptr);
|
||||||
|
|
|
@ -280,3 +280,7 @@ bool HWDrawInfo::CheckFog(sector_t *frontsector, sector_t *backsector)
|
||||||
backsector->GetTexture(sector_t::ceiling)!=skyflatnum));
|
backsector->GetTexture(sector_t::ceiling)!=skyflatnum));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FVector4 HWDrawInfo::GetDirectionalLight(void)
|
||||||
|
{
|
||||||
|
return Level->DirectionalLight;
|
||||||
|
}
|
||||||
|
|
|
@ -231,6 +231,10 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
|
||||||
state.SetObjectColor2((color1 != color2) ? color2 : PalEntry(0));
|
state.SetObjectColor2((color1 != color2) ? color2 : PalEntry(0));
|
||||||
state.SetAddColor(side->GetAdditiveColor(tierndx, frontsector));
|
state.SetAddColor(side->GetAdditiveColor(tierndx, frontsector));
|
||||||
state.ApplyTextureManipulation(&tier.TextureFx);
|
state.ApplyTextureManipulation(&tier.TextureFx);
|
||||||
|
if (level.info->DirectionalLightMode == 2)
|
||||||
|
{
|
||||||
|
state.SetDirectionalLight(di->GetDirectionalLight());
|
||||||
|
}
|
||||||
|
|
||||||
if (color1 != color2)
|
if (color1 != color2)
|
||||||
{
|
{
|
||||||
|
@ -304,6 +308,7 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
|
||||||
state.EnableGlow(false);
|
state.EnableGlow(false);
|
||||||
state.EnableGradient(false);
|
state.EnableGradient(false);
|
||||||
state.ApplyTextureManipulation(nullptr);
|
state.ApplyTextureManipulation(nullptr);
|
||||||
|
state.SetDirectionalLight(FVector4(0.f, 0.f, 0.f, 0.f));
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -2481,6 +2481,55 @@ DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, setFrozen, setFrozen)
|
||||||
//
|
//
|
||||||
//=====================================================================================
|
//=====================================================================================
|
||||||
|
|
||||||
|
static void SetDirectionalLight(FLevelLocals *self, double x, double y, double z, double strength)
|
||||||
|
{
|
||||||
|
// normalize the vector
|
||||||
|
DVector3 dlv = DVector3(x, y, z);
|
||||||
|
dlv.MakeUnit();
|
||||||
|
self->DirectionalLight = FVector4(static_cast<float>(dlv.X), static_cast<float>(dlv.Y), static_cast<float>(dlv.Z), static_cast<float>(strength));
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, SetDirectionalLight, SetDirectionalLight)
|
||||||
|
{
|
||||||
|
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||||
|
PARAM_FLOAT(x);
|
||||||
|
PARAM_FLOAT(y);
|
||||||
|
PARAM_FLOAT(z);
|
||||||
|
PARAM_FLOAT(strength);
|
||||||
|
SetDirectionalLight(self, x, y, z, strength);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GetDirectionalLightVector(FLevelLocals *self, DVector3 *result)
|
||||||
|
{
|
||||||
|
*result = DVector3(self->DirectionalLight.X, self->DirectionalLight.Y, self->DirectionalLight.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, GetDirectionalLightVector, GetDirectionalLightVector)
|
||||||
|
{
|
||||||
|
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||||
|
DVector3 result;
|
||||||
|
GetDirectionalLightVector(self, &result);
|
||||||
|
ACTION_RETURN_VEC3(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static double GetDirectionalLightStrength(FLevelLocals *self)
|
||||||
|
{
|
||||||
|
return self->DirectionalLight.W;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, GetDirectionalLightStrength, GetDirectionalLightStrength)
|
||||||
|
{
|
||||||
|
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||||
|
ACTION_RETURN_FLOAT(GetDirectionalLightStrength(self));
|
||||||
|
}
|
||||||
|
|
||||||
|
//=====================================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//=====================================================================================
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_NATIVE(_AltHUD, GetLatency, Net_GetLatency)
|
DEFINE_ACTION_FUNCTION_NATIVE(_AltHUD, GetLatency, Net_GetLatency)
|
||||||
{
|
{
|
||||||
PARAM_PROLOGUE;
|
PARAM_PROLOGUE;
|
||||||
|
@ -2721,6 +2770,7 @@ DEFINE_FIELD(FLevelLocals, fogdensity)
|
||||||
DEFINE_FIELD(FLevelLocals, outsidefogdensity)
|
DEFINE_FIELD(FLevelLocals, outsidefogdensity)
|
||||||
DEFINE_FIELD(FLevelLocals, skyfog)
|
DEFINE_FIELD(FLevelLocals, skyfog)
|
||||||
DEFINE_FIELD(FLevelLocals, pixelstretch)
|
DEFINE_FIELD(FLevelLocals, pixelstretch)
|
||||||
|
DEFINE_FIELD(FLevelLocals, DirectionalLightMode)
|
||||||
DEFINE_FIELD(FLevelLocals, MusicVolume)
|
DEFINE_FIELD(FLevelLocals, MusicVolume)
|
||||||
DEFINE_FIELD(FLevelLocals, deathsequence)
|
DEFINE_FIELD(FLevelLocals, deathsequence)
|
||||||
DEFINE_FIELD_BIT(FLevelLocals, frozenstate, frozen, 1) // still needed for backwards compatibility.
|
DEFINE_FIELD_BIT(FLevelLocals, frozenstate, frozen, 1) // still needed for backwards compatibility.
|
||||||
|
|
|
@ -35,11 +35,24 @@ vec3 lightContribution(int i, vec3 normal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float lightDirectionalAttenuation(vec3 normal)
|
||||||
|
{
|
||||||
|
vec3 lightDirectionalDir = uDirectionalLight.xyz;
|
||||||
|
return clamp(dot(lightDirectionalDir, normal), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
vec3 ProcessMaterialLight(Material material, vec3 color)
|
vec3 ProcessMaterialLight(Material material, vec3 color)
|
||||||
{
|
{
|
||||||
vec4 dynlight = uDynLightColor;
|
vec4 dynlight = uDynLightColor;
|
||||||
vec3 normal = material.Normal;
|
vec3 normal = material.Normal;
|
||||||
|
|
||||||
|
if (uDirectionalLight.w != 0 && normal != vec3(0.0))
|
||||||
|
{
|
||||||
|
float lightDirectionalStrength = uDirectionalLight.w;
|
||||||
|
dynlight.rgb += color * lightDirectionalAttenuation(normal) * lightDirectionalStrength;
|
||||||
|
color *= 1.0 - lightDirectionalStrength;
|
||||||
|
}
|
||||||
|
|
||||||
if (uLightIndex >= 0)
|
if (uLightIndex >= 0)
|
||||||
{
|
{
|
||||||
ivec4 lightRange = ivec4(lights[uLightIndex]) + ivec4(uLightIndex + 1);
|
ivec4 lightRange = ivec4(lights[uLightIndex]) + ivec4(uLightIndex + 1);
|
||||||
|
|
|
@ -80,6 +80,36 @@ vec3 ProcessMaterialLight(Material material, vec3 ambientLight)
|
||||||
|
|
||||||
vec3 Lo = uDynLightColor.rgb;
|
vec3 Lo = uDynLightColor.rgb;
|
||||||
|
|
||||||
|
if (uDirectionalLight.w != 0 && N != vec3(0.0))
|
||||||
|
{
|
||||||
|
float lightDirectionalStrength = uDirectionalLight.w;
|
||||||
|
|
||||||
|
vec3 lightDirectionalDir = uDirectionalLight.xyz;
|
||||||
|
float attenuation = clamp(dot(N, lightDirectionalDir), 0.0, 1.0);
|
||||||
|
if (attenuation > 0.0)
|
||||||
|
{
|
||||||
|
vec3 H = normalize(V + lightDirectionalDir);
|
||||||
|
|
||||||
|
vec3 radiance = ambientLight.rgb * attenuation * lightDirectionalStrength;
|
||||||
|
|
||||||
|
// cook-torrance brdf
|
||||||
|
float NDF = DistributionGGX(N, H, roughness);
|
||||||
|
float G = GeometrySmith(N, V, lightDirectionalDir, roughness);
|
||||||
|
vec3 F = fresnelSchlick(clamp(dot(H, V), 0.0, 1.0), F0);
|
||||||
|
|
||||||
|
vec3 kS = F;
|
||||||
|
vec3 kD = (vec3(1.0) - kS) * (1.0 - metallic);
|
||||||
|
|
||||||
|
vec3 nominator = NDF * G * F;
|
||||||
|
float denominator = 4.0 * clamp(dot(N, V), 0.0, 1.0) * clamp(dot(N, lightDirectionalDir), 0.0, 1.0);
|
||||||
|
vec3 specular = nominator / max(denominator, 0.001);
|
||||||
|
|
||||||
|
Lo += (kD * albedo / PI + specular) * radiance;
|
||||||
|
}
|
||||||
|
|
||||||
|
ambientLight *= 1.0 - lightDirectionalStrength;
|
||||||
|
}
|
||||||
|
|
||||||
if (uLightIndex >= 0)
|
if (uLightIndex >= 0)
|
||||||
{
|
{
|
||||||
ivec4 lightRange = ivec4(lights[uLightIndex]) + ivec4(uLightIndex + 1);
|
ivec4 lightRange = ivec4(lights[uLightIndex]) + ivec4(uLightIndex + 1);
|
||||||
|
|
|
@ -34,6 +34,20 @@ vec2 lightAttenuation(int i, vec3 normal, vec3 viewdir, float lightcolorA)
|
||||||
return vec2(attenuation, attenuation * specularLevel * pow(specAngle, phExp));
|
return vec2(attenuation, attenuation * specularLevel * pow(specAngle, phExp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec2 lightDirectionalAttenuation(vec3 normal, vec3 viewdir)
|
||||||
|
{
|
||||||
|
vec3 lightDirectionalDir = uDirectionalLight.xyz;
|
||||||
|
float attenuation = clamp(dot(lightDirectionalDir, normal), 0.0, 1.0);
|
||||||
|
|
||||||
|
float glossiness = uSpecularMaterial.x;
|
||||||
|
float specularLevel = uSpecularMaterial.y;
|
||||||
|
|
||||||
|
vec3 halfdir = normalize(viewdir + lightDirectionalDir);
|
||||||
|
float specAngle = clamp(dot(halfdir, normal), 0.0f, 1.0f);
|
||||||
|
float phExp = glossiness * 4.0f;
|
||||||
|
return vec2(attenuation, attenuation * specularLevel * pow(specAngle, phExp));
|
||||||
|
}
|
||||||
|
|
||||||
vec3 ProcessMaterialLight(Material material, vec3 color)
|
vec3 ProcessMaterialLight(Material material, vec3 color)
|
||||||
{
|
{
|
||||||
vec4 dynlight = uDynLightColor;
|
vec4 dynlight = uDynLightColor;
|
||||||
|
@ -42,6 +56,15 @@ vec3 ProcessMaterialLight(Material material, vec3 color)
|
||||||
vec3 normal = material.Normal;
|
vec3 normal = material.Normal;
|
||||||
vec3 viewdir = normalize(uCameraPos.xyz - pixelpos.xyz);
|
vec3 viewdir = normalize(uCameraPos.xyz - pixelpos.xyz);
|
||||||
|
|
||||||
|
if (uDirectionalLight.w != 0 && normal != vec3(0.0))
|
||||||
|
{
|
||||||
|
float lightDirectionalStrength = uDirectionalLight.w;
|
||||||
|
vec2 lightLevelAttenuation = lightDirectionalAttenuation(normal, viewdir) * lightDirectionalStrength;
|
||||||
|
dynlight.rgb += color * lightLevelAttenuation.x;
|
||||||
|
specular.rgb += color * lightLevelAttenuation.y;
|
||||||
|
color *= 1.0 - lightDirectionalStrength;
|
||||||
|
}
|
||||||
|
|
||||||
if (uLightIndex >= 0)
|
if (uLightIndex >= 0)
|
||||||
{
|
{
|
||||||
ivec4 lightRange = ivec4(lights[uLightIndex]) + ivec4(uLightIndex + 1);
|
ivec4 lightRange = ivec4(lights[uLightIndex]) + ivec4(uLightIndex + 1);
|
||||||
|
|
|
@ -442,12 +442,17 @@ struct LevelLocals native
|
||||||
native readonly int outsidefogdensity;
|
native readonly int outsidefogdensity;
|
||||||
native readonly int skyfog;
|
native readonly int skyfog;
|
||||||
native readonly float pixelstretch;
|
native readonly float pixelstretch;
|
||||||
|
native readonly int8 DirectionalLightMode;
|
||||||
native readonly float MusicVolume;
|
native readonly float MusicVolume;
|
||||||
native name deathsequence;
|
native name deathsequence;
|
||||||
native readonly int compatflags;
|
native readonly int compatflags;
|
||||||
native readonly int compatflags2;
|
native readonly int compatflags2;
|
||||||
native readonly LevelInfo info;
|
native readonly LevelInfo info;
|
||||||
|
|
||||||
|
native void SetDirectionalLight(double x, double y, double z, double strength);
|
||||||
|
native Vector3 GetDirectionalLightVector(void);
|
||||||
|
native double GetDirectionalLightStrength(void);
|
||||||
|
|
||||||
native String GetUDMFString(int type, int index, Name key);
|
native String GetUDMFString(int type, int index, Name key);
|
||||||
native int GetUDMFInt(int type, int index, Name key);
|
native int GetUDMFInt(int type, int index, Name key);
|
||||||
native double GetUDMFFloat(int type, int index, Name key);
|
native double GetUDMFFloat(int type, int index, Name key);
|
||||||
|
|
Loading…
Reference in a new issue