mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 06:53:58 +00:00
Add gbuffer pass support to FShaderManager and FRenderState
This commit is contained in:
parent
37e3172c94
commit
9af34bac69
5 changed files with 170 additions and 87 deletions
|
@ -105,6 +105,7 @@ void FRenderState::Reset()
|
|||
mViewMatrix.loadIdentity();
|
||||
mModelMatrix.loadIdentity();
|
||||
mTextureMatrix.loadIdentity();
|
||||
mPassType = NORMAL_PASS;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -118,11 +119,11 @@ bool FRenderState::ApplyShader()
|
|||
static const float nulvec[] = { 0.f, 0.f, 0.f, 0.f };
|
||||
if (mSpecialEffect > EFF_NONE)
|
||||
{
|
||||
activeShader = GLRenderer->mShaderManager->BindEffect(mSpecialEffect);
|
||||
activeShader = GLRenderer->mShaderManager->BindEffect(mSpecialEffect, mPassType);
|
||||
}
|
||||
else
|
||||
{
|
||||
activeShader = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : 4, mAlphaThreshold >= 0.f);
|
||||
activeShader = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : 4, mAlphaThreshold >= 0.f, mPassType);
|
||||
activeShader->Bind();
|
||||
}
|
||||
|
||||
|
@ -342,7 +343,7 @@ void FRenderState::ApplyMatrices()
|
|||
{
|
||||
if (GLRenderer->mShaderManager != NULL)
|
||||
{
|
||||
GLRenderer->mShaderManager->ApplyMatrices(&mProjectionMatrix, &mViewMatrix);
|
||||
GLRenderer->mShaderManager->ApplyMatrices(&mProjectionMatrix, &mViewMatrix, mPassType);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,13 @@ enum EEffect
|
|||
MAX_EFFECTS
|
||||
};
|
||||
|
||||
enum EPassType
|
||||
{
|
||||
NORMAL_PASS,
|
||||
GBUFFER_PASS,
|
||||
MAX_PASS_TYPES
|
||||
};
|
||||
|
||||
class FRenderState
|
||||
{
|
||||
bool mTextureEnabled;
|
||||
|
@ -111,6 +118,8 @@ class FRenderState
|
|||
|
||||
FShader *activeShader;
|
||||
|
||||
EPassType mPassType = NORMAL_PASS;
|
||||
|
||||
bool ApplyShader();
|
||||
|
||||
public:
|
||||
|
@ -459,6 +468,16 @@ public:
|
|||
return mInterpolationFactor;
|
||||
}
|
||||
|
||||
void SetPassType(EPassType passType)
|
||||
{
|
||||
mPassType = passType;
|
||||
}
|
||||
|
||||
EPassType GetPassType()
|
||||
{
|
||||
return mPassType;
|
||||
}
|
||||
|
||||
// Backwards compatibility crap follows
|
||||
void ApplyFixedFunction();
|
||||
void DrawColormapOverlay();
|
||||
|
|
|
@ -180,6 +180,9 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
|||
glBindAttribLocation(hShader, VATTR_COLOR, "aColor");
|
||||
glBindAttribLocation(hShader, VATTR_VERTEX2, "aVertex2");
|
||||
|
||||
glBindFragDataLocation(hShader, 0, "FragColor");
|
||||
glBindFragDataLocation(hShader, 1, "FragData");
|
||||
|
||||
glLinkProgram(hShader);
|
||||
|
||||
glGetShaderInfoLog(hVertProg, 10000, NULL, buffer);
|
||||
|
@ -297,12 +300,13 @@ bool FShader::Bind()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FShader *FShaderManager::Compile (const char *ShaderName, const char *ShaderPath, bool usediscard)
|
||||
FShader *FShaderCollection::Compile (const char *ShaderName, const char *ShaderPath, bool usediscard, EPassType passType)
|
||||
{
|
||||
FString defines;
|
||||
// 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";
|
||||
if (passType == GBUFFER_PASS) defines += "#define GBUFFER_PASS\n";
|
||||
|
||||
FShader *shader = NULL;
|
||||
try
|
||||
|
@ -385,27 +389,75 @@ static const FEffectShader effectshaders[]=
|
|||
{ "stencil", "shaders/glsl/main.vp", "shaders/glsl/stencil.fp", NULL, "#define SIMPLE\n#define NO_ALPHATEST\n" },
|
||||
};
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FShaderManager::FShaderManager()
|
||||
{
|
||||
if (!gl.legacyMode) CompileShaders();
|
||||
if (!gl.legacyMode)
|
||||
{
|
||||
for (int passType = 0; passType < MAX_PASS_TYPES; passType++)
|
||||
mPassShaders.Push(new FShaderCollection((EPassType)passType));
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FShaderManager::~FShaderManager()
|
||||
{
|
||||
if (!gl.legacyMode) Clean();
|
||||
if (!gl.legacyMode)
|
||||
{
|
||||
glUseProgram(0);
|
||||
mActiveShader = NULL;
|
||||
|
||||
for (auto collection : mPassShaders)
|
||||
delete collection;
|
||||
}
|
||||
}
|
||||
|
||||
void FShaderManager::SetActiveShader(FShader *sh)
|
||||
{
|
||||
if (mActiveShader != sh)
|
||||
{
|
||||
glUseProgram(sh!= NULL? sh->GetHandle() : 0);
|
||||
mActiveShader = sh;
|
||||
}
|
||||
}
|
||||
|
||||
FShader *FShaderManager::BindEffect(int effect, EPassType passType)
|
||||
{
|
||||
if (passType < mPassShaders.Size())
|
||||
return mPassShaders[passType]->BindEffect(effect);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FShader *FShaderManager::Get(unsigned int eff, bool alphateston, EPassType passType)
|
||||
{
|
||||
if (passType < mPassShaders.Size())
|
||||
return mPassShaders[passType]->Get(eff, alphateston);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void FShaderManager::ApplyMatrices(VSMatrix *proj, VSMatrix *view, EPassType passType)
|
||||
{
|
||||
if (gl.legacyMode)
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(proj->get());
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadMatrixf(view->get());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (passType < mPassShaders.Size())
|
||||
mPassShaders[passType]->ApplyMatrices(proj, view);
|
||||
|
||||
if (mActiveShader)
|
||||
mActiveShader->Bind();
|
||||
}
|
||||
}
|
||||
|
||||
void FShaderManager::ResetFixedColormap()
|
||||
{
|
||||
for (auto &collection : mPassShaders)
|
||||
collection->ResetFixedColormap();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -414,10 +466,30 @@ FShaderManager::~FShaderManager()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FShaderManager::CompileShaders()
|
||||
FShaderCollection::FShaderCollection(EPassType passType)
|
||||
{
|
||||
mActiveShader = NULL;
|
||||
CompileShaders(passType);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FShaderCollection::~FShaderCollection()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FShaderCollection::CompileShaders(EPassType passType)
|
||||
{
|
||||
mTextureEffects.Clear();
|
||||
mTextureEffectsNAT.Clear();
|
||||
for (int i = 0; i < MAX_EFFECTS; i++)
|
||||
|
@ -427,11 +499,11 @@ void FShaderManager::CompileShaders()
|
|||
|
||||
for(int i=0;defaultshaders[i].ShaderName != NULL;i++)
|
||||
{
|
||||
FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, true);
|
||||
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, false);
|
||||
FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, false, passType);
|
||||
mTextureEffectsNAT.Push(shc);
|
||||
}
|
||||
}
|
||||
|
@ -441,7 +513,7 @@ void FShaderManager::CompileShaders()
|
|||
FString name = ExtractFileBase(usershaders[i]);
|
||||
FName sfn = name;
|
||||
|
||||
FShader *shc = Compile(sfn, usershaders[i], true);
|
||||
FShader *shc = Compile(sfn, usershaders[i], true, passType);
|
||||
mTextureEffects.Push(shc);
|
||||
}
|
||||
|
||||
|
@ -463,11 +535,8 @@ void FShaderManager::CompileShaders()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FShaderManager::Clean()
|
||||
void FShaderCollection::Clean()
|
||||
{
|
||||
glUseProgram(0);
|
||||
mActiveShader = NULL;
|
||||
|
||||
for (unsigned int i = 0; i < mTextureEffectsNAT.Size(); i++)
|
||||
{
|
||||
if (mTextureEffectsNAT[i] != NULL) delete mTextureEffectsNAT[i];
|
||||
|
@ -491,7 +560,7 @@ void FShaderManager::Clean()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
int FShaderManager::Find(const char * shn)
|
||||
int FShaderCollection::Find(const char * shn)
|
||||
{
|
||||
FName sfn = shn;
|
||||
|
||||
|
@ -505,21 +574,6 @@ int FShaderManager::Find(const char * shn)
|
|||
return -1;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FShaderManager::SetActiveShader(FShader *sh)
|
||||
{
|
||||
if (mActiveShader != sh)
|
||||
{
|
||||
glUseProgram(sh!= NULL? sh->GetHandle() : 0);
|
||||
mActiveShader = sh;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -527,7 +581,7 @@ void FShaderManager::SetActiveShader(FShader *sh)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FShader *FShaderManager::BindEffect(int effect)
|
||||
FShader *FShaderCollection::BindEffect(int effect)
|
||||
{
|
||||
if (effect >= 0 && effect < MAX_EFFECTS && mEffectShaders[effect] != NULL)
|
||||
{
|
||||
|
@ -545,17 +599,8 @@ FShader *FShaderManager::BindEffect(int effect)
|
|||
//==========================================================================
|
||||
EXTERN_CVAR(Int, gl_fuzztype)
|
||||
|
||||
void FShaderManager::ApplyMatrices(VSMatrix *proj, VSMatrix *view)
|
||||
void FShaderCollection::ApplyMatrices(VSMatrix *proj, VSMatrix *view)
|
||||
{
|
||||
if (gl.legacyMode)
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(proj->get());
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadMatrixf(view->get());
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
mTextureEffects[i]->ApplyMatrices(proj, view);
|
||||
|
@ -574,8 +619,6 @@ void FShaderManager::ApplyMatrices(VSMatrix *proj, VSMatrix *view)
|
|||
{
|
||||
mEffectShaders[i]->ApplyMatrices(proj, view);
|
||||
}
|
||||
if (mActiveShader != NULL) mActiveShader->Bind();
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -37,6 +37,7 @@ enum
|
|||
VATTR_NORMAL = 4
|
||||
};
|
||||
|
||||
class FShaderCollection;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -248,7 +249,7 @@ public:
|
|||
|
||||
class FShader
|
||||
{
|
||||
friend class FShaderManager;
|
||||
friend class FShaderCollection;
|
||||
friend class FRenderState;
|
||||
|
||||
unsigned int hShader;
|
||||
|
@ -322,7 +323,6 @@ public:
|
|||
|
||||
};
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// The global shader manager
|
||||
|
@ -330,26 +330,40 @@ public:
|
|||
//==========================================================================
|
||||
class FShaderManager
|
||||
{
|
||||
TArray<FShader*> mTextureEffects;
|
||||
TArray<FShader*> mTextureEffectsNAT;
|
||||
FShader *mActiveShader;
|
||||
FShader *mEffectShaders[MAX_EFFECTS];
|
||||
|
||||
void Clean();
|
||||
void CompileShaders();
|
||||
|
||||
public:
|
||||
FShaderManager();
|
||||
~FShaderManager();
|
||||
FShader *Compile(const char *ShaderName, const char *ShaderPath, bool usediscard);
|
||||
|
||||
void SetActiveShader(FShader *sh);
|
||||
FShader *GetActiveShader() const { return mActiveShader; }
|
||||
|
||||
FShader *BindEffect(int effect, EPassType passType);
|
||||
FShader *Get(unsigned int eff, bool alphateston, EPassType passType);
|
||||
void ApplyMatrices(VSMatrix *proj, VSMatrix *view, EPassType passType);
|
||||
|
||||
void ResetFixedColormap();
|
||||
|
||||
private:
|
||||
FShader *mActiveShader = nullptr;
|
||||
TArray<FShaderCollection*> mPassShaders;
|
||||
};
|
||||
|
||||
class FShaderCollection
|
||||
{
|
||||
TArray<FShader*> mTextureEffects;
|
||||
TArray<FShader*> mTextureEffectsNAT;
|
||||
FShader *mEffectShaders[MAX_EFFECTS];
|
||||
|
||||
void Clean();
|
||||
void CompileShaders(EPassType passType);
|
||||
|
||||
public:
|
||||
FShaderCollection(EPassType passType);
|
||||
~FShaderCollection();
|
||||
FShader *Compile(const char *ShaderName, const char *ShaderPath, bool usediscard, EPassType passType);
|
||||
int Find(const char *mame);
|
||||
FShader *BindEffect(int effect);
|
||||
void SetActiveShader(FShader *sh);
|
||||
void ApplyMatrices(VSMatrix *proj, VSMatrix *view);
|
||||
FShader *GetActiveShader() const
|
||||
{
|
||||
return mActiveShader;
|
||||
}
|
||||
|
||||
void ResetFixedColormap()
|
||||
{
|
||||
|
|
|
@ -5,6 +5,9 @@ in vec4 vTexCoord;
|
|||
in vec4 vColor;
|
||||
|
||||
out vec4 FragColor;
|
||||
#ifdef GBUFFER_PASS
|
||||
out vec4 FragData;
|
||||
#endif
|
||||
|
||||
#ifdef SHADER_STORAGE_LIGHTS
|
||||
layout(std430, binding = 1) buffer LightBufferSSO
|
||||
|
@ -345,5 +348,8 @@ void main()
|
|||
}
|
||||
}
|
||||
FragColor = frag;
|
||||
#ifdef GBUFFER_PASS
|
||||
FragData = vec4(uFogColor.rgb, 1.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue