mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-05-31 00:51:21 +00:00
- major refactor of texture upscaling control.
All decisions were done deep inside the texture creation code, leaving zero options to the higher level code for controlling the feature. Changed this so that the option to upscale must be passed as a parameter to FRenderState::SetMaterial and extended all needed variables to manage the added texture variants. Still not solved: Material layers need explicit control, not only for scaling but also for filtering.
This commit is contained in:
parent
0b990f0dcb
commit
8505c7ee7d
27 changed files with 144 additions and 129 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -20,16 +20,17 @@ class FMaterial
|
|||
TArray<FTexture*> 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<FTexture*> &GetLayerArray() const
|
||||
{
|
||||
return mTextureLayers;
|
||||
|
|
|
@ -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<TranslatedTexture> 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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue