diff --git a/src/common/textures/hires/hqresize.cpp b/src/common/textures/hires/hqresize.cpp index 9a4fd8b45..67e20acfb 100644 --- a/src/common/textures/hires/hqresize.cpp +++ b/src/common/textures/hires/hqresize.cpp @@ -409,22 +409,10 @@ void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasA { // [BB] Make sure that inWidth and inHeight denote the size of // the returned buffer even if we don't upsample the input buffer. + int inWidth = texbuffer.mWidth; int inHeight = texbuffer.mHeight; - // [BB] Don't resample if width * height of the input texture is bigger than gl_texture_hqresize_maxinputsize squared. - const int maxInputSize = gl_texture_hqresize_maxinputsize; - if (inWidth * inHeight > maxInputSize * maxInputSize) - return; - - // [BB] Don't try to upsample textures based off FCanvasTexture. (This should never get here in the first place!) - if (bHasCanvas) - return; - - // already scaled? - if (Scale.X >= 2 && Scale.Y >= 2) - return; - int type = gl_texture_hqresizemode; int mult = gl_texture_hqresizemult; #ifdef HAVE_MMX @@ -493,3 +481,33 @@ void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasA contentId.scalefactor = mult; texbuffer.mContentId = contentId.id; } + +bool shouldUpscale(FGameTexture *tex, ETextureType UseType) +{ + // [BB] Don't resample if width * height of the input texture is bigger than gl_texture_hqresize_maxinputsize squared. + const int maxInputSize = gl_texture_hqresize_maxinputsize; + if (tex->GetTexelWidth() * tex->GetTexelHeight() > maxInputSize * maxInputSize) + return false; + + // [BB] Don't try to upsample textures based off FCanvasTexture. (This should never get here in the first place!) + if (tex->isHardwareCanvas()) + return false; + + // already scaled? + if (tex->GetDisplayWidth() >= 2* tex->GetTexelWidth() || tex->GetDisplayHeight() >= 2*tex->GetTexelHeight()) + return false; + + switch (UseType) + { + case ETextureType::Sprite: + case ETextureType::SkinSprite: + return !!(gl_texture_hqresize_targets & 2); + + case ETextureType::FontChar: + return !!(gl_texture_hqresize_targets & 4); + + default: + return !!(gl_texture_hqresize_targets & 1); + } + +} \ No newline at end of file diff --git a/src/common/textures/hw_material.cpp b/src/common/textures/hw_material.cpp index 2aa81199f..638866a20 100644 --- a/src/common/textures/hw_material.cpp +++ b/src/common/textures/hw_material.cpp @@ -36,7 +36,7 @@ IHardwareTexture* CreateHardwareTexture(); // //=========================================================================== -FMaterial::FMaterial(FGameTexture * tx, bool expanded) +FMaterial::FMaterial(FGameTexture * tx, int scaleflags) { mShaderIndex = SHADER_Default; sourcetex = tx; @@ -122,10 +122,10 @@ FMaterial::FMaterial(FGameTexture * tx, bool expanded) } } } - mExpanded = expanded; + mScaleFlags = scaleflags; mTextureLayers.ShrinkToFit(); - imgtex->Material[expanded] = this; + imgtex->Material[scaleflags] = this; if (tx->isHardwareCanvas()) tx->SetTranslucent(false); } @@ -151,7 +151,7 @@ IHardwareTexture *FMaterial::GetLayer(int i, int translation, FTexture **pLayer) FTexture *layer = i == 0 ? imgtex : mTextureLayers[i - 1]; if (pLayer) *pLayer = layer; - if (layer) return layer->GetHardwareTexture(translation, mExpanded); + if (layer) return layer->GetHardwareTexture(translation, mScaleFlags); return nullptr; } @@ -162,17 +162,17 @@ IHardwareTexture *FMaterial::GetLayer(int i, int translation, FTexture **pLayer) // //========================================================================== -FMaterial * FMaterial::ValidateTexture(FGameTexture * gtex, bool expand, bool create) +FMaterial * FMaterial::ValidateTexture(FGameTexture * gtex, int scaleflags, bool create) { if (gtex && gtex->isValid()) { auto tex = gtex->GetTexture(); - if (!tex->ShouldExpandSprite()) expand = false; + if (!tex->ShouldExpandSprite()) scaleflags &= ~CTF_Expand; - FMaterial *hwtex = tex->Material[expand]; + FMaterial *hwtex = tex->Material[scaleflags]; if (hwtex == NULL && create) { - hwtex = new FMaterial(gtex, expand); + hwtex = new FMaterial(gtex, scaleflags); } return hwtex; } diff --git a/src/common/textures/hw_material.h b/src/common/textures/hw_material.h index e1e27e3db..bc9af78f0 100644 --- a/src/common/textures/hw_material.h +++ b/src/common/textures/hw_material.h @@ -20,16 +20,17 @@ class FMaterial TArray mTextureLayers; int mShaderIndex; int mLayerFlags = 0; - bool mExpanded; + int mScaleFlags; public: FGameTexture *sourcetex; // the owning texture. FTexture* imgtex; // the first layer's texture image - should be moved into the array - FMaterial(FGameTexture *tex, bool forceexpand); + FMaterial(FGameTexture *tex, int scaleflags); ~FMaterial(); int GetLayerFlags() const { return mLayerFlags; } int GetShaderIndex() const { return mShaderIndex; } + int GetScaleFlags() const { return mScaleFlags; } FGameTexture* Source() const { @@ -45,10 +46,6 @@ public: //ValidateTexture(tex, false); mTextureLayers.Push(tex); } - bool isExpanded() const - { - return mExpanded; - } int GetLayers() const { @@ -58,7 +55,7 @@ public: IHardwareTexture *GetLayer(int i, int translation, FTexture **pLayer = nullptr) const; - static FMaterial *ValidateTexture(FGameTexture * tex, bool expand, bool create = true); + static FMaterial *ValidateTexture(FGameTexture * tex, int scaleflags, bool create = true); const TArray &GetLayerArray() const { return mTextureLayers; diff --git a/src/common/textures/hw_texcontainer.h b/src/common/textures/hw_texcontainer.h index 247279fb0..f7020b5b7 100644 --- a/src/common/textures/hw_texcontainer.h +++ b/src/common/textures/hw_texcontainer.h @@ -7,6 +7,15 @@ struct FTextureBuffer; class IHardwareTexture; +enum ECreateTexBufferFlags +{ + CTF_Expand = 1, // create buffer with a one-pixel wide border + CTF_Upscale = 2, // Upscale the texture + CTF_CreateMask = 3, // Flags that are relevant for hardware texture creation. + CTF_ProcessData = 4, // run postprocessing on the generated buffer. This is only needed when using the data for a hardware texture. + CTF_CheckOnly = 8, // Only runs the code to get a content ID but does not create a texture. Can be used to access a caching system for the hardware textures. +}; + class FHardwareTextureContainer { public: @@ -40,20 +49,20 @@ private: private: - TranslatedTexture hwDefTex[2]; + TranslatedTexture hwDefTex[4]; TArray hwTex_Translated; - TranslatedTexture * GetTexID(int translation, bool expanded) + TranslatedTexture * GetTexID(int translation, int scaleflags) { auto remap = GPalette.TranslationToTable(translation); translation = remap == nullptr ? 0 : remap->Index; - if (translation == 0) + if (translation == 0 && !(scaleflags & CTF_Upscale)) { - return &hwDefTex[expanded]; + return &hwDefTex[scaleflags]; } - if (expanded) translation = -translation; + translation |= (scaleflags << 24); // normally there aren't more than very few different // translations here so this isn't performance critical. unsigned index = hwTex_Translated.FindEx([=](auto &element) @@ -73,31 +82,28 @@ private: public: - void Clean(bool cleannormal, bool cleanexpanded) + void Clean(bool reallyclean) { - if (cleannormal) hwDefTex[0].Delete(); - if (cleanexpanded) hwDefTex[1].Delete(); hwDefTex[0].DeleteDescriptors(); hwDefTex[1].DeleteDescriptors(); - for (int i = hwTex_Translated.Size() - 1; i >= 0; i--) - { - if (cleannormal && hwTex_Translated[i].translation > 0) hwTex_Translated.Delete(i); - else if (cleanexpanded && hwTex_Translated[i].translation < 0) hwTex_Translated.Delete(i); + for (unsigned int j = 0; j < hwTex_Translated.Size(); j++) + hwTex_Translated[j].DeleteDescriptors(); - for (unsigned int j = 0; j < hwTex_Translated.Size(); j++) - hwTex_Translated[j].DeleteDescriptors(); - } + if (!reallyclean) return; + hwDefTex[0].Delete(); + hwDefTex[1].Delete(); + hwTex_Translated.Clear(); } - IHardwareTexture * GetHardwareTexture(int translation, bool expanded) + IHardwareTexture * GetHardwareTexture(int translation, int scaleflags) { - auto tt = GetTexID(translation, expanded); + auto tt = GetTexID(translation, scaleflags); return tt->hwTexture; } - void AddHardwareTexture(int translation, bool expanded, IHardwareTexture *tex) + void AddHardwareTexture(int translation, int scaleflags, IHardwareTexture *tex) { - auto tt = GetTexID(translation, expanded); + auto tt = GetTexID(translation, scaleflags); tt->Delete(); tt->hwTexture =tex; } @@ -109,16 +115,15 @@ public: // //=========================================================================== - void CleanUnused(SpriteHits &usedtranslations, bool expanded) + void CleanUnused(SpriteHits &usedtranslations, int scaleflags) { if (usedtranslations.CheckKey(0) == nullptr) { - hwDefTex[expanded].Delete(); + hwDefTex[scaleflags].Delete(); } - int fac = expanded ? -1 : 1; for (int i = hwTex_Translated.Size()-1; i>= 0; i--) { - if (usedtranslations.CheckKey(hwTex_Translated[i].translation * fac) == nullptr) + if (usedtranslations.CheckKey(hwTex_Translated[i].translation & 0xffffff) == nullptr) { hwTex_Translated.Delete(i); } diff --git a/src/common/textures/texture.cpp b/src/common/textures/texture.cpp index d51d06043..26b0f1404 100644 --- a/src/common/textures/texture.cpp +++ b/src/common/textures/texture.cpp @@ -688,27 +688,10 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags) result.mWidth = W; result.mHeight = H; - bool upscale = true; - switch (UseType) - { - case ETextureType::Sprite: - case ETextureType::SkinSprite: - if (!(gl_texture_hqresize_targets & 2)) upscale = false; - break; - - case ETextureType::FontChar: - if (!(gl_texture_hqresize_targets & 4)) upscale = false; - break; - - default: - if (!(gl_texture_hqresize_targets & 1)) upscale = false; - break; - } - // Only do postprocessing for image-backed textures. (i.e. not for the burn texture which can also pass through here.) if (GetImage() && flags & CTF_ProcessData) { - if (upscale) CreateUpsampledTextureBuffer(result, !!isTransparent, checkonly); + if (flags & CTF_Upscale) CreateUpsampledTextureBuffer(result, !!isTransparent, checkonly); if (!checkonly) ProcessData(result.mBuffer, result.mWidth, result.mHeight, false); } @@ -738,7 +721,7 @@ bool FTexture::DetermineTranslucency() void FTexture::CleanHardwareTextures(bool reallyclean) { - SystemTextures.Clean(reallyclean, reallyclean); + SystemTextures.Clean(reallyclean); } //=========================================================================== @@ -964,15 +947,15 @@ void FTexture::SetSpriteRect() // //=========================================================================== -IHardwareTexture* FTexture::GetHardwareTexture(int translation, bool expanded) +IHardwareTexture* FTexture::GetHardwareTexture(int translation, int scaleflags) { if (UseType != ETextureType::Null) { - IHardwareTexture* hwtex = SystemTextures.GetHardwareTexture(translation, expanded); + IHardwareTexture* hwtex = SystemTextures.GetHardwareTexture(translation, scaleflags); if (hwtex == nullptr) { hwtex = CreateHardwareTexture(); - SystemTextures.AddHardwareTexture(translation, expanded, hwtex); + SystemTextures.AddHardwareTexture(translation, scaleflags, hwtex); } return hwtex; } diff --git a/src/common/textures/textures.h b/src/common/textures/textures.h index a826c06eb..65a5a7dce 100644 --- a/src/common/textures/textures.h +++ b/src/common/textures/textures.h @@ -120,15 +120,6 @@ struct FloatRect } }; -enum ECreateTexBufferFlags -{ - CTF_Expand = 2, // create buffer with a one-pixel wide border - CTF_ProcessData = 4, // run postprocessing on the generated buffer. This is only needed when using the data for a hardware texture. - CTF_CheckOnly = 8, // Only runs the code to get a content ID but does not create a texture. Can be used to access a caching system for the hardware textures. -}; - - - class FBitmap; struct FRemapTable; struct FCopyInfo; @@ -258,7 +249,7 @@ public: SpritePositioningInfo *spi = nullptr; - IHardwareTexture* GetHardwareTexture(int translation, bool expanded); + IHardwareTexture* GetHardwareTexture(int translation, int scaleflags); static FTexture *CreateTexture(const char *name, int lumpnum, ETextureType usetype); virtual ~FTexture (); virtual FImageSource *GetImage() const { return nullptr; } @@ -369,7 +360,7 @@ protected: int SourceLump; FTextureID id; - FMaterial *Material[2] = { nullptr, nullptr }; + FMaterial *Material[4] = { }; public: FHardwareTextureContainer SystemTextures; protected: @@ -534,7 +525,7 @@ public: FWrapperTexture(int w, int h, int bits = 1); IHardwareTexture *GetSystemTexture() { - return SystemTextures.GetHardwareTexture(0, false); + return SystemTextures.GetHardwareTexture(0, 0); } int GetColorFormat() const @@ -764,6 +755,7 @@ inline FGameTexture* MakeGameTexture(FTexture* tex) return new FGameTexture(tex); } +bool shouldUpscale(FGameTexture* tex, ETextureType UseType); #endif diff --git a/src/rendering/gl/renderer/gl_renderer.cpp b/src/rendering/gl/renderer/gl_renderer.cpp index ee5fbb09a..23380de8b 100644 --- a/src/rendering/gl/renderer/gl_renderer.cpp +++ b/src/rendering/gl/renderer/gl_renderer.cpp @@ -297,7 +297,7 @@ sector_t *FGLRenderer::RenderView(player_t* player) void FGLRenderer::BindToFrameBuffer(FTexture *tex) { - auto BaseLayer = static_cast(tex->GetHardwareTexture(0, false)); + auto BaseLayer = static_cast(tex->GetHardwareTexture(0, 0)); if (BaseLayer == nullptr) { diff --git a/src/rendering/gl/renderer/gl_renderstate.cpp b/src/rendering/gl/renderer/gl_renderstate.cpp index 73386ee10..1c60be381 100644 --- a/src/rendering/gl/renderer/gl_renderstate.cpp +++ b/src/rendering/gl/renderer/gl_renderstate.cpp @@ -323,7 +323,7 @@ void FGLRenderState::ApplyMaterial(FMaterial *mat, int clampmode, int translatio int usebright = false; int maxbound = 0; - int flags = mat->isExpanded() ? CTF_Expand : 0; + int flags = mat->GetScaleFlags(); int numLayers = mat->GetLayers(); auto base = static_cast(mat->GetLayer(0, translation)); @@ -333,7 +333,8 @@ void FGLRenderState::ApplyMaterial(FMaterial *mat, int clampmode, int translatio { FTexture *layer; auto systex = static_cast(mat->GetLayer(i, 0, &layer)); - systex->BindOrCreate(layer, i, clampmode, 0, mat->isExpanded() ? CTF_Expand : 0); + // fixme: Upscale flags must be disabled for certain layers. + systex->BindOrCreate(layer, i, clampmode, 0, flags); maxbound = i; } } diff --git a/src/rendering/gl/system/gl_framebuffer.cpp b/src/rendering/gl/system/gl_framebuffer.cpp index c68ca64ca..7ea0f3df6 100644 --- a/src/rendering/gl/system/gl_framebuffer.cpp +++ b/src/rendering/gl/system/gl_framebuffer.cpp @@ -310,7 +310,7 @@ void OpenGLFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation) { if (mat->Source()->GetUseType() == ETextureType::SWCanvas) return; - int flags = mat->isExpanded() ? CTF_Expand : 0; + int flags = mat->GetScaleFlags(); int numLayers = mat->GetLayers(); FTexture* layer; auto base = static_cast(mat->GetLayer(0, translation, &layer)); @@ -320,7 +320,7 @@ void OpenGLFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation) for (int i = 1; i < numLayers; i++) { auto systex = static_cast(mat->GetLayer(i, 0, &layer)); - systex->BindOrCreate(layer, i, CLAMP_NONE, 0, mat->isExpanded() ? CTF_Expand : 0); + systex->BindOrCreate(layer, i, CLAMP_NONE, 0, flags); } } // unbind everything. diff --git a/src/rendering/hwrenderer/models/hw_models.cpp b/src/rendering/hwrenderer/models/hw_models.cpp index 6c76126e5..2d180126e 100644 --- a/src/rendering/hwrenderer/models/hw_models.cpp +++ b/src/rendering/hwrenderer/models/hw_models.cpp @@ -114,7 +114,7 @@ void FHWModelRenderer::SetInterpolation(double inter) void FHWModelRenderer::SetMaterial(FGameTexture *skin, bool clampNoFilter, int translation) { - state.SetMaterial(skin, false, clampNoFilter ? CLAMP_NOFILTER : CLAMP_NONE, translation, -1); + state.SetMaterial(skin, 0, clampNoFilter ? CLAMP_NOFILTER : CLAMP_NONE, translation, -1); state.SetLightIndex(modellightindex); } diff --git a/src/rendering/hwrenderer/scene/hw_decal.cpp b/src/rendering/hwrenderer/scene/hw_decal.cpp index e92a6c80e..3416ddfff 100644 --- a/src/rendering/hwrenderer/scene/hw_decal.cpp +++ b/src/rendering/hwrenderer/scene/hw_decal.cpp @@ -66,7 +66,8 @@ void HWDecal::DrawDecal(HWDrawInfo *di, FRenderState &state) state.SetTextureMode(decal->RenderStyle); state.SetRenderStyle(decal->RenderStyle); - state.SetMaterial(texture, false, CLAMP_XY, decal->Translation, -1); + int flags = shouldUpscale(texture, ETextureType::Sprite) ? CTF_Upscale : 0; + state.SetMaterial(texture, flags, CLAMP_XY, decal->Translation, -1); // If srcalpha is one it looks better with a higher alpha threshold diff --git a/src/rendering/hwrenderer/scene/hw_flats.cpp b/src/rendering/hwrenderer/scene/hw_flats.cpp index a4e8d1eee..245e80a89 100644 --- a/src/rendering/hwrenderer/scene/hw_flats.cpp +++ b/src/rendering/hwrenderer/scene/hw_flats.cpp @@ -204,7 +204,8 @@ void HWFlat::DrawSubsectors(HWDrawInfo *di, FRenderState &state) void HWFlat::DrawOtherPlanes(HWDrawInfo *di, FRenderState &state) { - state.SetMaterial(texture, false, CLAMP_NONE, 0, -1); + int flags = shouldUpscale(texture, ETextureType::Flat) ? CTF_Upscale : 0; + state.SetMaterial(texture, flags, CLAMP_NONE, 0, -1); // Draw the subsectors assigned to it due to missing textures auto pNode = (renderflags&SSRF_RENDERFLOOR) ? @@ -236,7 +237,8 @@ void HWFlat::DrawFloodPlanes(HWDrawInfo *di, FRenderState &state) // This requires a stencil because the projected plane interferes with // the depth buffer - state.SetMaterial(texture, false, CLAMP_NONE, 0, -1); + int flags = shouldUpscale(texture, ETextureType::Flat) ? CTF_Upscale : 0; + state.SetMaterial(texture, flags, CLAMP_NONE, 0, -1); // Draw the subsectors assigned to it due to missing textures auto pNode = (renderflags&SSRF_RENDERFLOOR) ? @@ -322,16 +324,17 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent) } else if (!translucent) { + int flags = shouldUpscale(texture, ETextureType::Flat) ? CTF_Upscale : 0; if (sector->special != GLSector_Skybox) { - state.SetMaterial(texture, false, CLAMP_NONE, 0, -1); + state.SetMaterial(texture, flags, CLAMP_NONE, 0, -1); state.SetPlaneTextureRotation(&plane, texture); DrawSubsectors(di, state); state.EnableTextureMatrix(false); } else if (!hacktype) { - state.SetMaterial(texture, false, CLAMP_XY, 0, -1); + state.SetMaterial(texture, flags, CLAMP_XY, 0, -1); state.SetLightIndex(dynlightindex); state.Draw(DT_TriangleStrip,iboindex, 4); flatvertices += 4; @@ -352,7 +355,8 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent) { if (!texture->GetTranslucency()) state.AlphaFunc(Alpha_GEqual, gl_mask_threshold); else state.AlphaFunc(Alpha_GEqual, 0.f); - state.SetMaterial(texture, false, CLAMP_NONE, 0, -1); + int flags = shouldUpscale(texture, ETextureType::Flat) ? CTF_Upscale : 0; + state.SetMaterial(texture, flags, CLAMP_NONE, 0, -1); state.SetPlaneTextureRotation(&plane, texture); DrawSubsectors(di, state); state.EnableTextureMatrix(false); diff --git a/src/rendering/hwrenderer/scene/hw_portal.cpp b/src/rendering/hwrenderer/scene/hw_portal.cpp index f3915096f..ad491217f 100644 --- a/src/rendering/hwrenderer/scene/hw_portal.cpp +++ b/src/rendering/hwrenderer/scene/hw_portal.cpp @@ -975,7 +975,8 @@ void HWHorizonPortal::DrawContents(HWDrawInfo *di, FRenderState &state) } - state.SetMaterial(texture, false, CLAMP_NONE, 0, -1); + int flags = shouldUpscale(texture, ETextureType::Flat) ? CTF_Upscale : 0; + state.SetMaterial(texture, flags, CLAMP_NONE, 0, -1); state.SetObjectColor(origin->specialcolor); state.SetPlaneTextureRotation(sp, texture); diff --git a/src/rendering/hwrenderer/scene/hw_renderstate.h b/src/rendering/hwrenderer/scene/hw_renderstate.h index e0800172c..47e08c03c 100644 --- a/src/rendering/hwrenderer/scene/hw_renderstate.h +++ b/src/rendering/hwrenderer/scene/hw_renderstate.h @@ -569,10 +569,10 @@ public: mTextureModeFlags = mat->GetLayerFlags(); } - void SetMaterial(FGameTexture* tex, bool expandmode, int clampmode, int translation, int overrideshader) + void SetMaterial(FGameTexture* tex, int scaleflags, int clampmode, int translation, int overrideshader) { - expandmode &= tex->expandSprites(); - SetMaterial(FMaterial::ValidateTexture(tex, expandmode), clampmode, translation, overrideshader); + if (!tex->expandSprites()) scaleflags &= ~CTF_Expand; + SetMaterial(FMaterial::ValidateTexture(tex, scaleflags), clampmode, translation, overrideshader); } void SetClipSplit(float bottom, float top) diff --git a/src/rendering/hwrenderer/scene/hw_skyportal.cpp b/src/rendering/hwrenderer/scene/hw_skyportal.cpp index 5b13f7371..ef2af5565 100644 --- a/src/rendering/hwrenderer/scene/hw_skyportal.cpp +++ b/src/rendering/hwrenderer/scene/hw_skyportal.cpp @@ -52,9 +52,10 @@ void HWSkyPortal::RenderRow(HWDrawInfo *di, FRenderState &state, EDrawType prim, void HWSkyPortal::RenderDome(HWDrawInfo *di, FRenderState &state, FGameTexture * tex, float x_offset, float y_offset, bool mirror, int mode) { + int flags = shouldUpscale(tex, ETextureType::Wall) ? CTF_Upscale : 0; if (tex) { - state.SetMaterial(tex, false, CLAMP_NONE, 0, -1); + state.SetMaterial(tex, flags, CLAMP_NONE, 0, -1); state.EnableModelMatrix(true); state.EnableTextureMatrix(true); @@ -106,39 +107,41 @@ void HWSkyPortal::RenderBox(HWDrawInfo *di, FRenderState &state, FTextureID texn else state.mModelMatrix.rotate(-180.0f+x_offset, di->Level->info->skyrotatevector2.X, di->Level->info->skyrotatevector2.Z, di->Level->info->skyrotatevector2.Y); - if (tex->GetSkyFace(5)) + // Only test the first face - the result here must be consistent - either all get scaled or none. + int flags = shouldUpscale(tex->GetSkyFace(0), ETextureType::Flat) ? CTF_Upscale : 0; + if (tex->GetSkyFace(5)) { faces=4; // north - state.SetMaterial(tex->GetSkyFace(0), false, CLAMP_XY, 0, -1); + state.SetMaterial(tex->GetSkyFace(0), flags, CLAMP_XY, 0, -1); state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(0), 4); // east - state.SetMaterial(tex->GetSkyFace(1), false, CLAMP_XY, 0, -1); + state.SetMaterial(tex->GetSkyFace(1), flags, CLAMP_XY, 0, -1); state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(1), 4); // south - state.SetMaterial(tex->GetSkyFace(2), false, CLAMP_XY, 0, -1); + state.SetMaterial(tex->GetSkyFace(2), flags, CLAMP_XY, 0, -1); state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(2), 4); // west - state.SetMaterial(tex->GetSkyFace(3), false, CLAMP_XY, 0, -1); + state.SetMaterial(tex->GetSkyFace(3), flags, CLAMP_XY, 0, -1); state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(3), 4); } else { faces=1; - state.SetMaterial(tex->GetSkyFace(0), false, CLAMP_XY, 0, -1); + state.SetMaterial(tex->GetSkyFace(0), flags, CLAMP_XY, 0, -1); state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(-1), 10); } // top - state.SetMaterial(tex->GetSkyFace(faces), false, CLAMP_XY, 0, -1); + state.SetMaterial(tex->GetSkyFace(faces), flags, CLAMP_XY, 0, -1); state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(tex->GetSkyFlip() ? 6 : 5), 4); // bottom - state.SetMaterial(tex->GetSkyFace(faces+1), false, CLAMP_XY, 0, -1); + state.SetMaterial(tex->GetSkyFace(faces+1), flags, CLAMP_XY, 0, -1); state.Draw(DT_TriangleStrip, vertexBuffer->FaceStart(4), 4); state.EnableModelMatrix(false); diff --git a/src/rendering/hwrenderer/scene/hw_sprites.cpp b/src/rendering/hwrenderer/scene/hw_sprites.cpp index 392d1caad..dbe44637a 100644 --- a/src/rendering/hwrenderer/scene/hw_sprites.cpp +++ b/src/rendering/hwrenderer/scene/hw_sprites.cpp @@ -198,7 +198,9 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent) } uint32_t spritetype = (actor->renderflags & RF_SPRITETYPEMASK); - if (texture) state.SetMaterial(texture, spritetype == RF_FACESPRITE, CLAMP_XY, translation, OverrideShader); + int flags = shouldUpscale(texture, ETextureType::Flat) ? CTF_Upscale : 0; + if (spritetype == RF_FACESPRITE) flags |= CTF_Expand; + if (texture) state.SetMaterial(texture, flags, CLAMP_XY, translation, OverrideShader); else if (!modelframe) state.EnableTexture(false); //SetColor(lightlevel, rel, Colormap, trans); diff --git a/src/rendering/hwrenderer/scene/hw_walls.cpp b/src/rendering/hwrenderer/scene/hw_walls.cpp index 73c19f804..2d1235ae1 100644 --- a/src/rendering/hwrenderer/scene/hw_walls.cpp +++ b/src/rendering/hwrenderer/scene/hw_walls.cpp @@ -156,7 +156,8 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags) state.SetGlowParams(topglowcolor, bottomglowcolor); state.SetGlowPlanes(frontsector->ceilingplane, frontsector->floorplane); } - state.SetMaterial(texture, false, flags & 3, 0, -1); + int uflags = shouldUpscale(texture, ETextureType::Flat) ? CTF_Upscale : 0; + state.SetMaterial(texture, uflags, flags & 3, 0, -1); if (type == RENDERWALL_M2SNF) { diff --git a/src/rendering/hwrenderer/scene/hw_weapon.cpp b/src/rendering/hwrenderer/scene/hw_weapon.cpp index f07c667f3..6d6aaee84 100644 --- a/src/rendering/hwrenderer/scene/hw_weapon.cpp +++ b/src/rendering/hwrenderer/scene/hw_weapon.cpp @@ -96,7 +96,8 @@ void HWDrawInfo::DrawPSprite(HUDSprite *huds, FRenderState &state) { float thresh = (huds->texture->GetTranslucency() || huds->OverrideShader != -1) ? 0.f : gl_mask_sprite_threshold; state.AlphaFunc(Alpha_GEqual, thresh); - state.SetMaterial(huds->texture, true, CLAMP_XY_NOMIP, (huds->weapon->Flags & PSPF_PLAYERTRANSLATED) ? huds->owner->Translation : 0, huds->OverrideShader); + int flags = shouldUpscale(huds->texture, ETextureType::Flat) ? CTF_Upscale|CTF_Expand : CTF_Expand; + state.SetMaterial(huds->texture, flags, CLAMP_XY_NOMIP, (huds->weapon->Flags & PSPF_PLAYERTRANSLATED) ? huds->owner->Translation : 0, huds->OverrideShader); state.Draw(DT_TriangleStrip, huds->mx, 4); } diff --git a/src/rendering/hwrenderer/textures/hw_precache.cpp b/src/rendering/hwrenderer/textures/hw_precache.cpp index 5c599c491..7ce5052ca 100644 --- a/src/rendering/hwrenderer/textures/hw_precache.cpp +++ b/src/rendering/hwrenderer/textures/hw_precache.cpp @@ -62,7 +62,7 @@ static void PrecacheTexture(FGameTexture *tex, int cache) //=========================================================================== static void PrecacheList(FMaterial *gltex, SpriteHits& translations) { - gltex->BaseLayer()->SystemTextures.CleanUnused(translations, gltex->isExpanded()); + gltex->BaseLayer()->SystemTextures.CleanUnused(translations, gltex->GetScaleFlags()); SpriteHits::Iterator it(translations); SpriteHits::Pair* pair; while (it.NextPair(pair)) screen->PrecacheMaterial(gltex, pair->Key); @@ -252,7 +252,8 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap &actorhitl { if (texhitlist[i] & (FTextureManager::HIT_Wall | FTextureManager::HIT_Flat | FTextureManager::HIT_Sky)) { - if (tex->GetImage() && tex->SystemTextures.GetHardwareTexture(0, false) == nullptr) + int flags = shouldUpscale(gtex, ETextureType::Wall) ? CTF_Upscale : 0; + if (tex->GetImage() && tex->SystemTextures.GetHardwareTexture(0, flags) == nullptr) { FImageSource::RegisterForPrecache(tex->GetImage(), V_IsTrueColor()); } diff --git a/src/rendering/hwrenderer/utility/hw_draw2d.cpp b/src/rendering/hwrenderer/utility/hw_draw2d.cpp index 9ea18891e..efff2852e 100644 --- a/src/rendering/hwrenderer/utility/hw_draw2d.cpp +++ b/src/rendering/hwrenderer/utility/hw_draw2d.cpp @@ -164,7 +164,7 @@ void Draw2D(F2DDrawer *drawer, FRenderState &state) if (cmd.mTexture != nullptr && cmd.mTexture->isValid()) { - state.SetMaterial(cmd.mTexture, false, cmd.mFlags & F2DDrawer::DTF_Wrap ? CLAMP_NONE : CLAMP_XY_NOMIP, cmd.mTranslationId, -1); + state.SetMaterial(cmd.mTexture, 0, cmd.mFlags & F2DDrawer::DTF_Wrap ? CLAMP_NONE : CLAMP_XY_NOMIP, cmd.mTranslationId, -1); state.EnableTexture(true); // Canvas textures are stored upside down diff --git a/src/rendering/polyrenderer/backend/poly_framebuffer.cpp b/src/rendering/polyrenderer/backend/poly_framebuffer.cpp index e8b1c5c87..63eea8f2c 100644 --- a/src/rendering/polyrenderer/backend/poly_framebuffer.cpp +++ b/src/rendering/polyrenderer/backend/poly_framebuffer.cpp @@ -377,7 +377,7 @@ sector_t *PolyFrameBuffer::RenderViewpoint(FRenderViewpoint &mainvp, AActor * ca void PolyFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV) { // This doesn't need to clear the fake flat cache. It can be shared between camera textures and the main view of a scene. - auto BaseLayer = static_cast(tex->GetHardwareTexture(0, false)); + auto BaseLayer = static_cast(tex->GetHardwareTexture(0, 0)); float ratio = (float)tex->GetDisplayWidthDouble() / (float)tex->GetDisplayHeightDouble(); DCanvas *image = BaseLayer->GetImage(tex, 0, 0); @@ -535,7 +535,7 @@ void PolyFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation) { if (mat->Source()->GetUseType() == ETextureType::SWCanvas) return; - int flags = mat->isExpanded() ? CTF_Expand : 0; + int flags = mat->GetScaleFlags(); FTexture* layer; auto systex = static_cast(mat->GetLayer(0, translation, &layer)); systex->GetImage(layer, translation, flags); @@ -544,7 +544,7 @@ void PolyFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation) for (int i = 1; i < numLayers; i++) { auto systex = static_cast(mat->GetLayer(i, 0, &layer)); - systex->GetImage(layer, 0, mat->isExpanded() ? CTF_Expand : 0); + systex->GetImage(layer, 0, flags); // fixme: Upscale flags must be disabled for certain layers. } } diff --git a/src/rendering/polyrenderer/backend/poly_hwtexture.cpp b/src/rendering/polyrenderer/backend/poly_hwtexture.cpp index 51a788660..55a47fca9 100644 --- a/src/rendering/polyrenderer/backend/poly_hwtexture.cpp +++ b/src/rendering/polyrenderer/backend/poly_hwtexture.cpp @@ -68,7 +68,7 @@ DCanvas *PolyHardwareTexture::GetImage(FTexture *baselayer, const FMaterialState if (!mCanvas) { - int flags = state.mMaterial->isExpanded() ? CTF_Expand : 0; + int flags = state.mMaterial->GetScaleFlags(); return GetImage(baselayer, state.mTranslation, flags); } diff --git a/src/rendering/polyrenderer/backend/poly_renderstate.cpp b/src/rendering/polyrenderer/backend/poly_renderstate.cpp index 41e2aeb4e..9119ce96d 100644 --- a/src/rendering/polyrenderer/backend/poly_renderstate.cpp +++ b/src/rendering/polyrenderer/backend/poly_renderstate.cpp @@ -327,7 +327,7 @@ void PolyRenderState::ApplyMaterial() FTexture* layer; auto systex = static_cast(mMaterial.mMaterial->GetLayer(i, 0, &layer)); - texcanvas = systex->GetImage(layer, 0, mMaterial.mMaterial->isExpanded() ? CTF_Expand : 0); + texcanvas = systex->GetImage(layer, 0, mMaterial.mMaterial->GetScaleFlags()); mDrawCommands->SetTexture(i, texcanvas->GetPixels(), texcanvas->GetWidth(), texcanvas->GetHeight(), texcanvas->IsBgra()); } } diff --git a/src/rendering/swrenderer/r_swscene.cpp b/src/rendering/swrenderer/r_swscene.cpp index ac5c382a9..2886d4575 100644 --- a/src/rendering/swrenderer/r_swscene.cpp +++ b/src/rendering/swrenderer/r_swscene.cpp @@ -94,7 +94,7 @@ sector_t *SWSceneDrawer::RenderView(player_t *player) FBTextureIndex = (FBTextureIndex + 1) % 2; auto &fbtex = FBTexture[FBTextureIndex]; - auto GetSystemTexture = [&]() { return fbtex->GetTexture()->SystemTextures.GetHardwareTexture(0, false); }; + auto GetSystemTexture = [&]() { return fbtex->GetTexture()->SystemTextures.GetHardwareTexture(0, 0); }; if (fbtex == nullptr || GetSystemTexture() == nullptr || fbtex->GetTexelWidth() != screen->GetWidth() || diff --git a/src/rendering/swrenderer/textures/r_swtexture.cpp b/src/rendering/swrenderer/textures/r_swtexture.cpp index 6b9fcd7f3..ace25007e 100644 --- a/src/rendering/swrenderer/textures/r_swtexture.cpp +++ b/src/rendering/swrenderer/textures/r_swtexture.cpp @@ -54,8 +54,10 @@ FSoftwareTexture::FSoftwareTexture(FGameTexture *tex) mSource = tex->GetTexture(); mBufferFlags = CTF_ProcessData; + auto f = mBufferFlags; + if (shouldUpscale(tex, tex->GetUseType())) f |= CTF_Upscale; // calculate the real size after running the scaler. - auto info = mSource->CreateTexBuffer(0, CTF_CheckOnly| mBufferFlags); + auto info = mSource->CreateTexBuffer(0, CTF_CheckOnly| f); mPhysicalWidth = info.mWidth; mPhysicalHeight = info.mHeight; mPhysicalScale = tex->GetTexelWidth() > 0 ? mPhysicalWidth / tex->GetTexelWidth() : mPhysicalWidth; @@ -113,6 +115,8 @@ const uint8_t *FSoftwareTexture::GetPixels(int style) } else { + auto f = mBufferFlags; + if (shouldUpscale(mTexture, mTexture->GetUseType())) f |= CTF_Upscale; auto tempbuffer = mSource->CreateTexBuffer(0, mBufferFlags); Pixels.Resize(GetPhysicalWidth()*GetPhysicalHeight()); PalEntry *pe = (PalEntry*)tempbuffer.mBuffer; diff --git a/src/rendering/vulkan/system/vk_framebuffer.cpp b/src/rendering/vulkan/system/vk_framebuffer.cpp index dd4ef1d79..460a180db 100644 --- a/src/rendering/vulkan/system/vk_framebuffer.cpp +++ b/src/rendering/vulkan/system/vk_framebuffer.cpp @@ -515,7 +515,7 @@ sector_t *VulkanFrameBuffer::RenderViewpoint(FRenderViewpoint &mainvp, AActor * void VulkanFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV) { - auto BaseLayer = static_cast(tex->GetHardwareTexture(0, false)); + auto BaseLayer = static_cast(tex->GetHardwareTexture(0, 0)); float ratio = (float)tex->GetDisplayWidthDouble() / (float)tex->GetDisplayHeightDouble(); VkTextureImage *image = BaseLayer->GetImage(tex, 0, 0); @@ -648,17 +648,17 @@ void VulkanFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation) if (mat->Source()->GetUseType() == ETextureType::SWCanvas) return; // Textures that are already scaled in the texture lump will not get replaced by hires textures. - int flags = mat->isExpanded() ? CTF_Expand : 0; + int flags = mat->GetScaleFlags(); FTexture* layer; auto systex = static_cast(mat->GetLayer(0, translation, &layer)); - systex->GetImage(layer, translation, mat->isExpanded() ? CTF_Expand : 0); + systex->GetImage(layer, translation, flags); int numLayers = mat->GetLayers(); for (int i = 1; i < numLayers; i++) { auto systex = static_cast(mat->GetLayer(i, 0, &layer)); - systex->GetImage(layer, 0, mat->isExpanded() ? CTF_Expand : 0); + systex->GetImage(layer, 0, flags); // fixme: Upscale flags must be disabled for certain layers. } } diff --git a/src/rendering/vulkan/textures/vk_hwtexture.cpp b/src/rendering/vulkan/textures/vk_hwtexture.cpp index 1868331fa..e3c81054c 100644 --- a/src/rendering/vulkan/textures/vk_hwtexture.cpp +++ b/src/rendering/vulkan/textures/vk_hwtexture.cpp @@ -119,7 +119,7 @@ VulkanDescriptorSet *VkHardwareTexture::GetDescriptorSet(const FMaterialState &s clampmode = base->GetClampMode(clampmode); // Textures that are already scaled in the texture lump will not get replaced by hires textures. - int flags = state.mMaterial->isExpanded() ? CTF_Expand : 0; + int flags = mat->GetScaleFlags(); for (auto &set : mDescriptorSets) { @@ -141,7 +141,8 @@ VulkanDescriptorSet *VkHardwareTexture::GetDescriptorSet(const FMaterialState &s { FTexture *layer; auto systex = static_cast(mat->GetLayer(i, 0, &layer)); - update.addCombinedImageSampler(descriptor.get(), i, systex->GetImage(layer, 0, mat->isExpanded() ? CTF_Expand : 0)->View.get(), sampler, systex->mImage.Layout); + // fixme: Upscale flags must be disabled for certain layers. + update.addCombinedImageSampler(descriptor.get(), i, systex->GetImage(layer, 0, flags)->View.get(), sampler, systex->mImage.Layout); } auto dummyImage = fb->GetRenderPassManager()->GetNullTextureView();