From 24f748da03dad1c43c2c8a779546da7bf97d3176 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Tue, 20 Sep 2016 02:57:57 +0200 Subject: [PATCH] Add gbuffer pass support to FShaderManager and FRenderState --- src/gl/renderer/gl_renderstate.cpp | 7 +- src/gl/renderer/gl_renderstate.h | 19 +++ src/gl/shaders/gl_shader.cpp | 179 ++++++++++++++++++----------- src/gl/shaders/gl_shader.h | 46 +++++--- wadsrc/static/shaders/glsl/main.fp | 6 + 5 files changed, 170 insertions(+), 87 deletions(-) diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index cd51e540a..2cfd739e9 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -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(); } @@ -343,7 +344,7 @@ void FRenderState::ApplyMatrices() { if (GLRenderer->mShaderManager != NULL) { - GLRenderer->mShaderManager->ApplyMatrices(&mProjectionMatrix, &mViewMatrix); + GLRenderer->mShaderManager->ApplyMatrices(&mProjectionMatrix, &mViewMatrix, mPassType); } } diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 1c0a20348..7bec51be0 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -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(); diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 158163a48..26a449bf2 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -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); @@ -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; // 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 @@ -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" }, }; - -//========================================================================== -// -// -// -//========================================================================== - 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(); } //========================================================================== @@ -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(); mTextureEffectsNAT.Clear(); for (int i = 0; i < MAX_EFFECTS; i++) @@ -428,11 +500,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); } } @@ -442,7 +514,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); } @@ -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++) { 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; @@ -506,21 +575,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; - } -} - //========================================================================== // @@ -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) { @@ -546,36 +600,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); } } diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index 5af927e6d..793fa63dd 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -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; @@ -323,7 +324,6 @@ public: }; - //========================================================================== // // The global shader manager @@ -331,26 +331,40 @@ public: //========================================================================== class FShaderManager { - TArray mTextureEffects; - TArray 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 mPassShaders; +}; + +class FShaderCollection +{ + TArray mTextureEffects; + TArray 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() { diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 84b7f5742..0b66f0569 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -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 @@ -433,5 +436,8 @@ void main() } } FragColor = frag; +#ifdef GBUFFER_PASS + FragData = vec4(uFogColor.rgb, 1.0); +#endif }