diff --git a/src/common/rendering/hwrenderer/data/hw_renderstate.h b/src/common/rendering/hwrenderer/data/hw_renderstate.h index 21c8c3ef2..00e3d943d 100644 --- a/src/common/rendering/hwrenderer/data/hw_renderstate.h +++ b/src/common/rendering/hwrenderer/data/hw_renderstate.h @@ -174,6 +174,11 @@ protected: virtual void DoDrawIndexed(int dt, int index, int count, bool apply) = 0; public: + int getShaderIndex() + { + return (mMaterial.mOverrideShader > 0) ? mMaterial.mOverrideShader : (mMaterial.mMaterial ? mMaterial.mMaterial->GetShaderIndex() : 0); + } + uint64_t firstFrame = 0; void Reset() @@ -541,10 +546,10 @@ public: } private: - void SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader); + void SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader, PClass *cls); public: - void SetMaterial(FGameTexture* tex, EUpscaleFlags upscalemask, int scaleflags, int clampmode, int translation, int overrideshader) + void SetMaterial(FGameTexture* tex, EUpscaleFlags upscalemask, int scaleflags, int clampmode, int translation, int overrideshader, PClass *cls = nullptr) { tex->setSeen(); if (!sysCallbacks.PreBindTexture || !sysCallbacks.PreBindTexture(this, tex, upscalemask, scaleflags, clampmode, translation, overrideshader)) @@ -553,12 +558,12 @@ public: } auto mat = FMaterial::ValidateTexture(tex, scaleflags); assert(mat); - SetMaterial(mat, clampmode, translation, overrideshader); + SetMaterial(mat, clampmode, translation, overrideshader, cls); } - void SetMaterial(FGameTexture* tex, EUpscaleFlags upscalemask, int scaleflags, int clampmode, FTranslationID translation, int overrideshader) + void SetMaterial(FGameTexture* tex, EUpscaleFlags upscalemask, int scaleflags, int clampmode, FTranslationID translation, int overrideshader, PClass *cls = nullptr) { - SetMaterial(tex, upscalemask, scaleflags, clampmode, translation.index(), overrideshader); + SetMaterial(tex, upscalemask, scaleflags, clampmode, translation.index(), overrideshader, cls); } diff --git a/src/common/textures/hw_material.cpp b/src/common/textures/hw_material.cpp index 1e7e635d8..d8ae8fcf5 100644 --- a/src/common/textures/hw_material.cpp +++ b/src/common/textures/hw_material.cpp @@ -36,29 +36,29 @@ CVAR(Bool, gl_customshader, true, 0); TArray usershaders; -void FRenderState::SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader) +void FRenderState::SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader, PClass *cls) { mMaterial.mMaterial = mat; mMaterial.mClampMode = clampmode; mMaterial.mTranslation = translation; - if(overrideshader > 0) + if(overrideshader >= FIRST_USER_SHADER) { mMaterial.mOverrideShader = overrideshader; mMaterial.globalShaderAddr = {0, 3, 0}; } else - { // handle per-map global shaders + { // handle per-map/per-class global shaders GlobalShaderAddr addr; - auto globalshader = GetGlobalShader(mat->GetShaderIndex(), nullptr, addr); + auto globalshader = GetGlobalShader((overrideshader > 0) ? overrideshader : mat->GetShaderIndex(), cls, addr); - if(addr.type == 1 && globalshader->shaderindex >= 0) + if(addr.type > 0 && globalshader->shaderindex >= 0) { mMaterial.mOverrideShader = globalshader->shaderindex; mMaterial.globalShaderAddr = addr; } else { - mMaterial.mOverrideShader = -1; + mMaterial.mOverrideShader = overrideshader; mMaterial.globalShaderAddr = {0, 3, 0}; } } diff --git a/src/r_data/gldefs.cpp b/src/r_data/gldefs.cpp index a1446ce42..37b67e1db 100644 --- a/src/r_data/gldefs.cpp +++ b/src/r_data/gldefs.cpp @@ -68,7 +68,12 @@ TMap classshaders[NUM_BUILTIN_SHADERS]; const GlobalShaderDesc * GetGlobalShader(int shaderNum, PClass * curActor, GlobalShaderAddr &addr) { - if(shaderNum < NUM_BUILTIN_SHADERS) + if(shaderNum >= NUM_BUILTIN_SHADERS && usershaders[shaderNum - NUM_BUILTIN_SHADERS].shaderFlags & SFlag_Global) + { // allow class and map shaders to override gobal shaders + shaderNum = usershaders[shaderNum - NUM_BUILTIN_SHADERS].shaderType; + } + + if(shaderNum >= 0 && shaderNum < NUM_BUILTIN_SHADERS) { GlobalShaderDesc * shader; if(curActor) diff --git a/src/rendering/hwrenderer/hw_models.cpp b/src/rendering/hwrenderer/hw_models.cpp index 152663304..de8ab1bc7 100644 --- a/src/rendering/hwrenderer/hw_models.cpp +++ b/src/rendering/hwrenderer/hw_models.cpp @@ -136,7 +136,7 @@ void FHWModelRenderer::SetInterpolation(double inter) void FHWModelRenderer::SetMaterial(FGameTexture *skin, bool clampNoFilter, FTranslationID translation, AActor * act) { - state.SetMaterial(skin, UF_Skin, 0, clampNoFilter ? CLAMP_NOFILTER : CLAMP_NONE, translation, -1); + state.SetMaterial(skin, UF_Skin, 0, clampNoFilter ? CLAMP_NOFILTER : CLAMP_NONE, translation, -1, act ? act->GetClass() : nullptr); state.SetLightIndex(modellightindex); } diff --git a/src/rendering/hwrenderer/scene/hw_sprites.cpp b/src/rendering/hwrenderer/scene/hw_sprites.cpp index 9cafe2a14..61acacd37 100644 --- a/src/rendering/hwrenderer/scene/hw_sprites.cpp +++ b/src/rendering/hwrenderer/scene/hw_sprites.cpp @@ -238,7 +238,7 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent) } uint32_t spritetype = actor? uint32_t(actor->renderflags & RF_SPRITETYPEMASK) : 0; - if (texture) state.SetMaterial(texture, UF_Sprite, (spritetype == RF_FACESPRITE) ? CTF_Expand : 0, clampmode, translation, OverrideShader); + if (texture) state.SetMaterial(texture, UF_Sprite, (spritetype == RF_FACESPRITE) ? CTF_Expand : 0, clampmode, translation, OverrideShader, actor ? actor->GetClass() : nullptr); else if (!modelframe) state.EnableTexture(false); //SetColor(lightlevel, rel, Colormap, trans);