mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-06-02 18:01:38 +00:00
- fixed texture layer management so that each material layer can decide for itself if it wants to allow upscaling.
- rewrote the hardware texture precacher to use the new texture management to properly track the data to delete.
This commit is contained in:
parent
cedc95c2a5
commit
b2281c38e1
20 changed files with 190 additions and 135 deletions
|
@ -145,7 +145,7 @@ public:
|
|||
bool isFullbrightDisabled() const { return !!(flags & GTexf_DisableFullbrightSprites); }
|
||||
bool isFullbright() const { return !!(flags & GTexf_RenderFullbright); }
|
||||
bool isFullNameTexture() const { return !!(flags & GTexf_FullNameTexture); }
|
||||
bool expandSprites() const { return !!expandSprite; }
|
||||
bool expandSprites() { return expandSprite == -1? ShouldExpandSprite() : !!expandSprite; }
|
||||
bool useWorldPanning() const { return !!(flags & GTexf_WorldPanning); }
|
||||
void SetWorldPanning(bool on) { if (on) flags |= GTexf_WorldPanning; else flags &= ~GTexf_WorldPanning; }
|
||||
bool allowNoDecals() const { return !!(flags & GTexf_NoDecals); }
|
||||
|
@ -269,6 +269,19 @@ public:
|
|||
|
||||
void CleanHardwareData(bool full = true);
|
||||
|
||||
void GetLayers(TArray<FTexture*>& layers)
|
||||
{
|
||||
layers.Clear();
|
||||
for (auto tex : { Base.get(), Brightmap.get(), Detailmap.get(), Glowmap.get(), Normal.get(), Specular.get(), Metallic.get(), Roughness.get(), AmbientOcclusion.get() })
|
||||
{
|
||||
if (tex != nullptr) layers.Push(tex);
|
||||
}
|
||||
for (auto& tex : CustomShaderTextures)
|
||||
{
|
||||
if (tex != nullptr) layers.Push(tex.get());
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
inline FGameTexture* MakeGameTexture(FTexture* tex, const char *name, ETextureType useType)
|
||||
|
|
|
@ -41,7 +41,8 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
|
|||
{
|
||||
mShaderIndex = SHADER_Default;
|
||||
sourcetex = tx;
|
||||
imgtex = tx->GetTexture();
|
||||
auto imgtex = tx->GetTexture();
|
||||
mTextureLayers.Push({ imgtex, scaleflags });
|
||||
|
||||
if (tx->GetUseType() == ETextureType::SWCanvas && static_cast<FWrapperTexture*>(imgtex)->GetColorFormat() == 0)
|
||||
{
|
||||
|
@ -66,7 +67,7 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
|
|||
{
|
||||
for (auto &texture : { tx->Normal.get(), tx->Specular.get() })
|
||||
{
|
||||
mTextureLayers.Push(texture);
|
||||
mTextureLayers.Push({ texture, 0 });
|
||||
}
|
||||
mShaderIndex = SHADER_Specular;
|
||||
}
|
||||
|
@ -74,7 +75,7 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
|
|||
{
|
||||
for (auto &texture : { tx->Normal.get(), tx->Metallic.get(), tx->Roughness.get(), tx->AmbientOcclusion.get() })
|
||||
{
|
||||
mTextureLayers.Push(texture);
|
||||
mTextureLayers.Push({ texture, 0 });
|
||||
}
|
||||
mShaderIndex = SHADER_PBR;
|
||||
}
|
||||
|
@ -84,30 +85,30 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
|
|||
auto placeholder = TexMan.GameByIndex(1);
|
||||
if (tx->Brightmap.get())
|
||||
{
|
||||
mTextureLayers.Push(tx->Brightmap.get());
|
||||
mTextureLayers.Push({ tx->Brightmap.get(), scaleflags });
|
||||
mLayerFlags |= TEXF_Brightmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
mTextureLayers.Push(placeholder->GetTexture());
|
||||
mTextureLayers.Push({ placeholder->GetTexture(), 0 });
|
||||
}
|
||||
if (tx->Detailmap.get())
|
||||
{
|
||||
mTextureLayers.Push(tx->Detailmap.get());
|
||||
mTextureLayers.Push({ tx->Detailmap.get(), 0 });
|
||||
mLayerFlags |= TEXF_Detailmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
mTextureLayers.Push(placeholder->GetTexture());
|
||||
mTextureLayers.Push({ placeholder->GetTexture(), 0 });
|
||||
}
|
||||
if (tx->Glowmap.get())
|
||||
{
|
||||
mTextureLayers.Push(tx->Glowmap.get());
|
||||
mTextureLayers.Push({ tx->Glowmap.get(), scaleflags });
|
||||
mLayerFlags |= TEXF_Glowmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
mTextureLayers.Push(placeholder->GetTexture());
|
||||
mTextureLayers.Push({ placeholder->GetTexture(), 0 });
|
||||
}
|
||||
|
||||
auto index = tx->GetShaderIndex();
|
||||
|
@ -119,7 +120,7 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
|
|||
for (auto &texture : tx->CustomShaderTextures)
|
||||
{
|
||||
if (texture == nullptr) continue;
|
||||
mTextureLayers.Push(texture.get());
|
||||
mTextureLayers.Push({ texture.get(), 0 }); // scalability should be user-definable.
|
||||
}
|
||||
mShaderIndex = index;
|
||||
}
|
||||
|
@ -149,12 +150,12 @@ FMaterial::~FMaterial()
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
IHardwareTexture *FMaterial::GetLayer(int i, int translation, FTexture **pLayer) const
|
||||
IHardwareTexture *FMaterial::GetLayer(int i, int translation, MaterialLayerInfo **pLayer) const
|
||||
{
|
||||
FTexture *layer = i == 0 ? imgtex : mTextureLayers[i - 1];
|
||||
if (pLayer) *pLayer = layer;
|
||||
auto &layer = mTextureLayers[i];
|
||||
if (pLayer) *pLayer = &layer;
|
||||
|
||||
if (layer) return layer->GetHardwareTexture(translation, mScaleFlags);
|
||||
if (layer.layerTexture) return layer.layerTexture->GetHardwareTexture(translation, layer.scaleFlags);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -169,7 +170,7 @@ FMaterial * FMaterial::ValidateTexture(FGameTexture * gtex, int scaleflags, bool
|
|||
{
|
||||
if (gtex && gtex->isValid())
|
||||
{
|
||||
if (!gtex->ShouldExpandSprite()) scaleflags &= ~CTF_Expand;
|
||||
if (!gtex->expandSprites()) scaleflags &= ~CTF_Expand;
|
||||
|
||||
FMaterial *hwtex = gtex->Material[scaleflags];
|
||||
if (hwtex == NULL && create)
|
||||
|
|
|
@ -8,6 +8,12 @@
|
|||
struct FRemapTable;
|
||||
class IHardwareTexture;
|
||||
|
||||
struct MaterialLayerInfo
|
||||
{
|
||||
FTexture* layerTexture;
|
||||
int scaleFlags;
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// this is the material class for OpenGL.
|
||||
|
@ -17,14 +23,13 @@ class IHardwareTexture;
|
|||
class FMaterial
|
||||
{
|
||||
private:
|
||||
TArray<FTexture*> mTextureLayers;
|
||||
TArray<MaterialLayerInfo> mTextureLayers; // the only layers allowed to scale are the brightmap and the glowmap.
|
||||
int mShaderIndex;
|
||||
int mLayerFlags = 0;
|
||||
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, int scaleflags);
|
||||
virtual ~FMaterial();
|
||||
|
@ -37,27 +42,22 @@ public:
|
|||
{
|
||||
return sourcetex;
|
||||
}
|
||||
FTexture* BaseLayer() const
|
||||
|
||||
void AddTextureLayer(FTexture *tex, bool allowscale)
|
||||
{
|
||||
// Only for spftpoly!
|
||||
return imgtex;
|
||||
}
|
||||
void AddTextureLayer(FTexture *tex)
|
||||
{
|
||||
//ValidateTexture(tex, false);
|
||||
mTextureLayers.Push(tex);
|
||||
mTextureLayers.Push({ tex, allowscale });
|
||||
}
|
||||
|
||||
int GetLayers() const
|
||||
int NumLayers() const
|
||||
{
|
||||
return mTextureLayers.Size() + 1;
|
||||
return mTextureLayers.Size();
|
||||
}
|
||||
|
||||
IHardwareTexture *GetLayer(int i, int translation, FTexture **pLayer = nullptr) const;
|
||||
IHardwareTexture *GetLayer(int i, int translation, MaterialLayerInfo **pLayer = nullptr) const;
|
||||
|
||||
|
||||
static FMaterial *ValidateTexture(FGameTexture * tex, int scaleflags, bool create = true);
|
||||
const TArray<FTexture*> &GetLayerArray() const
|
||||
const TArray<MaterialLayerInfo> &GetLayerArray() const
|
||||
{
|
||||
return mTextureLayers;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ private:
|
|||
{
|
||||
IHardwareTexture *hwTexture = nullptr;
|
||||
int translation = 0;
|
||||
bool precacheMarker; // This is used to check whether a texture has been hit by the precacher, so that the cleanup code can delete the unneeded ones.
|
||||
|
||||
void Delete()
|
||||
{
|
||||
|
@ -40,6 +41,16 @@ private:
|
|||
{
|
||||
Delete();
|
||||
}
|
||||
|
||||
void MarkForPrecache(bool on)
|
||||
{
|
||||
precacheMarker = on;
|
||||
}
|
||||
|
||||
bool isMarkedForPreache() const
|
||||
{
|
||||
return precacheMarker;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -99,25 +110,44 @@ public:
|
|||
//===========================================================================
|
||||
//
|
||||
// Deletes all allocated resources and considers translations
|
||||
// This will only be called for sprites
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void CleanUnused(SpriteHits &usedtranslations, int scaleflags)
|
||||
void CleanUnused()
|
||||
{
|
||||
if (usedtranslations.CheckKey(0) == nullptr)
|
||||
for (auto& tt : hwDefTex)
|
||||
{
|
||||
hwDefTex[scaleflags].Delete();
|
||||
if (!tt.isMarkedForPreache()) tt.Delete();
|
||||
}
|
||||
for (int i = hwTex_Translated.Size()-1; i>= 0; i--)
|
||||
{
|
||||
if (usedtranslations.CheckKey(hwTex_Translated[i].translation & 0xffffff) == nullptr)
|
||||
auto& tt = hwTex_Translated[i];
|
||||
if (!tt.isMarkedForPreache())
|
||||
{
|
||||
hwTex_Translated.Delete(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void UnmarkAll()
|
||||
{
|
||||
for (auto& tt : hwDefTex)
|
||||
{
|
||||
if (!tt.isMarkedForPreache()) tt.MarkForPrecache(false);
|
||||
}
|
||||
for (auto& tt : hwTex_Translated)
|
||||
{
|
||||
if (!tt.isMarkedForPreache()) tt.MarkForPrecache(false);
|
||||
}
|
||||
}
|
||||
|
||||
void MarkForPrecache(int translation, int scaleflags)
|
||||
{
|
||||
auto tt = GetTexID(translation, scaleflags);
|
||||
tt->MarkForPrecache(true);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
void Iterate(T callback)
|
||||
{
|
||||
|
|
|
@ -397,12 +397,6 @@ bool FTexture::DetermineTranslucency()
|
|||
return !!bTranslucent;
|
||||
}
|
||||
|
||||
|
||||
void FTexture::CleanHardwareTextures()
|
||||
{
|
||||
SystemTextures.Clean();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// the default just returns an empty texture.
|
||||
|
|
|
@ -226,7 +226,26 @@ public:
|
|||
IHardwareTexture* GetHardwareTexture(int translation, int scaleflags);
|
||||
virtual FImageSource *GetImage() const { return nullptr; }
|
||||
void CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasAlpha, bool checkonly);
|
||||
void CleanHardwareTextures();
|
||||
|
||||
void CleanHardwareTextures()
|
||||
{
|
||||
SystemTextures.Clean();
|
||||
}
|
||||
|
||||
void CleanPrecacheMarker()
|
||||
{
|
||||
SystemTextures.UnmarkAll();
|
||||
}
|
||||
|
||||
void MarkForPrecache(int translation, int scaleflags)
|
||||
{
|
||||
SystemTextures.MarkForPrecache(translation, scaleflags);
|
||||
}
|
||||
|
||||
void CleanUnused()
|
||||
{
|
||||
SystemTextures.CleanUnused();
|
||||
}
|
||||
|
||||
int GetWidth() { return Width; }
|
||||
int GetHeight() { return Height; }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue