From 58c62e071ca1d6016ea24813f1f84a133c491da3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 30 May 2020 21:45:17 +0200 Subject: [PATCH] - use FMaterial. --- source/common/rendering/gl/gl_hwtexture.cpp | 8 +- source/glbackend/gl_renderstate.h | 20 +++- source/glbackend/gl_texture.cpp | 108 +++----------------- source/glbackend/glbackend.cpp | 78 +++++++++++--- source/glbackend/glbackend.h | 20 ++++ 5 files changed, 127 insertions(+), 107 deletions(-) diff --git a/source/common/rendering/gl/gl_hwtexture.cpp b/source/common/rendering/gl/gl_hwtexture.cpp index d16af5e8c..520369163 100644 --- a/source/common/rendering/gl/gl_hwtexture.cpp +++ b/source/common/rendering/gl/gl_hwtexture.cpp @@ -307,7 +307,11 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i // Bind it to the system. if (!Bind(texunit, needmipmap)) { - + if (flags & CTF_Indexed) + { + glTextureBytes = 1; + forcenofilter = true; + } int w = 0, h = 0; // Create this texture @@ -331,7 +335,7 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i return false; } } - if (forcenofilter) clampmode += CLAMP_NOFILTER - CLAMP_NONE; + if (forcenofilter && clampmode <= CLAMP_XY) clampmode += CLAMP_NOFILTER - CLAMP_NONE; GLRenderer->mSamplerManager->Bind(texunit, clampmode, 255); return true; } diff --git a/source/glbackend/gl_renderstate.h b/source/glbackend/gl_renderstate.h index f44cbcdd9..a485ce627 100644 --- a/source/glbackend/gl_renderstate.h +++ b/source/glbackend/gl_renderstate.h @@ -70,6 +70,23 @@ struct FDepthBiasState } }; +struct FMaterialState +{ + FMaterial* mMaterial; + int mClampMode; + int mTranslation; + int mOverrideShader; + bool mChanged; + + void Reset() + { + mMaterial = nullptr; + mTranslation = 0; + mClampMode = CLAMP_NONE; + mOverrideShader = -1; + mChanged = false; + } +}; struct PolymostRenderState { @@ -89,6 +106,7 @@ struct PolymostRenderState PalEntry fullscreenTint = 0xffffff, hictint = 0xffffff, hictint_overlay = 0xffffff; int hictint_flags = -1; FDepthBiasState mBias{ }; + FMaterialState mMaterial; OpenGLRenderer::FHardwareTexture* PaletteTexture = nullptr, * LookupTexture = nullptr; int StateFlags = STF_COLORMASK|STF_DEPTHMASK; @@ -97,9 +115,9 @@ struct PolymostRenderState PalEntry ClearColor = 0; short vp_x, vp_y, vp_w, vp_h; short sc_x = SHRT_MIN, sc_y, sc_w, sc_h; - int texIds[4], samplerIds[4]; PalEntry FogColor; + void ApplyMaterial(FMaterial* mat, int clampmode, int translation, int overrideshader); void Apply(PolymostShader *shader, GLState &oldstate); }; diff --git a/source/glbackend/gl_texture.cpp b/source/glbackend/gl_texture.cpp index 16add7a7b..90706843d 100644 --- a/source/glbackend/gl_texture.cpp +++ b/source/glbackend/gl_texture.cpp @@ -63,113 +63,39 @@ OpenGLRenderer::FHardwareTexture* GLInstance::LoadTexture(FTexture *tex, int tex bool GLInstance::SetTexture(int picnum, FGameTexture* tex, int paletteid, int method, int sampleroverride) { - TexturePick pick; - if (!PickTexture(picnum, tex, paletteid, pick)) return false; + TexturePick texpick; + if (!PickTexture(picnum, tex, paletteid, texpick)) return false; - GLInterface.SetPalette(GetTranslationType(pick.translation & 0x7fffffff) - Translation_Remap); - GLInterface.SetPalswap(GetTranslationIndex(pick.translation)); - GLInterface.SetBasepalTint(pick.basepalTint); - - bool texbound[3] = {}; - //int MatrixChange = 0; - //VSMatrix texmat; - - // This is intentionally the same value for both parameters. The shader does not use the same uniform for modulation and overlay colors. - GLInterface.SetTinting(pick.tintFlags, pick.tintColor, pick.tintColor); - - // Load the main texture - - int TextureType = (pick.translation & 0x80000000) ? TT_INDEXED : TT_TRUECOLOR; - int lookuppal = pick.translation & 0x7fffffff; - int bindflags = 0; - - auto mtex = LoadTexture(tex->GetTexture(), TextureType, lookuppal); - if (mtex) - { + int TextureType = (texpick.translation & 0x80000000) ? TT_INDEXED : TT_TRUECOLOR; auto sampler = (method & DAMETH_CLAMPED) ? (sampleroverride != -1 ? sampleroverride : SamplerClampXY) : SamplerRepeat; if (TextureType == TT_INDEXED) { sampler = sampler + SamplerNoFilterRepeat - SamplerRepeat; - bindflags = CTF_Indexed; } else if (tex->isHardwareCanvas()) { sampler = CLAMP_CAMTEX; } - UseDetailMapping(false); - UseGlowMapping(false); - UseBrightmaps(false); - mtex->BindOrCreate(tex->GetTexture(), 0, sampler, lookuppal, bindflags); - BindTexture(0, mtex, sampler); - // Needs a) testing and b) verification for correctness. This doesn't look like it makes sense. -#if 0 - if (rep && (rep->scale.x != 1.0f || rep->scale.y != 1.0f)) - { - //texmat.loadIdentity(); - //texmat.scale(rep->scale.x, rep->scale.y, 1.0f); - //GLInterface.SetMatrix(Matrix_Texture, &texmat); - } -#endif - - // Also load additional layers needed for this texture. - if (hw_detailmapping) - { - auto det = tex->GetDetailmap(); - auto detscale = tex->GetDetailScale(); - if (det) - { - auto htex = LoadTexture(det, TT_TRUECOLOR, 0); - UseDetailMapping(true); - htex->BindOrCreate(det, 2, CLAMP_NONE, 0, 0); - BindTexture(2, htex, SamplerRepeat); - texbound[0] = true; - - /* todo: - GLInterface.SetDetailScale(detscale); - */ - } - } - if (hw_glowmapping) - { - auto glow = tex->GetGlowmap(); - if (glow) - { - auto htex = LoadTexture(glow, TT_TRUECOLOR, 0); - UseGlowMapping(true); - htex->BindOrCreate(glow, 3, sampler, 0, CTF_Upscale); - BindTexture(3, htex, SamplerRepeat); - texbound[1] = true; - } - } - - if (!(globalflags & GLOBAL_NO_GL_FULLBRIGHT)) - { - auto btex = tex->GetBrightmap(); - if (btex) - { - auto htex = LoadTexture(btex, TT_TRUECOLOR, lookuppal); - if (htex != nullptr) - { - UseBrightmaps(true); - htex->BindOrCreate(btex, 1, sampler, 0, CTF_Upscale); - BindTexture(1, htex, sampler); - texbound[2] = true; - } - } - } - if (!texbound[0]) UnbindTexture(2); - if (!texbound[1]) UnbindTexture(3); - if (!texbound[2]) UnbindTexture(1); - - } - else return false; + int lookuppal = texpick.translation & 0x7fffffff; + // This is intentionally the same value for both parameters. The shader does not use the same uniform for modulation and overlay colors. + GLInterface.SetTinting(texpick.tintFlags, texpick.tintColor, texpick.tintColor); + GLInterface.SetPalette(GetTranslationType(lookuppal) - Translation_Remap); + GLInterface.SetPalswap(GetTranslationIndex(lookuppal)); + GLInterface.SetBasepalTint(texpick.basepalTint); + auto &mat = renderState.mMaterial; + mat.mMaterial = FMaterial::ValidateTexture(tex, 0); // todo allow scaling + mat.mClampMode = sampler; + mat.mTranslation = texpick.translation; + mat.mOverrideShader = 0; + mat.mChanged = true; + if (TextureType == TT_INDEXED) renderState.Flags |= RF_UsePalette; + else renderState.Flags &= ~RF_UsePalette; GLInterface.SetAlphaThreshold(tex->alphaThreshold); return true; } - //=========================================================================== // // stand-ins for the texture system. Nothing of this is used right now, but needs to be present to satisfy the linker diff --git a/source/glbackend/glbackend.cpp b/source/glbackend/glbackend.cpp index 8e2b04738..dd6740d9a 100644 --- a/source/glbackend/glbackend.cpp +++ b/source/glbackend/glbackend.cpp @@ -284,26 +284,78 @@ void GLInstance::DrawImGui(ImDrawData* data) } +//=========================================================================== +// +// Binds a texture to the renderer +// +//=========================================================================== + +void PolymostRenderState::ApplyMaterial(FMaterial* mat, int clampmode, int translation, int overrideshader) +{ + + auto tex = mat->Source(); + //mEffectState = overrideshader >= 0 ? overrideshader : mat->GetShaderIndex(); + //mShaderTimer = tex->GetShaderSpeed(); + //SetSpecular(tex->GetGlossiness(), tex->GetSpecularLevel()); + //if (tex->isHardwareCanvas()) static_cast(tex->GetTexture())->NeedUpdate(); + + clampmode = tex->GetClampMode(clampmode); + + // avoid rebinding the same texture multiple times. + //if (mat == lastMaterial && lastClamp == clampmode && translation == lastTranslation) return; +#if 0 + lastMaterial = mat; + lastClamp = clampmode; + lastTranslation = translation; +#endif + + int scf = 0; + if (Flags & RF_UsePalette) + { + scf |= CTF_Indexed; + translation = -1; + } + + int usebright = false; + int maxbound = 0; + + int numLayers = mat->NumLayers(); + MaterialLayerInfo* layer; + auto base = static_cast(mat->GetLayer(0, translation, &layer)); + scf |= layer->scaleFlags; + if (base->BindOrCreate(layer->layerTexture, 0, clampmode, translation, scf)) + { + for (int i = 1; i < numLayers; i++) + { + auto systex = static_cast(mat->GetLayer(i, 0, &layer)); + // fixme: Upscale flags must be disabled for certain layers. + systex->BindOrCreate(layer->layerTexture, i, clampmode, 0, layer->scaleFlags); + maxbound = i; + } + } + // The palette lookup must be done manually. +#if 0 + // unbind everything from the last texture that's still active + for (int i = maxbound + 1; i <= 16/*maxBoundMaterial*/; i++) + { + OpenGLRenderer::FHardwareTexture::Unbind(i); + //maxBoundMaterial = maxbound; + } +#endif +} + void PolymostRenderState::Apply(PolymostShader* shader, GLState &oldState) { if (!OpenGLRenderer::GLRenderer) return; auto sm = OpenGLRenderer::GLRenderer->mSamplerManager; + bool reset = false; - for (int i = 0; i < MAX_TEXTURES; i++) + if (mMaterial.mChanged) { - if ( texIds[i] != oldState.TexId[i] || samplerIds[i] != oldState.SamplerId[i]) - { - if (i != 0) - { - glActiveTexture(GL_TEXTURE0 + i); - reset = true; - } - glBindTexture(GL_TEXTURE_2D, texIds[i]); - sm->Bind(i, samplerIds[i], -1); - oldState.TexId[i] = texIds[i]; - oldState.SamplerId[i] = samplerIds[i]; - } + mMaterial.mChanged = false; + ApplyMaterial(mMaterial.mMaterial, mMaterial.mClampMode, mMaterial.mTranslation, mMaterial.mOverrideShader); } + if (PaletteTexture != nullptr) { PaletteTexture->Bind(4, false); diff --git a/source/glbackend/glbackend.h b/source/glbackend/glbackend.h index a0dcf4639..864228791 100644 --- a/source/glbackend/glbackend.h +++ b/source/glbackend/glbackend.h @@ -9,6 +9,7 @@ #include "matrix.h" #include "palentry.h" #include "renderstyle.h" +#include "hw_material.h" class FShader; class PolymostShader; @@ -352,6 +353,24 @@ public: SetColor(r * (1 / 255.f), g * (1 / 255.f), b * (1 / 255.f), a * (1 / 255.f)); } + void SetMaterial(FMaterial* mat, int clampmode, int translation, int overrideshader) + { + assert(mat); + renderState.mMaterial.mMaterial = mat; + renderState.mMaterial.mClampMode = clampmode; + renderState.mMaterial.mTranslation = translation; + renderState.mMaterial.mOverrideShader = overrideshader; + renderState.mMaterial.mChanged = true; + //mTextureModeFlags = mat->GetLayerFlags(); + } + + void SetMaterial(FGameTexture* tex, EUpscaleFlags upscalemask, int scaleflags, int clampmode, int translation, int overrideshader) + { + assert(tex); + if (shouldUpscale(tex, upscalemask)) scaleflags |= CTF_Upscale; + SetMaterial(FMaterial::ValidateTexture(tex, scaleflags), clampmode, translation, overrideshader); + } +#if 0 void BindTexture(int texunit, OpenGLRenderer::FHardwareTexture* tex, int sampler) { if (!tex) return; @@ -379,6 +398,7 @@ public: UnbindTexture(texunit); } } +#endif void UseColorOnly(bool yes) {