From 292458ee2d9adf3172c60cc7176b3c31bd82fabb Mon Sep 17 00:00:00 2001 From: usernameak Date: Wed, 4 Jul 2018 21:36:33 +0300 Subject: [PATCH 1/6] Custom hardware shaders now can use custom texture units --- src/hwrenderer/textures/hw_material.cpp | 6 ++++++ src/r_data/gldefs.cpp | 18 ++++++++++++++++++ src/textures/textures.h | 5 +++++ 3 files changed, 29 insertions(+) diff --git a/src/hwrenderer/textures/hw_material.cpp b/src/hwrenderer/textures/hw_material.cpp index 23242c91c8..6e31226a43 100644 --- a/src/hwrenderer/textures/hw_material.cpp +++ b/src/hwrenderer/textures/hw_material.cpp @@ -154,6 +154,12 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) { if (tx->shaderindex >= FIRST_USER_SHADER) { + for (auto &texture : tx->CustomShaderTextures) + { + if(texture == nullptr) continue; + ValidateSysTexture(texture, expanded); + mTextureLayers.Push({ texture, false }); + } mShaderIndex = tx->shaderindex; } else diff --git a/src/r_data/gldefs.cpp b/src/r_data/gldefs.cpp index 4ebd8283fd..5738680214 100644 --- a/src/r_data/gldefs.cpp +++ b/src/r_data/gldefs.cpp @@ -1398,6 +1398,24 @@ class GLDefsParser sc.MustGetFloat(); speed = float(sc.Float); } + else if (sc.Compare("texture")) + { + sc.MustGetString(); + bool okay = false; + for(int i = 0; i < MAX_CUSTOM_HW_SHADER_TEXTURES; i++) { + if(!tex->CustomShaderTextures[i]) { + tex->CustomShaderTextures[i] = TexMan.FindTexture(sc.String, ETextureType::Any, FTextureManager::TEXMAN_TryAny); + if (!tex->CustomShaderTextures[i]) { + sc.ScriptError("Custom hardware shader texture '%s' not found in texture '%s'\n", sc.String, tex? tex->Name.GetChars() : "(null)"); + } + okay = true; + break; + } + } + if(!okay) { + sc.ScriptError("Error: out of texture units in texture '%s'", tex? tex->Name.GetChars() : "(null)"); + } + } } if (!tex) { diff --git a/src/textures/textures.h b/src/textures/textures.h index f4beed8229..77b133cbb4 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -44,6 +44,9 @@ #include "r_data/r_translate.h" #include +// 15 because 0th texture is our texture +#define MAX_CUSTOM_HW_SHADER_TEXTURES 15 + typedef TMap SpriteHits; enum MaterialShaderIndex @@ -244,6 +247,8 @@ public: FTexture *Metallic = nullptr; // Metalness texture for the physically based rendering (PBR) light model FTexture *Roughness = nullptr; // Roughness texture for PBR FTexture *AmbientOcclusion = nullptr; // Ambient occlusion texture for PBR + + FTexture *CustomShaderTextures[MAX_CUSTOM_HW_SHADER_TEXTURES] = { nullptr }; // Custom texture maps for custom hardware shaders FString Name; ETextureType UseType; // This texture's primary purpose From fa51a54042bb29d9f36b5de62275eb31a0734eb9 Mon Sep 17 00:00:00 2001 From: usernameak Date: Thu, 5 Jul 2018 15:01:16 +0300 Subject: [PATCH 2/6] Made ability to define custom material shaders for ProcessMaterial function --- src/gl/shaders/gl_shader.cpp | 3 ++- src/r_data/gldefs.cpp | 10 +++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 8bff7ee2af..31e9bbc5d0 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -496,6 +496,7 @@ static const FDefaultShader defaultshaders[]= }; TArray usershaders; +TArray usermaterials; struct FEffectShader { @@ -647,7 +648,7 @@ void FShaderCollection::CompileShaders(EPassType passType) FString name = ExtractFileBase(usershaders[i]); FName sfn = name; - FShader *shc = Compile(sfn, usershaders[i], "shaders/glsl/material_normal.fp", "", true, passType); + FShader *shc = Compile(sfn, usershaders[i], usermaterials[i], "", true, passType); mMaterialShaders.Push(shc); } diff --git a/src/r_data/gldefs.cpp b/src/r_data/gldefs.cpp index 5738680214..97619cd0f9 100644 --- a/src/r_data/gldefs.cpp +++ b/src/r_data/gldefs.cpp @@ -51,6 +51,7 @@ void AddLightAssociation(const char *actor, const char *frame, const char *light void InitializeActorLights(TArray &LightAssociations); extern TArray usershaders; +extern TArray usermaterials; extern TDeletingArray LightDefaults; @@ -1378,6 +1379,7 @@ class GLDefsParser bool iwad = false; int maplump = -1; FString maplumpname; + FString materiallumpname = "shaders/glsl/material_normal.fp"; float speed = 1.f; sc.MustGetString(); @@ -1393,6 +1395,11 @@ class GLDefsParser sc.MustGetString(); maplumpname = sc.String; } + else if (sc.Compare("material")) + { + sc.MustGetString(); + materiallumpname = sc.String; + } else if (sc.Compare("speed")) { sc.MustGetFloat(); @@ -1432,13 +1439,14 @@ class GLDefsParser tex->shaderspeed = speed; for (unsigned i = 0; i < usershaders.Size(); i++) { - if (!usershaders[i].CompareNoCase(maplumpname)) + if (!usershaders[i].CompareNoCase(maplumpname) && !usermaterials[i].CompareNoCase(materiallumpname)) { tex->shaderindex = i + FIRST_USER_SHADER; return; } } tex->shaderindex = usershaders.Push(maplumpname) + FIRST_USER_SHADER; + usermaterials.Push(materiallumpname); } } } From e306d4ee04a55a4ab8641a627edab7ec7801a765 Mon Sep 17 00:00:00 2001 From: usernameak Date: Thu, 5 Jul 2018 17:01:45 +0300 Subject: [PATCH 3/6] Fix codestyle; add ability to name the textures --- src/gl/shaders/gl_shader.cpp | 3 ++- src/r_data/gldefs.cpp | 32 +++++++++++++++++++++++++++----- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 31e9bbc5d0..d14d807584 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -497,6 +497,7 @@ static const FDefaultShader defaultshaders[]= TArray usershaders; TArray usermaterials; +TArray usershaderdefs; struct FEffectShader { @@ -648,7 +649,7 @@ void FShaderCollection::CompileShaders(EPassType passType) FString name = ExtractFileBase(usershaders[i]); FName sfn = name; - FShader *shc = Compile(sfn, usershaders[i], usermaterials[i], "", true, passType); + FShader *shc = Compile(sfn, usershaders[i], usermaterials[i], usershaderdefs[i], true, passType); mMaterialShaders.Push(shc); } diff --git a/src/r_data/gldefs.cpp b/src/r_data/gldefs.cpp index 97619cd0f9..d46dc450e1 100644 --- a/src/r_data/gldefs.cpp +++ b/src/r_data/gldefs.cpp @@ -52,6 +52,7 @@ void InitializeActorLights(TArray &LightAssociations); extern TArray usershaders; extern TArray usermaterials; +extern TArray usershaderdefs; extern TDeletingArray LightDefaults; @@ -1380,6 +1381,8 @@ class GLDefsParser int maplump = -1; FString maplumpname; FString materiallumpname = "shaders/glsl/material_normal.fp"; + FString texnameDefs = ""; + TArray texNameList; float speed = 1.f; sc.MustGetString(); @@ -1407,19 +1410,35 @@ class GLDefsParser } else if (sc.Compare("texture")) { + sc.MustGetString(); + FString textureName = sc.String; + for(FString &texName : texNameList) + { + if(!texName.Compare(textureName)) + { + sc.ScriptError("Trying to redefine custom hardware shader texture '%s' in texture '%s'\n", textureName.GetChars(), tex? tex->Name.GetChars() : "(null)"); + } + } + texNameList.Push(textureName); sc.MustGetString(); bool okay = false; - for(int i = 0; i < MAX_CUSTOM_HW_SHADER_TEXTURES; i++) { - if(!tex->CustomShaderTextures[i]) { + for (int i = 0; i < MAX_CUSTOM_HW_SHADER_TEXTURES; i++) + { + if (!tex->CustomShaderTextures[i]) + { tex->CustomShaderTextures[i] = TexMan.FindTexture(sc.String, ETextureType::Any, FTextureManager::TEXMAN_TryAny); - if (!tex->CustomShaderTextures[i]) { + if (!tex->CustomShaderTextures[i]) + { sc.ScriptError("Custom hardware shader texture '%s' not found in texture '%s'\n", sc.String, tex? tex->Name.GetChars() : "(null)"); } + + texnameDefs.AppendFormat("#define %s texture%d\n", textureName.GetChars(), i + 2); okay = true; break; } } - if(!okay) { + if(!okay) + { sc.ScriptError("Error: out of texture units in texture '%s'", tex? tex->Name.GetChars() : "(null)"); } } @@ -1439,7 +1458,9 @@ class GLDefsParser tex->shaderspeed = speed; for (unsigned i = 0; i < usershaders.Size(); i++) { - if (!usershaders[i].CompareNoCase(maplumpname) && !usermaterials[i].CompareNoCase(materiallumpname)) + if (!usershaders[i].CompareNoCase(maplumpname) && + !usermaterials[i].CompareNoCase(materiallumpname) && + !usershaderdefs[i].Compare(texnameDefs)) { tex->shaderindex = i + FIRST_USER_SHADER; return; @@ -1447,6 +1468,7 @@ class GLDefsParser } tex->shaderindex = usershaders.Push(maplumpname) + FIRST_USER_SHADER; usermaterials.Push(materiallumpname); + usershaderdefs.Push(texnameDefs); } } } From 7de9e1f0974478b0941e98ce517c251f4b91a4a9 Mon Sep 17 00:00:00 2001 From: usernameak Date: Thu, 5 Jul 2018 17:25:55 +0300 Subject: [PATCH 4/6] Added ability to set defines in custom HW shaders --- src/r_data/gldefs.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/r_data/gldefs.cpp b/src/r_data/gldefs.cpp index d46dc450e1..b74b1de258 100644 --- a/src/r_data/gldefs.cpp +++ b/src/r_data/gldefs.cpp @@ -1442,6 +1442,18 @@ class GLDefsParser sc.ScriptError("Error: out of texture units in texture '%s'", tex? tex->Name.GetChars() : "(null)"); } } + else if(sc.Compare("define")) + { + sc.MustGetString(); + FString defineName = sc.String; + FString defineValue = ""; + if(sc.CheckToken('=')) + { + sc.MustGetString(); + defineValue = sc.String; + } + texnameDefs.AppendFormat("#define %s %s\n", defineName.GetChars(), defineValue.GetChars()); + } } if (!tex) { From 69a327144059b58e9a195696a68f5ace9803f9e9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 14 Jul 2018 12:10:41 +0200 Subject: [PATCH 5/6] - removed the unused feature to allow animated material layers. This was a relic from trying to support ZDoomGL's texture shader system but would make texture management with Vulkan significantly more complicated because it would require dynamic descriptor set management for textures which can cause a lot of overhead. --- src/hwrenderer/textures/hw_material.cpp | 20 +++++--------------- src/hwrenderer/textures/hw_material.h | 11 ++--------- 2 files changed, 7 insertions(+), 24 deletions(-) diff --git a/src/hwrenderer/textures/hw_material.cpp b/src/hwrenderer/textures/hw_material.cpp index 6e31226a43..cca6c9b2a8 100644 --- a/src/hwrenderer/textures/hw_material.cpp +++ b/src/hwrenderer/textures/hw_material.cpp @@ -158,7 +158,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) { if(texture == nullptr) continue; ValidateSysTexture(texture, expanded); - mTextureLayers.Push({ texture, false }); + mTextureLayers.Push(texture); } mShaderIndex = tx->shaderindex; } @@ -169,7 +169,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) for (auto &texture : { tx->Normal, tx->Specular }) { ValidateSysTexture(texture, expanded); - mTextureLayers.Push({ texture, false }); + mTextureLayers.Push(texture); } mShaderIndex = SHADER_Specular; } @@ -178,7 +178,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) for (auto &texture : { tx->Normal, tx->Metallic, tx->Roughness, tx->AmbientOcclusion }) { ValidateSysTexture(texture, expanded); - mTextureLayers.Push({ texture, false }); + mTextureLayers.Push(texture); } mShaderIndex = SHADER_PBR; } @@ -187,8 +187,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) if (tx->Brightmap != NULL) { ValidateSysTexture(tx->Brightmap, expanded); - FTextureLayer layer = {tx->Brightmap, false}; - mTextureLayers.Push(layer); + mTextureLayers.Push(tx->Brightmap); if (mShaderIndex == SHADER_Specular) mShaderIndex = SHADER_SpecularBrightmap; else if (mShaderIndex == SHADER_PBR) @@ -448,16 +447,7 @@ void FMaterial::Bind(int clampmode, int translation) { for(unsigned i=0;iid; - layer = TexMan(id); - } - else - { - layer = mTextureLayers[i].texture; - } + FTexture *layer = mTextureLayers[i]; auto systex = ValidateSysTexture(layer, mExpanded); systex->BindOrCreate(layer, i+1, clampmode, 0, mExpanded ? CTF_Expand : 0); maxbound = i+1; diff --git a/src/hwrenderer/textures/hw_material.h b/src/hwrenderer/textures/hw_material.h index 3ee1d935ce..7a3b2f391c 100644 --- a/src/hwrenderer/textures/hw_material.h +++ b/src/hwrenderer/textures/hw_material.h @@ -52,12 +52,6 @@ class FMaterial { friend class FRenderState; - struct FTextureLayer - { - FTexture *texture; - bool animated; - }; - // This array is needed because not all textures are managed by the texture manager // but some code needs to discard all hardware dependent data attached to any created texture. // Font characters are not, for example. @@ -65,7 +59,7 @@ class FMaterial static int mMaxBound; IHardwareTexture *mBaseLayer; - TArray mTextureLayers; + TArray mTextureLayers; int mShaderIndex; short mLeftOffset; @@ -95,9 +89,8 @@ public: void PrecacheList(SpriteHits &translations); void AddTextureLayer(FTexture *tex) { - FTextureLayer layer = { tex, false }; ValidateTexture(tex, false); - mTextureLayers.Push(layer); + mTextureLayers.Push(tex); } bool isMasked() const { From 7817e6a7b250378361e7abe191a81fe984a78aa2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 14 Jul 2018 13:05:49 +0200 Subject: [PATCH 6/6] - moved the texture binding code back to the OpenGL specific parts. turns out that this cannot be consolidated with Vulkan because the semantics are far too different here. --- src/gl/renderer/gl_renderer.cpp | 22 ++++++- src/gl/renderer/gl_renderer.h | 6 +- src/gl/renderer/gl_renderstate.cpp | 63 +++++++++++++++++++ src/gl/renderer/gl_renderstate.h | 27 ++++---- src/gl/system/gl_framebuffer.cpp | 11 ++-- src/gl/system/gl_framebuffer.h | 2 +- src/gl/system/gl_wipe.cpp | 2 +- src/gl/textures/gl_hwtexture.cpp | 3 +- src/hwrenderer/textures/hw_ihwtexture.h | 2 - src/hwrenderer/textures/hw_material.cpp | 82 +------------------------ src/hwrenderer/textures/hw_material.h | 26 ++++++-- src/v_video.h | 1 + 12 files changed, 129 insertions(+), 118 deletions(-) diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 8d0a7c43e5..55ba61e4e1 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -345,6 +345,26 @@ sector_t *FGLRenderer::RenderView(player_t* player) return retsec; } +//=========================================================================== +// +// +// +//=========================================================================== + +void FGLRenderer::BindToFrameBuffer(FMaterial *mat) +{ + auto BaseLayer = static_cast(mat->GetLayer(0)); + + if (BaseLayer == nullptr) + { + // must create the hardware texture first + BaseLayer->BindOrCreate(mat->sourcetex, 0, 0, 0, 0); + FHardwareTexture::Unbind(0); + gl_RenderState.ClearLastMaterial(); + } + BaseLayer->BindToFrameBuffer(mat->GetWidth(), mat->GetHeight()); +} + //=========================================================================== // // Camera texture rendering @@ -367,7 +387,7 @@ void FGLRenderer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, doub else { StartOffscreen(); - gltex->BindToFrameBuffer(); + BindToFrameBuffer(gltex); } IntRect bounds; diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index a66d5ced22..99e07f1f16 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -177,10 +177,8 @@ public: bool StartOffscreen(); void EndOffscreen(); - void FillSimplePoly(FTexture *texture, FVector2 *points, int npoints, - double originx, double originy, double scalex, double scaley, - DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip); - + void BindToFrameBuffer(FMaterial *mat); + static float GetZNear() { return 5.f; } static float GetZFar() { return 65536.f; } }; diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 9473a057ab..550b27c4b7 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -36,6 +36,7 @@ #include "gl/renderer/gl_renderer.h" #include "gl/dynlights//gl_lightbuffer.h" #include "gl/renderer/gl_renderbuffers.h" +#include "gl/textures/gl_hwtexture.h" void gl_SetTextureMode(int type); @@ -424,3 +425,65 @@ void FRenderState::SetClipHeight(float height, float direction) glDisable(GL_CLIP_DISTANCE0); // GL_CLIP_PLANE0 is the same value so no need to make a distinction } } + +//=========================================================================== +// +// Binds a texture to the renderer +// +//=========================================================================== + +void FRenderState::SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader, bool alphatexture) +{ + // alpha textures need special treatment in the legacy renderer because without shaders they need a different texture. This will also override all other translations. + if (alphatexture && gl.legacyMode) translation = -STRange_AlphaTexture; + + if (mat->tex->bHasCanvas) + { + mTempTM = TM_OPAQUE; + } + else + { + mTempTM = TM_MODULATE; + } + mEffectState = overrideshader >= 0 ? overrideshader : mat->mShaderIndex; + mShaderTimer = mat->tex->shaderspeed; + SetSpecular(mat->tex->Glossiness, mat->tex->SpecularLevel); + + // avoid rebinding the same texture multiple times. + if (mat == lastMaterial && lastClamp == clampmode && translation == lastTranslation) return; + lastMaterial = mat; + lastClamp = clampmode; + lastTranslation = translation; + + int usebright = false; + int maxbound = 0; + auto tex = mat->tex; + + if (tex->UseType == ETextureType::SWCanvas) clampmode = CLAMP_NOFILTER; + if (tex->bHasCanvas) clampmode = CLAMP_CAMTEX; + else if (tex->bWarped && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE; + + // Textures that are already scaled in the texture lump will not get replaced by hires textures. + int flags = mat->isExpanded() ? CTF_Expand : (gl_texture_usehires && tex->Scale.X == 1 && tex->Scale.Y == 1 && clampmode <= CLAMP_XY) ? CTF_CheckHires : 0; + int numLayers = mat->GetLayers(); + auto base = static_cast(mat->GetLayer(0)); + + if (base->BindOrCreate(tex, 0, clampmode, translation, flags)) + { + for (int i = 1; i(mat->GetLayer(i, &layer)); + systex->BindOrCreate(layer, i, clampmode, 0, mat->isExpanded() ? CTF_Expand : 0); + maxbound = i; + } + } + // unbind everything from the last texture that's still active + for (int i = maxbound + 1; i <= maxBoundMaterial; i++) + { + FHardwareTexture::Unbind(i); + maxBoundMaterial = maxbound; + } +} + + diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 3cd5056112..c8211f1c76 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -131,6 +131,13 @@ class FRenderState bool ApplyShader(); + // Texture binding state + FMaterial *lastMaterial = nullptr; + int lastClamp = 0; + int lastTranslation = 0; + int maxBoundMaterial = -1; + + public: VSMatrix mProjectionMatrix; @@ -146,25 +153,13 @@ public: void Reset(); - void SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader, bool alphatexture) + void ClearLastMaterial() { - // alpha textures need special treatment in the legacy renderer because without shaders they need a different texture. This will also override all other translations. - if (alphatexture && gl.legacyMode) translation = -STRange_AlphaTexture; - - if (mat->tex->bHasCanvas) - { - mTempTM = TM_OPAQUE; - } - else - { - mTempTM = TM_MODULATE; - } - mEffectState = overrideshader >= 0? overrideshader : mat->mShaderIndex; - mShaderTimer = mat->tex->shaderspeed; - SetSpecular(mat->tex->Glossiness, mat->tex->SpecularLevel); - mat->Bind(clampmode, translation); + lastMaterial = nullptr; } + void SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader, bool alphatexture); + void Apply(); void ApplyColorMask(); void ApplyMatrices(); diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index ad8a25a45f..5d47740596 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -73,7 +73,6 @@ OpenGLFrameBuffer::OpenGLFrameBuffer(void *hMonitor, int width, int height, int // Make sure all global variables tracking OpenGL context state are reset.. FHardwareTexture::InitGlobalState(); - FMaterial::InitGlobalState(); gl_RenderState.Reset(); GLRenderer = new FGLRenderer(this); @@ -355,6 +354,11 @@ IHardwareTexture *OpenGLFrameBuffer::CreateHardwareTexture(FTexture *tex) return new FHardwareTexture(tex->bNoCompress); } +void OpenGLFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation) +{ + gl_RenderState.SetMaterial(mat, CLAMP_NONE, translation, false, false); +} + FModelRenderer *OpenGLFrameBuffer::CreateModelRenderer(int mli) { return new FGLModelRenderer(mli); @@ -371,11 +375,6 @@ IShaderProgram *OpenGLFrameBuffer::CreateShaderProgram() } -void OpenGLFrameBuffer::UnbindTexUnit(int no) -{ - FHardwareTexture::Unbind(no); -} - void OpenGLFrameBuffer::FlushTextures() { if (GLRenderer) GLRenderer->FlushTextures(); diff --git a/src/gl/system/gl_framebuffer.h b/src/gl/system/gl_framebuffer.h index 8aff329064..e9026a737d 100644 --- a/src/gl/system/gl_framebuffer.h +++ b/src/gl/system/gl_framebuffer.h @@ -35,8 +35,8 @@ public: sector_t *RenderView(player_t *player) override; void SetTextureFilterMode() override; IHardwareTexture *CreateHardwareTexture(FTexture *tex) override; + void PrecacheMaterial(FMaterial *mat, int translation) override; FModelRenderer *CreateModelRenderer(int mli) override; - void UnbindTexUnit(int no) override; void FlushTextures() override; void TextureFilterChanged() override; void ResetFixedColormap() override; diff --git a/src/gl/system/gl_wipe.cpp b/src/gl/system/gl_wipe.cpp index 84d72bd98d..4fe51ec171 100644 --- a/src/gl/system/gl_wipe.cpp +++ b/src/gl/system/gl_wipe.cpp @@ -242,7 +242,7 @@ void OpenGLFrameBuffer::WipeCleanup() delete wipeendscreen; wipeendscreen = NULL; } - FMaterial::ClearLastTexture(); + gl_RenderState.ClearLastMaterial(); } //========================================================================== diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index ef069114dc..77f9da593f 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -36,6 +36,7 @@ #include "hwrenderer/utility/hw_cvars.h" #include "gl/system/gl_debug.h" #include "gl/renderer/gl_renderer.h" +#include "gl/renderer/gl_renderstate.h" #include "gl/textures/gl_samplers.h" @@ -481,7 +482,7 @@ void FHardwareTexture::UnbindAll() { Unbind(texunit); } - FMaterial::ClearLastTexture(); + gl_RenderState.ClearLastMaterial(); } //=========================================================================== diff --git a/src/hwrenderer/textures/hw_ihwtexture.h b/src/hwrenderer/textures/hw_ihwtexture.h index ca9d5bfad9..b91291806c 100644 --- a/src/hwrenderer/textures/hw_ihwtexture.h +++ b/src/hwrenderer/textures/hw_ihwtexture.h @@ -21,8 +21,6 @@ public: IHardwareTexture() {} virtual ~IHardwareTexture() {} - virtual void BindToFrameBuffer(int w, int h) = 0; - virtual bool BindOrCreate(FTexture *tex, int texunit, int clampmode, int translation, int flags) = 0; virtual void AllocateBuffer(int w, int h, int texelsize) = 0; virtual uint8_t *MapBuffer() = 0; virtual unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const char *name) = 0; diff --git a/src/hwrenderer/textures/hw_material.cpp b/src/hwrenderer/textures/hw_material.cpp index cca6c9b2a8..daeca6d06b 100644 --- a/src/hwrenderer/textures/hw_material.cpp +++ b/src/hwrenderer/textures/hw_material.cpp @@ -407,61 +407,6 @@ outl: return true; } - -//=========================================================================== -// -// Binds a texture to the renderer -// -//=========================================================================== - -static FMaterial *last; -static int lastclamp; -static int lasttrans; - -void FMaterial::InitGlobalState() -{ - last = nullptr; - lastclamp = 0; - lasttrans = 0; -} - -void FMaterial::Bind(int clampmode, int translation) -{ - // avoid rebinding the same texture multiple times. - if (this == last && lastclamp == clampmode && translation == lasttrans) return; - last = this; - lastclamp = clampmode; - lasttrans = translation; - - int usebright = false; - int maxbound = 0; - - if (tex->UseType == ETextureType::SWCanvas) clampmode = CLAMP_NOFILTER; - if (tex->bHasCanvas) clampmode = CLAMP_CAMTEX; - else if (tex->bWarped && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE; - - // Textures that are already scaled in the texture lump will not get replaced by hires textures. - int flags = mExpanded? CTF_Expand : (gl_texture_usehires && tex->Scale.X == 1 && tex->Scale.Y == 1 && clampmode <= CLAMP_XY)? CTF_CheckHires : 0; - - if (mBaseLayer->BindOrCreate(tex, 0, clampmode, translation, flags)) - { - for(unsigned i=0;iBindOrCreate(layer, i+1, clampmode, 0, mExpanded ? CTF_Expand : 0); - maxbound = i+1; - } - } - // unbind everything from the last texture that's still active - for(int i=maxbound+1; i<=mMaxBound;i++) - { - screen->UnbindTexUnit(i); - mMaxBound = maxbound; - } -} - - //=========================================================================== // // @@ -469,7 +414,7 @@ void FMaterial::Bind(int clampmode, int translation) //=========================================================================== void FMaterial::Precache() { - Bind(0, 0); + screen->PrecacheMaterial(this, 0); } //=========================================================================== @@ -482,7 +427,7 @@ void FMaterial::PrecacheList(SpriteHits &translations) if (mBaseLayer != nullptr) mBaseLayer->CleanUnused(translations); SpriteHits::Iterator it(translations); SpriteHits::Pair *pair; - while(it.NextPair(pair)) Bind(0, pair->Key); + while(it.NextPair(pair)) screen->PrecacheMaterial(this, pair->Key); } //=========================================================================== @@ -548,24 +493,6 @@ int FMaterial::GetAreas(FloatRect **pAreas) const } } -//=========================================================================== -// -// -// -//=========================================================================== - -void FMaterial::BindToFrameBuffer() -{ - if (mBaseLayer == nullptr) - { - // must create the hardware texture first - mBaseLayer->BindOrCreate(sourcetex, 0, 0, 0, 0); - screen->UnbindTexUnit(0); - ClearLastTexture(); - } - mBaseLayer->BindToFrameBuffer(mWidth, mHeight); -} - //========================================================================== // // Gets a texture from the texture manager and checks its validity for @@ -637,11 +564,6 @@ void FMaterial::FlushAll() } } -void FMaterial::ClearLastTexture() -{ - last = NULL; -} - void FMaterial::Clean(bool f) { // This somehow needs to deal with the other layers as well, but they probably need some form of reference counting to work properly... diff --git a/src/hwrenderer/textures/hw_material.h b/src/hwrenderer/textures/hw_material.h index 7a3b2f391c..d334ceaa1f 100644 --- a/src/hwrenderer/textures/hw_material.h +++ b/src/hwrenderer/textures/hw_material.h @@ -75,7 +75,6 @@ class FMaterial float mSpriteU[2], mSpriteV[2]; FloatRect mSpriteRect; - IHardwareTexture * ValidateSysTexture(FTexture * tex, bool expand); bool TrimBorders(uint16_t *rect); public: @@ -87,6 +86,7 @@ public: void SetSpriteRect(); void Precache(); void PrecacheList(SpriteHits &translations); + IHardwareTexture * ValidateSysTexture(FTexture * tex, bool expand); void AddTextureLayer(FTexture *tex) { ValidateTexture(tex, false); @@ -96,17 +96,34 @@ public: { return !!sourcetex->bMasked; } + bool isExpanded() const + { + return mExpanded; + } int GetLayers() const { return mTextureLayers.Size() + 1; } - void Bind(int clamp, int translation); + IHardwareTexture *GetLayer(int i, FTexture **pLayer = nullptr) + { + if (i == 0) + { + if (pLayer) *pLayer = tex; + return mBaseLayer; + } + else + { + i--; + FTexture *layer = mTextureLayers[i]; + if (pLayer) *pLayer = layer; + return ValidateSysTexture(layer, isExpanded()); + } + } void Clean(bool f); - void BindToFrameBuffer(); // Patch drawing utilities void GetSpriteRect(FloatRect * r) const @@ -165,9 +182,6 @@ public: static void FlushAll(); static FMaterial *ValidateTexture(FTexture * tex, bool expand); static FMaterial *ValidateTexture(FTextureID no, bool expand, bool trans); - static void ClearLastTexture(); - - static void InitGlobalState(); }; #endif diff --git a/src/v_video.h b/src/v_video.h index e329939abe..ffc9181fa6 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -405,6 +405,7 @@ public: virtual void CleanForRestart() {} virtual void SetTextureFilterMode() {} virtual IHardwareTexture *CreateHardwareTexture(FTexture *tex) { return nullptr; } + virtual void PrecacheMaterial(FMaterial *mat, int translation) {} virtual FModelRenderer *CreateModelRenderer(int mli) { return nullptr; } virtual void UnbindTexUnit(int no) {} virtual void FlushTextures() {}