Add gbuffer pass support to FShaderManager and FRenderState

This commit is contained in:
Magnus Norddahl 2016-09-20 02:57:57 +02:00
parent b1871b272b
commit 24f748da03
5 changed files with 170 additions and 87 deletions

View file

@ -105,6 +105,7 @@ void FRenderState::Reset()
mViewMatrix.loadIdentity(); mViewMatrix.loadIdentity();
mModelMatrix.loadIdentity(); mModelMatrix.loadIdentity();
mTextureMatrix.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 }; static const float nulvec[] = { 0.f, 0.f, 0.f, 0.f };
if (mSpecialEffect > EFF_NONE) if (mSpecialEffect > EFF_NONE)
{ {
activeShader = GLRenderer->mShaderManager->BindEffect(mSpecialEffect); activeShader = GLRenderer->mShaderManager->BindEffect(mSpecialEffect, mPassType);
} }
else else
{ {
activeShader = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : 4, mAlphaThreshold >= 0.f); activeShader = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : 4, mAlphaThreshold >= 0.f, mPassType);
activeShader->Bind(); activeShader->Bind();
} }
@ -343,7 +344,7 @@ void FRenderState::ApplyMatrices()
{ {
if (GLRenderer->mShaderManager != NULL) 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 MAX_EFFECTS
}; };
enum EPassType
{
NORMAL_PASS,
GBUFFER_PASS,
MAX_PASS_TYPES
};
class FRenderState class FRenderState
{ {
bool mTextureEnabled; bool mTextureEnabled;
@ -111,6 +118,8 @@ class FRenderState
FShader *activeShader; FShader *activeShader;
EPassType mPassType = NORMAL_PASS;
bool ApplyShader(); bool ApplyShader();
public: public:
@ -459,6 +468,16 @@ public:
return mInterpolationFactor; return mInterpolationFactor;
} }
void SetPassType(EPassType passType)
{
mPassType = passType;
}
EPassType GetPassType()
{
return mPassType;
}
// Backwards compatibility crap follows // Backwards compatibility crap follows
void ApplyFixedFunction(); void ApplyFixedFunction();
void DrawColormapOverlay(); 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_COLOR, "aColor");
glBindAttribLocation(hShader, VATTR_VERTEX2, "aVertex2"); glBindAttribLocation(hShader, VATTR_VERTEX2, "aVertex2");
glBindFragDataLocation(hShader, 0, "FragColor");
glBindFragDataLocation(hShader, 1, "FragData");
glLinkProgram(hShader); glLinkProgram(hShader);
glGetShaderInfoLog(hVertProg, 10000, NULL, buffer); glGetShaderInfoLog(hVertProg, 10000, NULL, buffer);
@ -298,12 +301,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; FString defines;
// this can't be in the shader code due to ATI strangeness. // this can't be in the shader code due to ATI strangeness.
if (gl.MaxLights() == 128) defines += "#define MAXLIGHTS128\n"; if (gl.MaxLights() == 128) defines += "#define MAXLIGHTS128\n";
if (!usediscard) defines += "#define NO_ALPHATEST\n"; if (!usediscard) defines += "#define NO_ALPHATEST\n";
if (passType == GBUFFER_PASS) defines += "#define GBUFFER_PASS\n";
FShader *shader = NULL; FShader *shader = NULL;
try try
@ -386,27 +390,75 @@ static const FEffectShader effectshaders[]=
{ "stencil", "shaders/glsl/main.vp", "shaders/glsl/stencil.fp", NULL, "#define SIMPLE\n#define NO_ALPHATEST\n" }, { "stencil", "shaders/glsl/main.vp", "shaders/glsl/stencil.fp", NULL, "#define SIMPLE\n#define NO_ALPHATEST\n" },
}; };
//==========================================================================
//
//
//
//==========================================================================
FShaderManager::FShaderManager() 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() 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();
} }
//========================================================================== //==========================================================================
@ -415,10 +467,30 @@ FShaderManager::~FShaderManager()
// //
//========================================================================== //==========================================================================
void FShaderManager::CompileShaders() FShaderCollection::FShaderCollection(EPassType passType)
{ {
mActiveShader = NULL; CompileShaders(passType);
}
//==========================================================================
//
//
//
//==========================================================================
FShaderCollection::~FShaderCollection()
{
Clean();
}
//==========================================================================
//
//
//
//==========================================================================
void FShaderCollection::CompileShaders(EPassType passType)
{
mTextureEffects.Clear(); mTextureEffects.Clear();
mTextureEffectsNAT.Clear(); mTextureEffectsNAT.Clear();
for (int i = 0; i < MAX_EFFECTS; i++) for (int i = 0; i < MAX_EFFECTS; i++)
@ -428,11 +500,11 @@ void FShaderManager::CompileShaders()
for(int i=0;defaultshaders[i].ShaderName != NULL;i++) 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); mTextureEffects.Push(shc);
if (i <= 3) 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); mTextureEffectsNAT.Push(shc);
} }
} }
@ -442,7 +514,7 @@ void FShaderManager::CompileShaders()
FString name = ExtractFileBase(usershaders[i]); FString name = ExtractFileBase(usershaders[i]);
FName sfn = name; FName sfn = name;
FShader *shc = Compile(sfn, usershaders[i], true); FShader *shc = Compile(sfn, usershaders[i], true, passType);
mTextureEffects.Push(shc); mTextureEffects.Push(shc);
} }
@ -464,11 +536,8 @@ void FShaderManager::CompileShaders()
// //
//========================================================================== //==========================================================================
void FShaderManager::Clean() void FShaderCollection::Clean()
{ {
glUseProgram(0);
mActiveShader = NULL;
for (unsigned int i = 0; i < mTextureEffectsNAT.Size(); i++) for (unsigned int i = 0; i < mTextureEffectsNAT.Size(); i++)
{ {
if (mTextureEffectsNAT[i] != NULL) delete mTextureEffectsNAT[i]; if (mTextureEffectsNAT[i] != NULL) delete mTextureEffectsNAT[i];
@ -492,7 +561,7 @@ void FShaderManager::Clean()
// //
//========================================================================== //==========================================================================
int FShaderManager::Find(const char * shn) int FShaderCollection::Find(const char * shn)
{ {
FName sfn = shn; FName sfn = shn;
@ -506,21 +575,6 @@ int FShaderManager::Find(const char * shn)
return -1; return -1;
} }
//==========================================================================
//
//
//
//==========================================================================
void FShaderManager::SetActiveShader(FShader *sh)
{
if (mActiveShader != sh)
{
glUseProgram(sh!= NULL? sh->GetHandle() : 0);
mActiveShader = sh;
}
}
//========================================================================== //==========================================================================
// //
@ -528,7 +582,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) if (effect >= 0 && effect < MAX_EFFECTS && mEffectShaders[effect] != NULL)
{ {
@ -546,36 +600,25 @@ FShader *FShaderManager::BindEffect(int effect)
//========================================================================== //==========================================================================
EXTERN_CVAR(Int, gl_fuzztype) 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); mTextureEffects[i]->ApplyMatrices(proj, view);
glLoadMatrixf(proj->get()); mTextureEffectsNAT[i]->ApplyMatrices(proj, view);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(view->get());
} }
else mTextureEffects[4]->ApplyMatrices(proj, view);
if (gl_fuzztype != 0)
{ {
for (int i = 0; i < 4; i++) mTextureEffects[4 + gl_fuzztype]->ApplyMatrices(proj, view);
{ }
mTextureEffects[i]->ApplyMatrices(proj, view); for (unsigned i = 12; i < mTextureEffects.Size(); i++)
mTextureEffectsNAT[i]->ApplyMatrices(proj, view); {
} mTextureEffects[i]->ApplyMatrices(proj, view);
mTextureEffects[4]->ApplyMatrices(proj, view); }
if (gl_fuzztype != 0) for (int i = 0; i < MAX_EFFECTS; i++)
{ {
mTextureEffects[4 + gl_fuzztype]->ApplyMatrices(proj, view); mEffectShaders[i]->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();
} }
} }

View file

@ -37,6 +37,7 @@ enum
VATTR_NORMAL = 4 VATTR_NORMAL = 4
}; };
class FShaderCollection;
//========================================================================== //==========================================================================
// //
@ -248,7 +249,7 @@ public:
class FShader class FShader
{ {
friend class FShaderManager; friend class FShaderCollection;
friend class FRenderState; friend class FRenderState;
unsigned int hShader; unsigned int hShader;
@ -323,7 +324,6 @@ public:
}; };
//========================================================================== //==========================================================================
// //
// The global shader manager // The global shader manager
@ -331,26 +331,40 @@ public:
//========================================================================== //==========================================================================
class FShaderManager class FShaderManager
{ {
TArray<FShader*> mTextureEffects;
TArray<FShader*> mTextureEffectsNAT;
FShader *mActiveShader;
FShader *mEffectShaders[MAX_EFFECTS];
void Clean();
void CompileShaders();
public: public:
FShaderManager(); FShaderManager();
~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); int Find(const char *mame);
FShader *BindEffect(int effect); FShader *BindEffect(int effect);
void SetActiveShader(FShader *sh);
void ApplyMatrices(VSMatrix *proj, VSMatrix *view); void ApplyMatrices(VSMatrix *proj, VSMatrix *view);
FShader *GetActiveShader() const
{
return mActiveShader;
}
void ResetFixedColormap() void ResetFixedColormap()
{ {

View file

@ -5,6 +5,9 @@ in vec4 vTexCoord;
in vec4 vColor; in vec4 vColor;
out vec4 FragColor; out vec4 FragColor;
#ifdef GBUFFER_PASS
out vec4 FragData;
#endif
#ifdef SHADER_STORAGE_LIGHTS #ifdef SHADER_STORAGE_LIGHTS
layout(std430, binding = 1) buffer LightBufferSSO layout(std430, binding = 1) buffer LightBufferSSO
@ -433,5 +436,8 @@ void main()
} }
} }
FragColor = frag; FragColor = frag;
#ifdef GBUFFER_PASS
FragData = vec4(uFogColor.rgb, 1.0);
#endif
} }