mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-03-18 08:51:15 +00:00
Merge branch 'materials' of https://github.com/coelckers/gzdoom
This commit is contained in:
commit
42dce912b4
14 changed files with 427 additions and 84 deletions
|
@ -56,6 +56,7 @@
|
|||
int ScriptDepth;
|
||||
void gl_InitGlow(FScanner &sc);
|
||||
void gl_ParseBrightmap(FScanner &sc, int);
|
||||
void gl_ParseMaterial(FScanner &sc, int);
|
||||
void gl_DestroyUserShaders();
|
||||
void gl_ParseHardwareShader(FScanner &sc, int deflump);
|
||||
void gl_ParseDetailTexture(FScanner &sc);
|
||||
|
@ -963,7 +964,8 @@ static const char *CoreKeywords[]=
|
|||
"hardwareshader",
|
||||
"detail",
|
||||
"#include",
|
||||
NULL
|
||||
"material",
|
||||
nullptr
|
||||
};
|
||||
|
||||
|
||||
|
@ -985,6 +987,7 @@ enum
|
|||
TAG_HARDWARESHADER,
|
||||
TAG_DETAIL,
|
||||
TAG_INCLUDE,
|
||||
TAG_MATERIAL
|
||||
};
|
||||
|
||||
|
||||
|
@ -1342,6 +1345,9 @@ static void DoParseDefs(FScanner &sc, int workingLump)
|
|||
case TAG_BRIGHTMAP:
|
||||
gl_ParseBrightmap(sc, workingLump);
|
||||
break;
|
||||
case TAG_MATERIAL:
|
||||
gl_ParseMaterial(sc, workingLump);
|
||||
break;
|
||||
case TAG_HARDWARESHADER:
|
||||
gl_ParseHardwareShader(sc, workingLump);
|
||||
break;
|
||||
|
|
|
@ -87,6 +87,8 @@ void FRenderState::Reset()
|
|||
mSpecialEffect = EFF_NONE;
|
||||
mClipHeight = 0.f;
|
||||
mClipHeightDirection = 0.f;
|
||||
mGlossiness = 0.0f;
|
||||
mSpecularLevel = 0.0f;
|
||||
mShaderTimer = 0.0f;
|
||||
ClearClipSplit();
|
||||
|
||||
|
@ -137,7 +139,7 @@ bool FRenderState::ApplyShader()
|
|||
}
|
||||
else
|
||||
{
|
||||
activeShader = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : 4, mAlphaThreshold >= 0.f, mPassType);
|
||||
activeShader = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : SHADER_NoTexture, mAlphaThreshold >= 0.f, mPassType);
|
||||
activeShader->Bind();
|
||||
}
|
||||
|
||||
|
@ -178,6 +180,7 @@ bool FRenderState::ApplyShader()
|
|||
activeShader->muLightIndex.Set(mLightIndex); // will always be -1 for now
|
||||
activeShader->muClipSplit.Set(mClipSplit);
|
||||
activeShader->muViewHeight.Set(viewheight);
|
||||
activeShader->muSpecularMaterial.Set(mGlossiness, mSpecularLevel);
|
||||
|
||||
if (mGlowEnabled)
|
||||
{
|
||||
|
|
|
@ -94,6 +94,7 @@ class FRenderState
|
|||
bool mLastDepthClamp;
|
||||
float mInterpolationFactor;
|
||||
float mClipHeight, mClipHeightDirection;
|
||||
float mGlossiness, mSpecularLevel;
|
||||
float mShaderTimer;
|
||||
|
||||
FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer;
|
||||
|
@ -152,6 +153,7 @@ public:
|
|||
}
|
||||
mEffectState = overrideshader >= 0? overrideshader : mat->mShaderIndex;
|
||||
mShaderTimer = mat->tex->gl_info.shaderspeed;
|
||||
SetSpecular(mat->tex->gl_info.Glossiness, mat->tex->gl_info.SpecularLevel);
|
||||
mat->Bind(clampmode, translation);
|
||||
}
|
||||
|
||||
|
@ -386,6 +388,12 @@ public:
|
|||
mObjectColor2 = pe;
|
||||
}
|
||||
|
||||
void SetSpecular(float glossiness, float specularLevel)
|
||||
{
|
||||
mGlossiness = glossiness;
|
||||
mSpecularLevel = specularLevel;
|
||||
}
|
||||
|
||||
void SetFog(PalEntry c, float d)
|
||||
{
|
||||
const float LOG2E = 1.442692f; // = 1/log(2)
|
||||
|
|
|
@ -991,7 +991,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
|
|||
{
|
||||
// Todo: implement shader selection here
|
||||
RenderStyle = LegacyRenderStyles[STYLE_Translucent];
|
||||
OverrideShader = gl_fuzztype + 4;
|
||||
OverrideShader = SHADER_NoTexture + gl_fuzztype;
|
||||
trans = 0.99f; // trans may not be 1 here
|
||||
hw_styleflags = STYLEHW_NoAlphaTest;
|
||||
}
|
||||
|
|
|
@ -355,7 +355,7 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
{
|
||||
// Todo: implement shader selection here
|
||||
RenderStyle = LegacyRenderStyles[STYLE_Translucent];
|
||||
OverrideShader = gl_fuzztype + 4;
|
||||
OverrideShader = SHADER_NoTexture + gl_fuzztype;
|
||||
trans = 0.99f; // trans may not be 1 here
|
||||
}
|
||||
else
|
||||
|
|
|
@ -254,6 +254,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
|||
muClipHeight.Init(hShader, "uClipHeight");
|
||||
muClipHeightDirection.Init(hShader, "uClipHeightDirection");
|
||||
muAlphaThreshold.Init(hShader, "uAlphaThreshold");
|
||||
muSpecularMaterial.Init(hShader, "uSpecularMaterial");
|
||||
muViewHeight.Init(hShader, "uViewHeight");
|
||||
muTimer.Init(hShader, "timer");
|
||||
|
||||
|
@ -326,9 +327,10 @@ bool FShader::Bind()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FShader *FShaderCollection::Compile (const char *ShaderName, const char *ShaderPath, bool usediscard, EPassType passType)
|
||||
FShader *FShaderCollection::Compile (const char *ShaderName, const char *ShaderPath, const char *shaderdefines, bool usediscard, EPassType passType)
|
||||
{
|
||||
FString defines;
|
||||
defines += shaderdefines;
|
||||
// this can't be in the shader code due to ATI strangeness.
|
||||
if (gl.MaxLights() == 128) defines += "#define MAXLIGHTS128\n";
|
||||
if (!usediscard) defines += "#define NO_ALPHATEST\n";
|
||||
|
@ -375,26 +377,30 @@ struct FDefaultShader
|
|||
{
|
||||
const char * ShaderName;
|
||||
const char * gettexelfunc;
|
||||
const char * Defines;
|
||||
};
|
||||
|
||||
// Note: the FIRST_USER_SHADER constant in gl_shader.h needs
|
||||
// to be updated whenever the size of this array is modified.
|
||||
// Note: the MaterialShaderIndex enum in gl_shader.h needs to be updated whenever this array is modified.
|
||||
static const FDefaultShader defaultshaders[]=
|
||||
{
|
||||
{"Default", "shaders/glsl/func_normal.fp"},
|
||||
{"Warp 1", "shaders/glsl/func_warp1.fp"},
|
||||
{"Warp 2", "shaders/glsl/func_warp2.fp"},
|
||||
{"Brightmap","shaders/glsl/func_brightmap.fp"},
|
||||
{"No Texture", "shaders/glsl/func_notexture.fp"},
|
||||
{"Basic Fuzz", "shaders/glsl/fuzz_standard.fp"},
|
||||
{"Smooth Fuzz", "shaders/glsl/fuzz_smooth.fp"},
|
||||
{"Swirly Fuzz", "shaders/glsl/fuzz_swirly.fp"},
|
||||
{"Translucent Fuzz", "shaders/glsl/fuzz_smoothtranslucent.fp"},
|
||||
{"Jagged Fuzz", "shaders/glsl/fuzz_jagged.fp"},
|
||||
{"Noise Fuzz", "shaders/glsl/fuzz_noise.fp"},
|
||||
{"Smooth Noise Fuzz", "shaders/glsl/fuzz_smoothnoise.fp"},
|
||||
{"Software Fuzz", "shaders/glsl/fuzz_software.fp"},
|
||||
{NULL,NULL}
|
||||
{"Default", "shaders/glsl/func_normal.fp", ""},
|
||||
{"Warp 1", "shaders/glsl/func_warp1.fp", ""},
|
||||
{"Warp 2", "shaders/glsl/func_warp2.fp", ""},
|
||||
{"Brightmap","shaders/glsl/func_brightmap.fp", ""},
|
||||
{"Specular","shaders/glsl/func_normal.fp", "#define SPECULAR\n"},
|
||||
{"SpecularBrightmap","shaders/glsl/func_brightmap.fp", "#define SPECULAR\n"},
|
||||
{"PBR","shaders/glsl/func_normal.fp", "#define PBR\n"},
|
||||
{"PBRBrightmap","shaders/glsl/func_brightmap.fp", "#define PBR\n"},
|
||||
{"No Texture", "shaders/glsl/func_notexture.fp", ""},
|
||||
{"Basic Fuzz", "shaders/glsl/fuzz_standard.fp", ""},
|
||||
{"Smooth Fuzz", "shaders/glsl/fuzz_smooth.fp", ""},
|
||||
{"Swirly Fuzz", "shaders/glsl/fuzz_swirly.fp", ""},
|
||||
{"Translucent Fuzz", "shaders/glsl/fuzz_smoothtranslucent.fp", ""},
|
||||
{"Jagged Fuzz", "shaders/glsl/fuzz_jagged.fp", ""},
|
||||
{"Noise Fuzz", "shaders/glsl/fuzz_noise.fp", ""},
|
||||
{"Smooth Noise Fuzz", "shaders/glsl/fuzz_smoothnoise.fp", ""},
|
||||
{"Software Fuzz", "shaders/glsl/fuzz_software.fp", ""},
|
||||
{NULL,NULL,NULL}
|
||||
};
|
||||
|
||||
static TArray<FString> usershaders;
|
||||
|
@ -524,8 +530,8 @@ FShaderCollection::~FShaderCollection()
|
|||
|
||||
void FShaderCollection::CompileShaders(EPassType passType)
|
||||
{
|
||||
mTextureEffects.Clear();
|
||||
mTextureEffectsNAT.Clear();
|
||||
mMaterialShaders.Clear();
|
||||
mMaterialShadersNAT.Clear();
|
||||
for (int i = 0; i < MAX_EFFECTS; i++)
|
||||
{
|
||||
mEffectShaders[i] = NULL;
|
||||
|
@ -533,12 +539,12 @@ void FShaderCollection::CompileShaders(EPassType passType)
|
|||
|
||||
for(int i=0;defaultshaders[i].ShaderName != NULL;i++)
|
||||
{
|
||||
FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, true, passType);
|
||||
mTextureEffects.Push(shc);
|
||||
if (i <= 3)
|
||||
FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, defaultshaders[i].Defines, true, passType);
|
||||
mMaterialShaders.Push(shc);
|
||||
if (i < SHADER_NoTexture)
|
||||
{
|
||||
FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, false, passType);
|
||||
mTextureEffectsNAT.Push(shc);
|
||||
FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, defaultshaders[i].Defines, false, passType);
|
||||
mMaterialShadersNAT.Push(shc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -547,8 +553,8 @@ void FShaderCollection::CompileShaders(EPassType passType)
|
|||
FString name = ExtractFileBase(usershaders[i]);
|
||||
FName sfn = name;
|
||||
|
||||
FShader *shc = Compile(sfn, usershaders[i], true, passType);
|
||||
mTextureEffects.Push(shc);
|
||||
FShader *shc = Compile(sfn, usershaders[i], "", true, passType);
|
||||
mMaterialShaders.Push(shc);
|
||||
}
|
||||
|
||||
for(int i=0;i<MAX_EFFECTS;i++)
|
||||
|
@ -571,21 +577,21 @@ void FShaderCollection::CompileShaders(EPassType passType)
|
|||
|
||||
void FShaderCollection::Clean()
|
||||
{
|
||||
for (unsigned int i = 0; i < mTextureEffectsNAT.Size(); i++)
|
||||
for (unsigned int i = 0; i < mMaterialShadersNAT.Size(); i++)
|
||||
{
|
||||
if (mTextureEffectsNAT[i] != NULL) delete mTextureEffectsNAT[i];
|
||||
if (mMaterialShadersNAT[i] != NULL) delete mMaterialShadersNAT[i];
|
||||
}
|
||||
for (unsigned int i = 0; i < mTextureEffects.Size(); i++)
|
||||
for (unsigned int i = 0; i < mMaterialShaders.Size(); i++)
|
||||
{
|
||||
if (mTextureEffects[i] != NULL) delete mTextureEffects[i];
|
||||
if (mMaterialShaders[i] != NULL) delete mMaterialShaders[i];
|
||||
}
|
||||
for (int i = 0; i < MAX_EFFECTS; i++)
|
||||
{
|
||||
if (mEffectShaders[i] != NULL) delete mEffectShaders[i];
|
||||
mEffectShaders[i] = NULL;
|
||||
}
|
||||
mTextureEffects.Clear();
|
||||
mTextureEffectsNAT.Clear();
|
||||
mMaterialShaders.Clear();
|
||||
mMaterialShadersNAT.Clear();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -598,9 +604,9 @@ int FShaderCollection::Find(const char * shn)
|
|||
{
|
||||
FName sfn = shn;
|
||||
|
||||
for(unsigned int i=0;i<mTextureEffects.Size();i++)
|
||||
for(unsigned int i=0;i<mMaterialShaders.Size();i++)
|
||||
{
|
||||
if (mTextureEffects[i]->mName == sfn)
|
||||
if (mMaterialShaders[i]->mName == sfn)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
@ -638,19 +644,19 @@ void FShaderCollection::ApplyMatrices(VSMatrix *proj, VSMatrix *view)
|
|||
VSMatrix norm;
|
||||
norm.computeNormalMatrix(*view);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (int i = 0; i < SHADER_NoTexture; i++)
|
||||
{
|
||||
mTextureEffects[i]->ApplyMatrices(proj, view, &norm);
|
||||
mTextureEffectsNAT[i]->ApplyMatrices(proj, view, &norm);
|
||||
mMaterialShaders[i]->ApplyMatrices(proj, view, &norm);
|
||||
mMaterialShadersNAT[i]->ApplyMatrices(proj, view, &norm);
|
||||
}
|
||||
mTextureEffects[4]->ApplyMatrices(proj, view, &norm);
|
||||
mMaterialShaders[SHADER_NoTexture]->ApplyMatrices(proj, view, &norm);
|
||||
if (gl_fuzztype != 0)
|
||||
{
|
||||
mTextureEffects[4 + gl_fuzztype]->ApplyMatrices(proj, view, &norm);
|
||||
mMaterialShaders[SHADER_NoTexture + gl_fuzztype]->ApplyMatrices(proj, view, &norm);
|
||||
}
|
||||
for (unsigned i = 12; i < mTextureEffects.Size(); i++)
|
||||
for (unsigned i = FIRST_USER_SHADER; i < mMaterialShaders.Size(); i++)
|
||||
{
|
||||
mTextureEffects[i]->ApplyMatrices(proj, view, &norm);
|
||||
mMaterialShaders[i]->ApplyMatrices(proj, view, &norm);
|
||||
}
|
||||
for (int i = 0; i < MAX_EFFECTS; i++)
|
||||
{
|
||||
|
|
|
@ -285,6 +285,7 @@ class FShader
|
|||
FBufferedUniform1f muClipHeightDirection;
|
||||
FBufferedUniform1f muAlphaThreshold;
|
||||
FBufferedUniform1i muViewHeight;
|
||||
FBufferedUniform2f muSpecularMaterial;
|
||||
FBufferedUniform1f muTimer;
|
||||
|
||||
int lights_index;
|
||||
|
@ -356,8 +357,8 @@ private:
|
|||
|
||||
class FShaderCollection
|
||||
{
|
||||
TArray<FShader*> mTextureEffects;
|
||||
TArray<FShader*> mTextureEffectsNAT;
|
||||
TArray<FShader*> mMaterialShaders;
|
||||
TArray<FShader*> mMaterialShadersNAT;
|
||||
FShader *mEffectShaders[MAX_EFFECTS];
|
||||
|
||||
void Clean();
|
||||
|
@ -366,20 +367,20 @@ class FShaderCollection
|
|||
public:
|
||||
FShaderCollection(EPassType passType);
|
||||
~FShaderCollection();
|
||||
FShader *Compile(const char *ShaderName, const char *ShaderPath, bool usediscard, EPassType passType);
|
||||
FShader *Compile(const char *ShaderName, const char *ShaderPath, const char *shaderdefines, bool usediscard, EPassType passType);
|
||||
int Find(const char *mame);
|
||||
FShader *BindEffect(int effect);
|
||||
void ApplyMatrices(VSMatrix *proj, VSMatrix *view);
|
||||
|
||||
void ResetFixedColormap()
|
||||
{
|
||||
for (unsigned i = 0; i < mTextureEffects.Size(); i++)
|
||||
for (unsigned i = 0; i < mMaterialShaders.Size(); i++)
|
||||
{
|
||||
mTextureEffects[i]->currentfixedcolormap = -1;
|
||||
mMaterialShaders[i]->currentfixedcolormap = -1;
|
||||
}
|
||||
for (unsigned i = 0; i < mTextureEffectsNAT.Size(); i++)
|
||||
for (unsigned i = 0; i < mMaterialShadersNAT.Size(); i++)
|
||||
{
|
||||
mTextureEffectsNAT[i]->currentfixedcolormap = -1;
|
||||
mMaterialShadersNAT[i]->currentfixedcolormap = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -388,17 +389,37 @@ public:
|
|||
// indices 0-2 match the warping modes, 3 is brightmap, 4 no texture, the following are custom
|
||||
if (!alphateston && eff <= 3)
|
||||
{
|
||||
return mTextureEffectsNAT[eff]; // Non-alphatest shaders are only created for default, warp1+2 and brightmap. The rest won't get used anyway
|
||||
return mMaterialShadersNAT[eff]; // Non-alphatest shaders are only created for default, warp1+2 and brightmap. The rest won't get used anyway
|
||||
}
|
||||
if (eff < mTextureEffects.Size())
|
||||
if (eff < mMaterialShaders.Size())
|
||||
{
|
||||
return mTextureEffects[eff];
|
||||
return mMaterialShaders[eff];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
#define FIRST_USER_SHADER 13
|
||||
enum MaterialShaderIndex
|
||||
{
|
||||
SHADER_Default,
|
||||
SHADER_Warp1,
|
||||
SHADER_Warp2,
|
||||
SHADER_Brightmap,
|
||||
SHADER_Specular,
|
||||
SHADER_SpecularBrightmap,
|
||||
SHADER_PBR,
|
||||
SHADER_PBRBrightmap,
|
||||
SHADER_NoTexture,
|
||||
SHADER_BasicFuzz,
|
||||
SHADER_SmoothFuzz,
|
||||
SHADER_SwirlyFuzz,
|
||||
SHADER_TranslucentFuzz,
|
||||
SHADER_JaggedFuzz,
|
||||
SHADER_NoiseFuzz,
|
||||
SHADER_SmoothNoiseFuzz,
|
||||
SHADER_SoftwareFuzz,
|
||||
FIRST_USER_SHADER
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
|
@ -438,7 +438,7 @@ int FMaterial::mMaxBound;
|
|||
|
||||
FMaterial::FMaterial(FTexture * tx, bool expanded)
|
||||
{
|
||||
mShaderIndex = 0;
|
||||
mShaderIndex = SHADER_Default;
|
||||
tex = tx;
|
||||
|
||||
// TODO: apply custom shader object here
|
||||
|
@ -449,7 +449,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded)
|
|||
*/
|
||||
if (tx->bWarped)
|
||||
{
|
||||
mShaderIndex = tx->bWarped;
|
||||
mShaderIndex = tx->bWarped; // This picks SHADER_Warp1 or SHADER_Warp2
|
||||
tx->gl_info.shaderspeed = static_cast<FWarpTexture*>(tx)->GetSpeed();
|
||||
}
|
||||
else if (tx->bHasCanvas)
|
||||
|
@ -468,13 +468,37 @@ FMaterial::FMaterial(FTexture * tx, bool expanded)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (tx->gl_info.Normal && tx->gl_info.Specular)
|
||||
{
|
||||
for (auto &texture : { tx->gl_info.Normal, tx->gl_info.Specular })
|
||||
{
|
||||
ValidateSysTexture(texture, expanded);
|
||||
mTextureLayers.Push({ texture, false });
|
||||
}
|
||||
mShaderIndex = SHADER_Specular;
|
||||
}
|
||||
else if (tx->gl_info.Normal && tx->gl_info.Metallic && tx->gl_info.Roughness && tx->gl_info.AmbientOcclusion)
|
||||
{
|
||||
for (auto &texture : { tx->gl_info.Normal, tx->gl_info.Metallic, tx->gl_info.Roughness, tx->gl_info.AmbientOcclusion })
|
||||
{
|
||||
ValidateSysTexture(texture, expanded);
|
||||
mTextureLayers.Push({ texture, false });
|
||||
}
|
||||
mShaderIndex = SHADER_PBR;
|
||||
}
|
||||
|
||||
tx->CreateDefaultBrightmap();
|
||||
if (tx->gl_info.Brightmap != NULL)
|
||||
{
|
||||
ValidateSysTexture(tx->gl_info.Brightmap, expanded);
|
||||
FTextureLayer layer = {tx->gl_info.Brightmap, false};
|
||||
mTextureLayers.Push(layer);
|
||||
mShaderIndex = 3;
|
||||
if (mShaderIndex == SHADER_Specular)
|
||||
mShaderIndex = SHADER_SpecularBrightmap;
|
||||
else if (mShaderIndex == SHADER_PBR)
|
||||
mShaderIndex = SHADER_PBRBrightmap;
|
||||
else
|
||||
mShaderIndex = SHADER_Brightmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -804,7 +828,7 @@ void FMaterial::GetTexCoordInfo(FTexCoordInfo *tci, float x, float y) const
|
|||
|
||||
int FMaterial::GetAreas(FloatRect **pAreas) const
|
||||
{
|
||||
if (mShaderIndex == 0) // texture splitting can only be done if there's no attached effects
|
||||
if (mShaderIndex == SHADER_Default) // texture splitting can only be done if there's no attached effects
|
||||
{
|
||||
FTexture *tex = mBaseLayer->tex;
|
||||
*pAreas = tex->gl_info.areas;
|
||||
|
|
|
@ -191,10 +191,17 @@ FTexture::MiscGLInfo::MiscGLInfo() throw()
|
|||
mIsTransparent = -1;
|
||||
shaderspeed = 1.f;
|
||||
shaderindex = 0;
|
||||
Glossiness = 10.0f;
|
||||
SpecularLevel = 0.1f;
|
||||
|
||||
Material[1] = Material[0] = NULL;
|
||||
SystemTexture[1] = SystemTexture[0] = NULL;
|
||||
Brightmap = NULL;
|
||||
Normal = NULL;
|
||||
Specular = NULL;
|
||||
Metallic = NULL;
|
||||
Roughness = NULL;
|
||||
AmbientOcclusion = NULL;
|
||||
}
|
||||
|
||||
FTexture::MiscGLInfo::~MiscGLInfo()
|
||||
|
@ -542,6 +549,124 @@ int FBrightmapTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotat
|
|||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Parses a material definition
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void gl_ParseMaterial(FScanner &sc, int deflump)
|
||||
{
|
||||
int type = FTexture::TEX_Any;
|
||||
bool disable_fullbright = false;
|
||||
bool disable_fullbright_specified = false;
|
||||
bool thiswad = false;
|
||||
bool iwad = false;
|
||||
|
||||
FTexture *textures[6];
|
||||
const char *keywords[7] = { "brightmap", "normal", "specular", "metallic", "roughness", "ao", nullptr };
|
||||
const char *notFound[6] = { "Brightmap", "Normalmap", "Specular texture", "Metallic texture", "Roughness texture", "Ambient occlusion texture" };
|
||||
memset(textures, 0, sizeof(textures));
|
||||
|
||||
sc.MustGetString();
|
||||
if (sc.Compare("texture")) type = FTexture::TEX_Wall;
|
||||
else if (sc.Compare("flat")) type = FTexture::TEX_Flat;
|
||||
else if (sc.Compare("sprite")) type = FTexture::TEX_Sprite;
|
||||
else sc.UnGet();
|
||||
|
||||
sc.MustGetString();
|
||||
FTextureID no = TexMan.CheckForTexture(sc.String, type, FTextureManager::TEXMAN_TryAny | FTextureManager::TEXMAN_Overridable);
|
||||
FTexture *tex = TexMan[no];
|
||||
|
||||
sc.MustGetToken('{');
|
||||
while (!sc.CheckToken('}'))
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (sc.Compare("disablefullbright"))
|
||||
{
|
||||
// This can also be used without a brightness map to disable
|
||||
// fullbright in rotations that only use brightness maps on
|
||||
// other angles.
|
||||
disable_fullbright = true;
|
||||
disable_fullbright_specified = true;
|
||||
}
|
||||
else if (sc.Compare("thiswad"))
|
||||
{
|
||||
// only affects textures defined in the WAD containing the definition file.
|
||||
thiswad = true;
|
||||
}
|
||||
else if (sc.Compare ("iwad"))
|
||||
{
|
||||
// only affects textures defined in the IWAD.
|
||||
iwad = true;
|
||||
}
|
||||
else if (sc.Compare("glossiness"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
if (tex)
|
||||
tex->gl_info.Glossiness = sc.Float;
|
||||
}
|
||||
else if (sc.Compare("specularlevel"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
if (tex)
|
||||
tex->gl_info.SpecularLevel = sc.Float;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; keywords[i] != nullptr; i++)
|
||||
{
|
||||
if (sc.Compare (keywords[i]))
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (textures[i])
|
||||
Printf("Multiple %s definitions in texture %s\n", keywords[i], tex? tex->Name.GetChars() : "(null)");
|
||||
textures[i] = TexMan.FindTexture(sc.String, FTexture::TEX_Any, FTextureManager::TEXMAN_TryAny);
|
||||
if (!textures[i])
|
||||
Printf("%s '%s' not found in texture '%s'\n", notFound[i], sc.String, tex? tex->Name.GetChars() : "(null)");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!tex)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (thiswad || iwad)
|
||||
{
|
||||
bool useme = false;
|
||||
int lumpnum = tex->GetSourceLump();
|
||||
|
||||
if (lumpnum != -1)
|
||||
{
|
||||
if (iwad && Wads.GetLumpFile(lumpnum) <= Wads.GetIwadNum()) useme = true;
|
||||
if (thiswad && Wads.GetLumpFile(lumpnum) == deflump) useme = true;
|
||||
}
|
||||
if (!useme) return;
|
||||
}
|
||||
|
||||
FTexture **bindings[6] =
|
||||
{
|
||||
&tex->gl_info.Brightmap,
|
||||
&tex->gl_info.Normal,
|
||||
&tex->gl_info.Specular,
|
||||
&tex->gl_info.Metallic,
|
||||
&tex->gl_info.Roughness,
|
||||
&tex->gl_info.AmbientOcclusion
|
||||
};
|
||||
for (int i = 0; keywords[i] != nullptr; i++)
|
||||
{
|
||||
if (textures[i])
|
||||
{
|
||||
textures[i]->bMasked = false;
|
||||
*bindings[i] = textures[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (disable_fullbright_specified)
|
||||
tex->gl_info.bDisableFullbright = disable_fullbright;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
22
src/m_swap.h
22
src/m_swap.h
|
@ -91,6 +91,16 @@ inline unsigned short LittleShort (unsigned short x)
|
|||
return (unsigned short)((x>>8) | (x<<8));
|
||||
}
|
||||
|
||||
inline short LittleShort (int x)
|
||||
{
|
||||
return LittleShort((short)x);
|
||||
}
|
||||
|
||||
inline unsigned short LittleShort (unsigned int x)
|
||||
{
|
||||
return LittleShort((unsigned short)x);
|
||||
}
|
||||
|
||||
// Swapping 32bit.
|
||||
inline unsigned int LittleLong (unsigned int x)
|
||||
{
|
||||
|
@ -110,6 +120,16 @@ inline int LittleLong (int x)
|
|||
| (((unsigned int)x)<<24));
|
||||
}
|
||||
|
||||
inline unsigned int LittleLong(unsigned long x)
|
||||
{
|
||||
return LittleLong((unsigned int)x);
|
||||
}
|
||||
|
||||
inline int LittleLong(long x)
|
||||
{
|
||||
return LittleLong((int)x);
|
||||
}
|
||||
|
||||
#define BigShort(x) (x)
|
||||
#define BigLong(x) (x)
|
||||
|
||||
|
@ -177,7 +197,7 @@ inline int BigLong (int x)
|
|||
|
||||
|
||||
// Data accessors, since some data is highly likely to be unaligned.
|
||||
#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__)
|
||||
#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__x86_64__)
|
||||
inline int GetShort(const unsigned char *foo)
|
||||
{
|
||||
return *(const short *)foo;
|
||||
|
|
|
@ -328,6 +328,11 @@ protected:
|
|||
Rotations = other->Rotations;
|
||||
gl_info = other->gl_info;
|
||||
gl_info.Brightmap = NULL;
|
||||
gl_info.Normal = NULL;
|
||||
gl_info.Specular = NULL;
|
||||
gl_info.Metallic = NULL;
|
||||
gl_info.Roughness = NULL;
|
||||
gl_info.AmbientOcclusion = NULL;
|
||||
gl_info.areas = NULL;
|
||||
}
|
||||
|
||||
|
@ -362,6 +367,13 @@ public:
|
|||
FMaterial *Material[2];
|
||||
FGLTexture *SystemTexture[2];
|
||||
FTexture *Brightmap;
|
||||
FTexture *Normal; // Normal map texture
|
||||
FTexture *Specular; // Specular light texture for the diffuse+normal+specular light model
|
||||
FTexture *Metallic; // Metalness texture for the physically based rendering (PBR) light model
|
||||
FTexture *Roughness; // Roughness texture for PBR
|
||||
FTexture *AmbientOcclusion; // Ambient occlusion texture for PBR
|
||||
float Glossiness;
|
||||
float SpecularLevel;
|
||||
PalEntry GlowColor;
|
||||
int GlowHeight;
|
||||
FloatRect *areas;
|
||||
|
|
|
@ -1,4 +1,13 @@
|
|||
#if defined(SPECULAR)
|
||||
uniform sampler2D texture4;
|
||||
#define brighttexture texture4
|
||||
#elif defined(PBR)
|
||||
uniform sampler2D texture6;
|
||||
#define brighttexture texture6
|
||||
#else
|
||||
uniform sampler2D texture2;
|
||||
#define brighttexture texture2
|
||||
#endif
|
||||
|
||||
vec4 ProcessTexel()
|
||||
{
|
||||
|
@ -7,6 +16,6 @@ vec4 ProcessTexel()
|
|||
|
||||
vec4 ProcessLight(vec4 color)
|
||||
{
|
||||
vec4 brightpix = desaturate(texture(texture2, vTexCoord.st));
|
||||
vec4 brightpix = desaturate(texture(brighttexture, vTexCoord.st));
|
||||
return vec4(min (color.rgb + brightpix.rgb, 1.0), color.a);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,22 @@ out vec4 FragNormal;
|
|||
uniform sampler2D tex;
|
||||
uniform sampler2D ShadowMap;
|
||||
|
||||
#if defined(SPECULAR)
|
||||
uniform sampler2D texture2;
|
||||
uniform sampler2D texture3;
|
||||
#define normaltexture texture2
|
||||
#define speculartexture texture3
|
||||
#elif defined(PBR)
|
||||
uniform sampler2D texture2;
|
||||
uniform sampler2D texture3;
|
||||
uniform sampler2D texture4;
|
||||
uniform sampler2D texture5;
|
||||
#define normaltexture texture2
|
||||
#define metallictexture texture3
|
||||
#define roughnesstexture texture4
|
||||
#define aotexture texture5
|
||||
#endif
|
||||
|
||||
vec4 Process(vec4 color);
|
||||
vec4 ProcessTexel();
|
||||
vec4 ProcessLight(vec4 color);
|
||||
|
@ -252,29 +268,112 @@ float diffuseContribution(vec3 lightDirection, vec3 normal)
|
|||
|
||||
//===========================================================================
|
||||
//
|
||||
// Calculates the brightness of a dynamic point light
|
||||
// Todo: Find a better way to define which lighting model to use.
|
||||
// (Specular mode has been removed for now.)
|
||||
// Blinn specular light calculation
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
float pointLightAttenuation(vec4 lightpos, float lightcolorA)
|
||||
float blinnSpecularContribution(float diffuseContribution, vec3 lightDirection, vec3 faceNormal, float glossiness, float specularLevel)
|
||||
{
|
||||
if (diffuseContribution > 0.0f)
|
||||
{
|
||||
vec3 viewDir = normalize(uCameraPos.xyz - pixelpos.xyz);
|
||||
vec3 halfDir = normalize(lightDirection + viewDir);
|
||||
float specAngle = max(dot(halfDir, faceNormal), 0.0f);
|
||||
float phExp = glossiness * 4.0f;
|
||||
return specularLevel * pow(specAngle, phExp);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Adjust normal vector according to the normal map
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
#if defined(SPECULAR) || defined(PBR)
|
||||
mat3 cotangent_frame(vec3 n, vec3 p, vec2 uv)
|
||||
{
|
||||
// get edge vectors of the pixel triangle
|
||||
vec3 dp1 = dFdx(p);
|
||||
vec3 dp2 = dFdy(p);
|
||||
vec2 duv1 = dFdx(uv);
|
||||
vec2 duv2 = dFdy(uv);
|
||||
|
||||
// solve the linear system
|
||||
vec3 dp2perp = cross(n, dp2); // cross(dp2, n);
|
||||
vec3 dp1perp = cross(dp1, n); // cross(n, dp1);
|
||||
vec3 t = dp2perp * duv1.x + dp1perp * duv2.x;
|
||||
vec3 b = dp2perp * duv1.y + dp1perp * duv2.y;
|
||||
|
||||
// construct a scale-invariant frame
|
||||
float invmax = inversesqrt(max(dot(t,t), dot(b,b)));
|
||||
return mat3(t * invmax, b * invmax, n);
|
||||
}
|
||||
|
||||
vec3 ApplyNormalMap()
|
||||
{
|
||||
#define WITH_NORMALMAP_UNSIGNED
|
||||
#define WITH_NORMALMAP_GREEN_UP
|
||||
//#define WITH_NORMALMAP_2CHANNEL
|
||||
|
||||
vec3 interpolatedNormal = normalize(vWorldNormal.xyz);
|
||||
|
||||
vec3 map = texture(normaltexture, vTexCoord.st).xyz;
|
||||
#if defined(WITH_NORMALMAP_UNSIGNED)
|
||||
map = map * 255./127. - 128./127.; // Math so "odd" because 0.5 cannot be precisely described in an unsigned format
|
||||
#endif
|
||||
#if defined(WITH_NORMALMAP_2CHANNEL)
|
||||
map.z = sqrt(1 - dot(map.xy, map.xy));
|
||||
#endif
|
||||
#if defined(WITH_NORMALMAP_GREEN_UP)
|
||||
map.y = -map.y;
|
||||
#endif
|
||||
|
||||
mat3 tbn = cotangent_frame(interpolatedNormal, pixelpos.xyz, vTexCoord.st);
|
||||
vec3 bumpedNormal = normalize(tbn * map);
|
||||
return bumpedNormal;
|
||||
}
|
||||
#else
|
||||
vec3 ApplyNormalMap()
|
||||
{
|
||||
return normalize(vWorldNormal.xyz);
|
||||
}
|
||||
#endif
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Calculates the brightness of a dynamic point light
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
vec2 pointLightAttenuation(vec4 lightpos, float lightcolorA)
|
||||
{
|
||||
float attenuation = max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w;
|
||||
if (attenuation == 0.0) return 0.0;
|
||||
if (attenuation == 0.0) return vec2(0.0);
|
||||
#ifdef SUPPORTS_SHADOWMAPS
|
||||
float shadowIndex = abs(lightcolorA) - 1.0;
|
||||
attenuation *= shadowmapAttenuation(lightpos, shadowIndex);
|
||||
#endif
|
||||
if (lightcolorA >= 0.0) // Sign bit is the attenuated light flag
|
||||
{
|
||||
return attenuation;
|
||||
return vec2(attenuation, 0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
vec3 lightDirection = normalize(lightpos.xyz - pixelpos.xyz);
|
||||
float diffuseAmount = diffuseContribution(lightDirection, normalize(vWorldNormal.xyz));
|
||||
return attenuation * diffuseAmount;
|
||||
vec3 pixelnormal = ApplyNormalMap();
|
||||
float diffuseAmount = diffuseContribution(lightDirection, pixelnormal);
|
||||
|
||||
#if defined(SPECULAR)
|
||||
float specularAmount = blinnSpecularContribution(diffuseAmount, lightDirection, pixelnormal, uSpecularMaterial.x, uSpecularMaterial.y);
|
||||
return vec2(diffuseAmount, specularAmount) * attenuation;
|
||||
#else
|
||||
return vec2(attenuation * diffuseAmount, 0.0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -299,7 +398,7 @@ float spotLightAttenuation(vec4 lightpos, vec3 spotdir, float lightCosInnerAngle
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
vec4 getLightColor(float fogdist, float fogfactor)
|
||||
vec4 getLightColor(vec4 material, vec4 materialSpec, float fogdist, float fogfactor)
|
||||
{
|
||||
vec4 color = vColor;
|
||||
|
||||
|
@ -345,6 +444,7 @@ vec4 getLightColor(float fogdist, float fogfactor)
|
|||
//
|
||||
|
||||
vec4 dynlight = uDynLightColor;
|
||||
vec4 specular = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
#if defined NUM_UBO_LIGHTS || defined SHADER_STORAGE_LIGHTS
|
||||
if (uLightIndex >= 0)
|
||||
|
@ -362,11 +462,11 @@ vec4 getLightColor(float fogdist, float fogfactor)
|
|||
vec4 lightspot1 = lights[i+2];
|
||||
vec4 lightspot2 = lights[i+3];
|
||||
|
||||
float attenuation = pointLightAttenuation(lightpos, lightcolor.a);
|
||||
vec2 attenuation = pointLightAttenuation(lightpos, lightcolor.a);
|
||||
if (lightspot1.w == 1.0)
|
||||
attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
|
||||
lightcolor.rgb *= attenuation;
|
||||
dynlight.rgb += lightcolor.rgb;
|
||||
attenuation.xy *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
|
||||
dynlight.rgb += lightcolor.rgb * attenuation.x;
|
||||
specular.rgb += lightcolor.rgb * attenuation.y;
|
||||
}
|
||||
//
|
||||
// subtractive lights
|
||||
|
@ -378,19 +478,20 @@ vec4 getLightColor(float fogdist, float fogfactor)
|
|||
vec4 lightspot1 = lights[i+2];
|
||||
vec4 lightspot2 = lights[i+3];
|
||||
|
||||
float attenuation = pointLightAttenuation(lightpos, lightcolor.a);
|
||||
vec2 attenuation = pointLightAttenuation(lightpos, lightcolor.a);
|
||||
if (lightspot1.w == 1.0)
|
||||
attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
|
||||
lightcolor.rgb *= attenuation;
|
||||
dynlight.rgb -= lightcolor.rgb;
|
||||
attenuation.xy *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
|
||||
dynlight.rgb -= lightcolor.rgb * attenuation.x;
|
||||
specular.rgb -= lightcolor.rgb * attenuation.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
color.rgb = clamp(color.rgb + desaturate(dynlight).rgb, 0.0, 1.4);
|
||||
|
||||
specular.rgb = clamp(specular.rgb + desaturate(specular).rgb, 0.0, 1.4);
|
||||
|
||||
// prevent any unintentional messing around with the alpha.
|
||||
return vec4(color.rgb, vColor.a);
|
||||
return vec4(material.rgb * color.rgb + materialSpec.rgb * specular.rgb, material.a * vColor.a);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -470,8 +571,13 @@ void main()
|
|||
fogfactor = exp2 (uFogDensity * fogdist);
|
||||
}
|
||||
|
||||
|
||||
frag *= getLightColor(fogdist, fogfactor);
|
||||
#if defined(SPECULAR)
|
||||
vec4 materialSpec = texture(speculartexture, vTexCoord.st);
|
||||
#else
|
||||
vec4 materialSpec = vec4(0.0);
|
||||
#endif
|
||||
|
||||
frag = getLightColor(frag, materialSpec, fogdist, fogfactor);
|
||||
|
||||
#if defined NUM_UBO_LIGHTS || defined SHADER_STORAGE_LIGHTS
|
||||
if (uLightIndex >= 0)
|
||||
|
@ -491,7 +597,7 @@ void main()
|
|||
vec4 lightspot1 = lights[i+2];
|
||||
vec4 lightspot2 = lights[i+3];
|
||||
|
||||
float attenuation = pointLightAttenuation(lightpos, lightcolor.a);
|
||||
float attenuation = pointLightAttenuation(lightpos, lightcolor.a).x;
|
||||
if (lightspot1.w == 1.0)
|
||||
attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
|
||||
lightcolor.rgb *= attenuation;
|
||||
|
|
|
@ -51,6 +51,9 @@ uniform int uLightIndex;
|
|||
// Software fuzz scaling
|
||||
uniform int uViewHeight;
|
||||
|
||||
// Blinn glossiness and specular level
|
||||
uniform vec2 uSpecularMaterial;
|
||||
|
||||
// quad drawer stuff
|
||||
#ifdef USE_QUAD_DRAWER
|
||||
uniform mat4 uQuadVertices;
|
||||
|
|
Loading…
Reference in a new issue