Add gbuffer pass support to FShaderManager and FRenderState

This commit is contained in:
Magnus Norddahl 2016-09-20 02:57:57 +02:00
parent 37e3172c94
commit 9af34bac69
5 changed files with 170 additions and 87 deletions

View file

@ -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);
}
}

View file

@ -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();

View file

@ -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,36 +599,25 @@ 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)
for (int i = 0; i < 4; i++)
{
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(proj->get());
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(view->get());
mTextureEffects[i]->ApplyMatrices(proj, view);
mTextureEffectsNAT[i]->ApplyMatrices(proj, view);
}
else
mTextureEffects[4]->ApplyMatrices(proj, view);
if (gl_fuzztype != 0)
{
for (int i = 0; i < 4; i++)
{
mTextureEffects[i]->ApplyMatrices(proj, view);
mTextureEffectsNAT[i]->ApplyMatrices(proj, view);
}
mTextureEffects[4]->ApplyMatrices(proj, view);
if (gl_fuzztype != 0)
{
mTextureEffects[4 + gl_fuzztype]->ApplyMatrices(proj, view);
}
for (unsigned i = 12; i < mTextureEffects.Size(); i++)
{
mTextureEffects[i]->ApplyMatrices(proj, view);
}
for (int i = 0; i < MAX_EFFECTS; i++)
{
mEffectShaders[i]->ApplyMatrices(proj, view);
}
if (mActiveShader != NULL) mActiveShader->Bind();
mTextureEffects[4 + gl_fuzztype]->ApplyMatrices(proj, view);
}
for (unsigned i = 12; i < mTextureEffects.Size(); i++)
{
mTextureEffects[i]->ApplyMatrices(proj, view);
}
for (int i = 0; i < MAX_EFFECTS; i++)
{
mEffectShaders[i]->ApplyMatrices(proj, view);
}
}

View file

@ -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()
{

View file

@ -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
}