diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index e9fb0fcaa1..80ced088b2 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -75,7 +75,7 @@ CVAR(Bool, gl_billboard_particles, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Int, gl_enhanced_nv_stealth, 3, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CUSTOM_CVAR(Int, gl_fuzztype, 0, CVAR_ARCHIVE) { - if (self < 0 || self > 7) self = 0; + if (self < 0 || self >= 7) self = 0; } extern bool r_showviewer; diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index b1ab7cda52..f00fc886a8 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -334,15 +334,16 @@ struct FEffectShader const char *vp; const char *fp1; const char *fp2; + const char *fp3; const char *defines; }; static const FEffectShader effectshaders[]= { - { "fogboundary", "shaders/glsl/main.vp", "shaders/glsl/fogboundary.fp", NULL, "#define NO_ALPHATEST\n" }, - { "spheremap", "shaders/glsl/main.vp", "shaders/glsl/main.fp", "shaders/glsl/func_normal.fp", "#define SPHEREMAP\n#define NO_ALPHATEST\n" }, - { "burn", "shaders/glsl/main.vp", "shaders/glsl/burn.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" }, + { "fogboundary", "shaders/glsl/main.vp", "shaders/glsl/fogboundary.fp", NULL, NULL, "#define NO_ALPHATEST\n" }, + { "spheremap", "shaders/glsl/main.vp", "shaders/glsl/main.fp", "shaders/glsl/func_normal.fp", "shaders/glsl/func_defaultlight.fp", "#define SPHEREMAP\n#define NO_ALPHATEST\n" }, + { "burn", "shaders/glsl/main.vp", "shaders/glsl/burn.fp", NULL, NULL, "#define SIMPLE\n#define NO_ALPHATEST\n" }, + { "stencil", "shaders/glsl/main.vp", "shaders/glsl/stencil.fp", NULL, NULL, "#define SIMPLE\n#define NO_ALPHATEST\n" }, }; @@ -368,25 +369,6 @@ FShaderManager::~FShaderManager() Clean(); } -//========================================================================== -// -// Initializes the shaders that are being used by the current texture set -// -//========================================================================== - -void FShaderManager::FindAllUsedShaders() -{ - for (int i = 0; i < TexMan.NumTextures(); i++) - { - FTexture *tex = TexMan.ByIndex(i); - - if (tex->bWarped == 1) tex->gl_info.texelShader = "Warp 1"; - else if (tex->bWarped == 2) tex->gl_info.texelShader = "Warp 2"; - - GLRenderer->mShaderManager->GetShaderIndex(tex->gl_info.texelShader, tex->gl_info.lightShader); - } -} - //========================================================================== // // @@ -395,7 +377,44 @@ void FShaderManager::FindAllUsedShaders() unsigned int FShaderManager::GetShaderIndex(FName tex, FName lite) { - return 0; + for (unsigned int i = 0; i < mShaders.Size(); i++) + { + if (mShaders[i].mTexelName == tex && mShaders[i].mLightName == lite) + { + return i; + } + } + for (unsigned int i = 0; i < TexelShaders.Size(); i++) + { + if (TexelShaders[i]->mName == tex) + { + unsigned int j; + for (j = 0; j < LightShaders.Size(); j++) + { + if (LightShaders[j]->mName == lite) break; + } + if (j == LightShaders.Size()) j = 0; // 0 is the default + + FString shname; + unsigned int ndx = mShaders.Reserve(1); + FShaderContainer *cont = &mShaders[ndx]; + + shname << TexelShaders[i]->mName << "::" << LightShaders[j]->mName; + DPrintf("Compiling shader %s\n", shname); + + cont->mTexelName = tex; + cont->mLightName = lite; + cont->mShader = Compile(shname, TexelShaders[i]->mSourceFile, LightShaders[j]->mSourceFile, true); + + if (!TexelShaders[i]->bRequireAlphaTest) + { + cont->mShaderNAT = Compile(shname, TexelShaders[i]->mSourceFile, LightShaders[j]->mSourceFile, false); + } + return ndx; + } + } + // A shader with the requires settings cannot be created so fall back to the default shader. + return SHADER_DEFAULT; } //========================================================================== @@ -423,37 +442,33 @@ void FShaderManager::CompileShaders() { mActiveShader = NULL; - mTextureEffects.Clear(); - mTextureEffectsNAT.Clear(); + mShaders.Clear(); for (int i = 0; i < MAX_EFFECTS; i++) { mEffectShaders[i] = NULL; } - /* - for(int i=0;defaultshaders[i].ShaderName != NULL;i++) - { - FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, true); - mTextureEffects.Push(shc); - if (i <= 3) - { - FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, false); - mTextureEffectsNAT.Push(shc); - } - } - */ - // load the ones the engine accesses directly in order first. The rest gets set up on a need to use basis. for (int i = 0; defShaderNames[i]; i++) { GetShaderIndex(defShaderNames[i], NAME_None); } + for (int i = 0; i < TexMan.NumTextures(); i++) + { + FTexture *tex = TexMan.ByIndex(i); + + if (tex->bWarped == 1) tex->gl_info.texelShader = "Warp 1"; + else if (tex->bWarped == 2) tex->gl_info.texelShader = "Warp 2"; + + GetShaderIndex(tex->gl_info.texelShader, tex->gl_info.lightShader); + } + for(int i=0;iLoad(effectshaders[i].ShaderName, effectshaders[i].vp, effectshaders[i].fp1, - effectshaders[i].fp2, NULL, effectshaders[i].defines)) + effectshaders[i].fp2, effectshaders[i].fp3, effectshaders[i].defines)) { delete eff; } @@ -472,21 +487,17 @@ void FShaderManager::Clean() glUseProgram(0); mActiveShader = NULL; - for (unsigned int i = 0; i < mTextureEffectsNAT.Size(); i++) + for (unsigned int i = 0; i < mShaders.Size(); i++) { - if (mTextureEffectsNAT[i] != NULL) delete mTextureEffectsNAT[i]; - } - for (unsigned int i = 0; i < mTextureEffects.Size(); i++) - { - if (mTextureEffects[i] != NULL) delete mTextureEffects[i]; + if (mShaders[i].mShader != NULL) delete mShaders[i].mShader; + if (mShaders[i].mShaderNAT != NULL) delete mShaders[i].mShaderNAT; } for (int i = 0; i < MAX_EFFECTS; i++) { if (mEffectShaders[i] != NULL) delete mEffectShaders[i]; mEffectShaders[i] = NULL; } - mTextureEffects.Clear(); - mTextureEffectsNAT.Clear(); + mShaders.Clear(); } //========================================================================== @@ -495,28 +506,6 @@ void FShaderManager::Clean() // //========================================================================== -/* -int FShaderManager::Find(const char * shn) -{ - FName sfn = shn; - - for(unsigned int i=0;imName == sfn) - { - return i; - } - } - return -1; -} -*/ - -//========================================================================== -// -// -// -//========================================================================== - void FShaderManager::SetActiveShader(FShader *sh) { if (mActiveShader != sh) @@ -549,23 +538,13 @@ FShader *FShaderManager::BindEffect(int effect) // // //========================================================================== -EXTERN_CVAR(Int, gl_fuzztype) void FShaderManager::ApplyMatrices(VSMatrix *proj, VSMatrix *view) { - for (int i = 0; i < 4; i++) + for (unsigned int i = 0; i < mShaders.Size(); 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); + if (mShaders[i].mShader != NULL) mShaders[i].mShader->ApplyMatrices(proj, view); + if (mShaders[i].mShaderNAT != NULL) mShaders[i].mShaderNAT->ApplyMatrices(proj, view); } for (int i = 0; i < MAX_EFFECTS; i++) { @@ -574,17 +553,6 @@ void FShaderManager::ApplyMatrices(VSMatrix *proj, VSMatrix *view) if (mActiveShader != NULL) mActiveShader->Bind(); } -//========================================================================== -// -// -// -//========================================================================== - -void gl_DestroyUserShaders() -{ - // todo -} - //========================================================================== // // Find a shader definition @@ -696,8 +664,10 @@ void gl_ParseShaderDef(FScanner &sc, bool isLight) bool CoreLump = false; sc.SetCMode(true); sc.MustGetString(); - FName shadername = sc.String; + def->mName = sc.String; sc.MustGetStringName("{"); + while (!sc.CheckString("}")) + { sc.MustGetString(); if (sc.Compare("source")) { @@ -722,7 +692,7 @@ void gl_ParseShaderDef(FScanner &sc, bool isLight) def->bRequireAlphaTest = true; } // parse other stuff here. - sc.MustGetStringName("}"); + } int lumpnum = Wads.CheckNumForFullName(def->mSourceFile); if (lumpnum < 0) @@ -752,3 +722,22 @@ void gl_ParseShaderDef(FScanner &sc, bool isLight) } pArr->Push(def); } + + +void gl_DestroyUserShaders() +{ + if (GLRenderer != NULL && GLRenderer->mShaderManager != NULL) + { + GLRenderer->mShaderManager->Clean(); + } + for (unsigned int i = 0; i < TexelShaders.Size(); i++) + { + delete TexelShaders[i]; + } + for (unsigned int i = 0; i < LightShaders.Size(); i++) + { + delete LightShaders[i]; + } + TexelShaders.Clear(); + LightShaders.Clear(); +} diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index bc132c1924..bed58c69b2 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -271,25 +271,33 @@ public: //========================================================================== class FShaderManager { - TArray mTextureEffects; - TArray mTextureEffectsNAT; + struct FShaderContainer + { + FName mTexelName; + FName mLightName; + FShader *mShader; + FShader *mShaderNAT; + }; + + TArray mShaders; + FShader *mActiveShader; FShader *mEffectShaders[MAX_EFFECTS]; - void Clean(); void CompileShaders(); void FindAllUsedShaders(); + FShader *Compile(const char *ShaderName, const char *TexShaderPath, const char *LightShaderPath, bool usediscard); + public: FShaderManager(); ~FShaderManager(); - FShader *Compile(const char *ShaderName, const char *TexShaderPath, const char *LightShaderPath, bool usediscard); - //int Find(const char *mame); FShader *BindEffect(int effect); void SetActiveShader(FShader *sh); void ApplyMatrices(VSMatrix *proj, VSMatrix *view); unsigned int GetShaderIndex(FName tex, FName light); + void Clean(); FShader *GetActiveShader() const { return mActiveShader; @@ -297,32 +305,32 @@ public: void ResetFixedColormap() { - for (unsigned i = 0; i < mTextureEffects.Size(); i++) + for (unsigned i = 0; i < mShaders.Size(); i++) { - mTextureEffects[i]->currentfixedcolormap = -1; - } - for (unsigned i = 0; i < mTextureEffectsNAT.Size(); i++) - { - mTextureEffectsNAT[i]->currentfixedcolormap = -1; + if (mShaders[i].mShader != NULL) mShaders[i].mShader->currentfixedcolormap = -1; + if (mShaders[i].mShaderNAT != NULL) mShaders[i].mShaderNAT->currentfixedcolormap = -1; } } FShader *Get(unsigned int eff, bool alphateston) { - // indices 0-2 match the warping modes, 3 is brightmap, 4 no texture, the following are custom - if (!alphateston && eff <= 3) + if (eff < mShaders.Size()) { - return mTextureEffectsNAT[eff]; // Non-alphatest shaders are only created for default, warp1+2 and brightmap. The rest won't get used anyway - } - if (eff < mTextureEffects.Size()) - { - return mTextureEffects[eff]; + if (!alphateston && mShaders[eff].mShaderNAT != NULL) return mShaders[eff].mShaderNAT; + return mShaders[eff].mShader; } return NULL; } -}; -#define FIRST_USER_SHADER 12 + void Validate() + { + if (mShaders.Size() == 0) + { + CompileShaders(); + } + } + +}; enum { diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 7a3fef1a3b..0d5ef7f556 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -57,6 +57,7 @@ #include "gl/renderer/gl_renderstate.h" #include "gl/renderer/gl_lightdata.h" #include "gl/data/gl_data.h" +#include "gl/shaders/gl_shader.h" #include "gl/textures/gl_hwtexture.h" #include "gl/textures/gl_texture.h" #include "gl/textures/gl_translate.h" @@ -536,6 +537,7 @@ void OpenGLFrameBuffer::GameRestart() UpdatePalette (); ScreenshotBuffer = NULL; LastCamera = NULL; + GLRenderer->mShaderManager->Validate(); gl_GenerateGlobalBrightmapFromColormap(); } diff --git a/wadsrc/static/gldefs.txt b/wadsrc/static/gldefs.txt index dcc1c74b53..73b3465431 100644 --- a/wadsrc/static/gldefs.txt +++ b/wadsrc/static/gldefs.txt @@ -6,6 +6,7 @@ TexelShader "None" TexelShader "No Texture" { source "shaders/glsl/func_notexture.fp", corelump + nolightshader } TexelShader "Warp 1" @@ -93,6 +94,6 @@ LightShader "None" LightShader "Brightmap" { - source "shaders/glsl/func_detail.fp", corelump + source "shaders/glsl/func_brightmap.fp", corelump //property Texture "texture2" // will be implemented later. }