- optimization of texture scaling checks.

The texture dimension checks can be performed up front when the texture is inserted into the texture manager.
This commit is contained in:
Christoph Oelckers 2020-04-17 00:37:05 +02:00
parent 09898ef6c3
commit 70ec20c137
33 changed files with 167 additions and 169 deletions

View file

@ -327,17 +327,15 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla
}
auto orig = pic->GetTexture();
auto tex = MakeGameTexture(new FImageTexture(orig->GetImage(), "")); // todo - can reuse orig directly later.
tex->SetUseType(ETextureType::FontChar);
auto tex = MakeGameTexture(orig, ETextureType::FontChar);
tex->CopySize(pic);
TexMan.AddGameTexture(tex);
Chars[i].OriginalPic = tex;
if (!noTranslate)
{
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar1(orig->GetImage()), ""));
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar1(orig->GetImage()), ""), ETextureType::FontChar);
Chars[i].TranslatedPic->CopySize(pic);
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
TexMan.AddGameTexture(Chars[i].TranslatedPic);
}
else
@ -413,7 +411,6 @@ void FFont::ReadSheetFont(TArray<FolderEntry> &folderdata, int width, int height
part[0].Image = tex->GetTexture()->GetImage();
FMultiPatchTexture *image = new FMultiPatchTexture(width, height, part, false, false);
FImageTexture *tex = new FImageTexture(image, "");
tex->SetUseType(ETextureType::FontChar);
tex->bMultiPatch = true;
tex->_LeftOffset[0] =
tex->_LeftOffset[1] =
@ -425,7 +422,7 @@ void FFont::ReadSheetFont(TArray<FolderEntry> &folderdata, int width, int height
tex->bWorldPanning = true;
tex->bNoDecals = false;
tex->SourceLump = -1; // We do not really care.
auto gtex = MakeGameTexture(tex);
auto gtex = MakeGameTexture(tex, ETextureType::FontChar);
TexMan.AddGameTexture(gtex);
charMap.Insert(int(position) + x + y * numtex_x, gtex);
}
@ -456,10 +453,10 @@ void FFont::ReadSheetFont(TArray<FolderEntry> &folderdata, int width, int height
auto b = pic->Get8BitPixels(false);
Chars[i].OriginalPic = MakeGameTexture(new FImageTexture(pic->GetImage(), ""));
Chars[i].OriginalPic = MakeGameTexture(pic, ETextureType::FontChar);
Chars[i].OriginalPic->SetUseType(ETextureType::FontChar);
Chars[i].OriginalPic->CopySize(*lump);
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar1(pic->GetImage()), ""));
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar1(pic->GetImage()), ""), ETextureType::FontChar);
Chars[i].TranslatedPic->CopySize(*lump);
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
TexMan.AddGameTexture(Chars[i].OriginalPic);

View file

@ -289,8 +289,7 @@ public:
{
auto offset = hexdata.glyphmap[i];
int size = hexdata.glyphdata[offset] / 16;
Chars[i - FirstChar].TranslatedPic = MakeGameTexture(new FImageTexture(new FHexFontChar (&hexdata.glyphdata[offset+1], size, size * 9, 16)));
Chars[i - FirstChar].TranslatedPic->SetUseType(ETextureType::FontChar);
Chars[i - FirstChar].TranslatedPic = MakeGameTexture(new FImageTexture(new FHexFontChar (&hexdata.glyphdata[offset+1], size, size * 9, 16)), ETextureType::FontChar);
Chars[i - FirstChar].XMove = size * spacing;
TexMan.AddGameTexture(Chars[i - FirstChar].TranslatedPic);
}
@ -362,8 +361,7 @@ public:
{
auto offset = hexdata.glyphmap[i];
int size = hexdata.glyphdata[offset] / 16;
Chars[i - FirstChar].TranslatedPic = MakeGameTexture(new FImageTexture(new FHexFontChar2(&hexdata.glyphdata[offset + 1], size, 2 + size * 8, 18)));
Chars[i - FirstChar].TranslatedPic->SetUseType(ETextureType::FontChar);
Chars[i - FirstChar].TranslatedPic = MakeGameTexture(new FImageTexture(new FHexFontChar2(&hexdata.glyphdata[offset + 1], size, 2 + size * 8, 18)), ETextureType::FontChar);
Chars[i - FirstChar].XMove = size * spacing;
TexMan.AddGameTexture(Chars[i - FirstChar].TranslatedPic);
}

View file

@ -353,8 +353,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const uint8_t *data)
}
else
{
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight)));
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight)), ETextureType::FontChar);
TexMan.AddGameTexture(Chars[i].TranslatedPic);
do
{
@ -488,8 +487,7 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data)
chardata[chari+2], // height
-(int8_t)chardata[chari+3], // x offset
-(int8_t)chardata[chari+4] // y offset
)));
tex->SetUseType(ETextureType::FontChar);
)), ETextureType::FontChar);
Chars[chardata[chari] - FirstChar].TranslatedPic = tex;
TexMan.AddGameTexture(tex);
}
@ -556,8 +554,7 @@ void FSingleLumpFont::CheckFON1Chars (double *luminosity)
if(!Chars[i].TranslatedPic)
{
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight)));
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight)), ETextureType::FontChar);
Chars[i].XMove = SpaceWidth;
TexMan.AddGameTexture(Chars[i].TranslatedPic);
}

View file

@ -104,16 +104,14 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FGameTexture
if (charlumps[i] != nullptr)
{
auto pic = charlumps[i];
Chars[i].OriginalPic = MakeGameTexture(new FImageTexture(pic->GetTexture()->GetImage(), ""));
Chars[i].OriginalPic->SetUseType(ETextureType::FontChar);
Chars[i].OriginalPic = MakeGameTexture(pic->GetTexture(), ETextureType::FontChar);
Chars[i].OriginalPic->CopySize(pic);
TexMan.AddGameTexture(Chars[i].OriginalPic);
if (!noTranslate)
{
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar1 (charlumps[i]->GetTexture()->GetImage()), ""));
Chars[i].TranslatedPic = MakeGameTexture(new FImageTexture(new FFontChar1 (charlumps[i]->GetTexture()->GetImage()), ""), ETextureType::FontChar);
Chars[i].TranslatedPic->CopySize(charlumps[i]);
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
TexMan.AddGameTexture(Chars[i].TranslatedPic);
}
else Chars[i].TranslatedPic = Chars[i].OriginalPic;

View file

@ -109,7 +109,8 @@ struct BuildInfo
bool bNoDecals = false;
int LeftOffset[2] = {};
int TopOffset[2] = {};
FImageTexture *tex = nullptr;
FImageTexture* itex = nullptr;
FGameTexture *texture = nullptr;
void swap(BuildInfo &other)
{
@ -128,7 +129,8 @@ struct BuildInfo
std::swap(LeftOffset[1], other.LeftOffset[1]);
std::swap(TopOffset[0], other.TopOffset[0]);
std::swap(TopOffset[1], other.TopOffset[1]);
std::swap(tex, other.tex);
std::swap(itex, other.itex);
std::swap(texture, other.texture);
}
};

View file

@ -609,7 +609,7 @@ FGameTexture *PNGTexture_CreateFromFile(PNGHandle *png, const FString &filename)
// Reject anything that cannot be put into a savegame picture by GZDoom itself.
if (compression != 0 || filter != 0 || interlace > 0 || bitdepth != 8 || (colortype != 2 && colortype != 3)) return nullptr;
else return MakeGameTexture(new FPNGFileTexture (png->File, width, height, colortype));
else return MakeGameTexture(new FPNGFileTexture (png->File, width, height, colortype), ETextureType::Override);
}
//==========================================================================

View file

@ -38,6 +38,7 @@
#include "bitmap.h"
#include "imagehelpers.h"
#include "image.h"
#include "textures.h"
class FBarShader : public FImageSource
@ -128,9 +129,9 @@ private:
};
FTexture *CreateShaderTexture(bool vertical, bool reverse)
FGameTexture *CreateShaderTexture(bool vertical, bool reverse)
{
FStringf name("BarShader%c%c", vertical ? 'v' : 'h', reverse ? 'r' : 'f');
return CreateImageTexture(new FBarShader(vertical, reverse), name.GetChars());
return MakeGameTexture(CreateImageTexture(new FBarShader(vertical, reverse), name.GetChars()), ETextureType::Override);
}

View file

@ -46,6 +46,8 @@
#include "texturemanager.h"
#include "printf.h"
int upscalemask;
EXTERN_CVAR(Int, gl_texture_hqresizemult)
CUSTOM_CVAR(Int, gl_texture_hqresizemode, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
{
@ -54,6 +56,7 @@ CUSTOM_CVAR(Int, gl_texture_hqresizemode, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG |
if ((gl_texture_hqresizemult > 4) && (self < 4) && (self > 0))
gl_texture_hqresizemult = 4;
TexMan.FlushAll();
UpdateUpscaleMask();
}
CUSTOM_CVAR(Int, gl_texture_hqresizemult, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
@ -63,6 +66,7 @@ CUSTOM_CVAR(Int, gl_texture_hqresizemult, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG |
if ((self > 4) && (gl_texture_hqresizemode < 4) && (gl_texture_hqresizemode > 0))
self = 4;
TexMan.FlushAll();
UpdateUpscaleMask();
}
CUSTOM_CVAR(Int, gl_texture_hqresize_maxinputsize, 512, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
@ -74,6 +78,7 @@ CUSTOM_CVAR(Int, gl_texture_hqresize_maxinputsize, 512, CVAR_ARCHIVE | CVAR_GLOB
CUSTOM_CVAR(Int, gl_texture_hqresize_targets, 7, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
{
TexMan.FlushAll();
UpdateUpscaleMask();
}
CVAR (Flag, gl_texture_hqresize_textures, gl_texture_hqresize_targets, 1);
@ -96,6 +101,13 @@ CUSTOM_CVAR(Int, gl_texture_hqresize_mt_height, 4, CVAR_ARCHIVE | CVAR_GLOBALCON
CVAR(Int, xbrz_colorformat, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
void UpdateUpscaleMask()
{
if (!gl_texture_hqresizemode || gl_texture_hqresizemult == 1) upscalemask = 0;
else upscalemask = gl_texture_hqresize_targets;
}
static void xbrzApplyOptions()
{
if (gl_texture_hqresizemult != 0 && (gl_texture_hqresizemode == 4 || gl_texture_hqresizemode == 5))
@ -490,34 +502,20 @@ void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasA
//
//===========================================================================
bool calcShouldUpscale(FGameTexture *tex, ETextureType UseType)
int calcShouldUpscale(FGameTexture *tex)
{
if (gl_texture_hqresizemode == 0 || gl_texture_hqresizemult == 1) return false;
// [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;
return 0;
// [BB] Don't try to upsample textures based off FCanvasTexture. (This should never get here in the first place!)
if (tex->isHardwareCanvas())
return false;
return 0;
// 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);
}
return 0;
return CTF_Upscale;
}

View file

@ -78,7 +78,7 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
}
// Note that these layers must present a valid texture even if not used, because empty TMUs in the shader are an undefined condition.
imgtex->CreateDefaultBrightmap();
tx->CreateDefaultBrightmap();
auto placeholder = TexMan.GameByIndex(1);
if (imgtex->Brightmap)
{

View file

@ -138,7 +138,6 @@ struct FPatchLookup
void FMultipatchTextureBuilder::MakeTexture(BuildInfo &buildinfo, ETextureType usetype)
{
FImageTexture *tex = new FImageTexture(nullptr, buildinfo.Name);
tex->SetUseType(usetype);
tex->bMultiPatch = true;
tex->SetSize(buildinfo.Width, buildinfo.Height);
tex->_LeftOffset[0] = buildinfo.LeftOffset[0];
@ -151,8 +150,9 @@ void FMultipatchTextureBuilder::MakeTexture(BuildInfo &buildinfo, ETextureType u
tex->bWorldPanning = buildinfo.bWorldPanning;
tex->bNoDecals = buildinfo.bNoDecals;
tex->SourceLump = buildinfo.DefinitionLump;
buildinfo.tex = tex;
TexMan.AddGameTexture(MakeGameTexture(tex));
buildinfo.itex = tex;
buildinfo.texture = MakeGameTexture(tex, usetype);
TexMan.AddGameTexture(buildinfo.texture);
}
//==========================================================================
@ -773,19 +773,19 @@ void FMultipatchTextureBuilder::ResolvePatches(BuildInfo &buildinfo)
for (unsigned i = 0; i < buildinfo.Inits.Size(); i++)
{
FTextureID texno = TexMan.CheckForTexture(buildinfo.Inits[i].TexName, buildinfo.Inits[i].UseType);
if (texno == buildinfo.tex->id) // we found ourselves. Try looking for another one with the same name which is not a multipatch texture itself.
if (texno == buildinfo.texture->GetID()) // we found ourselves. Try looking for another one with the same name which is not a multipatch texture itself.
{
TArray<FTextureID> list;
TexMan.ListTextures(buildinfo.Inits[i].TexName, list, true);
for (int i = list.Size() - 1; i >= 0; i--)
{
if (list[i] != buildinfo.tex->id && !TexMan.GetGameTexture(list[i])->isMultiPatch() )
if (list[i] != buildinfo.texture->GetID() && !TexMan.GetGameTexture(list[i])->isMultiPatch() )
{
texno = list[i];
break;
}
}
if (texno == buildinfo.tex->id)
if (texno == buildinfo.texture->GetID())
{
if (buildinfo.Inits[i].HasLine) buildinfo.Inits[i].sc.Message(MSG_WARNING, "Texture '%s' references itself as patch\n", buildinfo.Inits[i].TexName.GetChars());
else Printf(TEXTCOLOR_YELLOW "Texture '%s' references itself as patch\n", buildinfo.Inits[i].TexName.GetChars());
@ -814,7 +814,7 @@ void FMultipatchTextureBuilder::ResolvePatches(BuildInfo &buildinfo)
{
//We cannot set the image source yet. First all textures need to be resolved.
buildinfo.Inits[i].Texture = tex->GetTexture();
buildinfo.tex->bComplex |= tex->GetTexture()->bComplex; // this one's NOT a material property! It must remain on the texture image.
buildinfo.itex->bComplex |= tex->GetTexture()->bComplex; // this one's NOT a material property! It must remain on the texture image.
buildinfo.bComplex |= tex->GetTexture()->bComplex;
if (buildinfo.Inits[i].UseOffsets)
{
@ -898,14 +898,14 @@ void FMultipatchTextureBuilder::ResolveAllPatches()
buildinfo.Parts[0].Rotate == 0 &&
!buildinfo.bComplex)
{
buildinfo.tex->SetImage(buildinfo.Parts[0].Image);
buildinfo.itex->SetImage(buildinfo.Parts[0].Image);
done = true;
}
}
if (!done)
{
auto img = new FMultiPatchTexture(buildinfo.Width, buildinfo.Height, buildinfo.Parts, buildinfo.bComplex, buildinfo.textual);
buildinfo.tex->SetImage(img);
buildinfo.itex->SetImage(img);
}
BuiltTextures.Delete(i);
@ -918,7 +918,7 @@ void FMultipatchTextureBuilder::ResolveAllPatches()
for (auto &b : BuiltTextures)
{
Printf("%s\n", b.Name.GetChars());
b.tex->SetUseType(ETextureType::Null);
b.texture->SetUseType(ETextureType::Null);
}
break;
}

View file

@ -44,7 +44,6 @@ FSkyBox::FSkyBox(const char *name)
}
else previous = nullptr;
faces[0]=faces[1]=faces[2]=faces[3]=faces[4]=faces[5] = nullptr;
UseType = ETextureType::Override;
bSkybox = true;
fliptop = false;
}

View file

@ -80,7 +80,7 @@ FTexture * FTexture::CreateTexture(const char *name, int lumpnum, ETextureType u
FTexture *tex = new FImageTexture(image);
if (tex != nullptr)
{
tex->UseType = usetype;
//tex->UseType = usetype;
if (usetype == ETextureType::Flat)
{
int w = tex->GetTexelWidth();
@ -117,7 +117,7 @@ FTexture * FTexture::CreateTexture(const char *name, int lumpnum, ETextureType u
FTexture::FTexture (const char *name, int lumpnum)
:
Scale(1,1), SourceLump(lumpnum),
UseType(ETextureType::Any), bNoDecals(false), bNoRemap0(false), bWorldPanning(false),
bNoDecals(false), bNoRemap0(false), bWorldPanning(false),
bMasked(true), bAlphaTexture(false), bHasCanvas(false), bWarped(0), bComplex(false), bMultiPatch(false), bFullNameTexture(false),
Rotations(0xFFFF), SkyOffset(0), Width(0), Height(0)
{
@ -343,17 +343,18 @@ void FTexture::AddAutoMaterials()
// Checks if the texture has a default brightmap and creates it if so
//
//===========================================================================
void FTexture::CreateDefaultBrightmap()
void FGameTexture::CreateDefaultBrightmap()
{
if (!bBrightmapChecked)
auto tex = GetTexture();
if (!tex->bBrightmapChecked)
{
// Check for brightmaps
if (GetImage() && GetImage()->UseGamePalette() && GPalette.HasGlobalBrightmap &&
UseType != ETextureType::Decal && UseType != ETextureType::MiscPatch && UseType != ETextureType::FontChar &&
Brightmap == NULL)
if (tex->GetImage() && tex->GetImage()->UseGamePalette() && GPalette.HasGlobalBrightmap &&
GetUseType() != ETextureType::Decal && GetUseType() != ETextureType::MiscPatch && GetUseType() != ETextureType::FontChar &&
tex->Brightmap == NULL)
{
// May have one - let's check when we use this texture
auto texbuf = Get8BitPixels(false);
auto texbuf = tex->Get8BitPixels(false);
const int white = ColorMatcher.Pick(255, 255, 255);
int size = GetTexelWidth() * GetTexelHeight();
@ -362,21 +363,21 @@ void FTexture::CreateDefaultBrightmap()
if (GPalette.GlobalBrightmap.Remap[texbuf[i]] == white)
{
// Create a brightmap
DPrintf(DMSG_NOTIFY, "brightmap created for texture '%s'\n", Name.GetChars());
Brightmap = CreateBrightmapTexture(static_cast<FImageTexture*>(this)->GetImage());
bBrightmapChecked = true;
TexMan.AddGameTexture(MakeGameTexture(Brightmap));
DPrintf(DMSG_NOTIFY, "brightmap created for texture '%s'\n", GetName().GetChars());
tex->Brightmap = CreateBrightmapTexture(static_cast<FImageTexture*>(tex)->GetImage());
tex->bBrightmapChecked = true;
//TexMan.AddGameTexture(MakeGameTexture(tex->Brightmap));
return;
}
}
// No bright pixels found
DPrintf(DMSG_SPAMMY, "No bright pixels found in texture '%s'\n", Name.GetChars());
bBrightmapChecked = true;
DPrintf(DMSG_SPAMMY, "No bright pixels found in texture '%s'\n", GetName().GetChars());
tex->bBrightmapChecked = true;
}
else
{
// does not have one so set the flag to 'done'
bBrightmapChecked = true;
tex->bBrightmapChecked = true;
}
}
}
@ -440,7 +441,6 @@ bool FTexture::FindHoles(const unsigned char * buffer, int w, int h)
// already done!
if (areacount) return false;
if (UseType == ETextureType::Flat) return false; // flats don't have transparent parts
areacount = -1; //whatever happens next, it shouldn't be done twice!
// large textures are excluded for performance reasons
@ -949,7 +949,7 @@ void FTexture::SetSpriteRect()
IHardwareTexture* FTexture::GetHardwareTexture(int translation, int scaleflags)
{
if (UseType != ETextureType::Null)
//if (UseType != ETextureType::Null)
{
IHardwareTexture* hwtex = SystemTextures.GetHardwareTexture(translation, scaleflags);
if (hwtex == nullptr)
@ -1076,7 +1076,6 @@ FWrapperTexture::FWrapperTexture(int w, int h, int bits)
Width = w;
Height = h;
Format = bits;
UseType = ETextureType::SWCanvas;
bNoCompress = true;
auto hwtex = CreateHardwareTexture();
// todo: Initialize here.

View file

@ -17,6 +17,7 @@ enum class ETextureType : uint8_t
SkinGraphic,
Null,
FirstDefined,
Special,
SWCanvas,
};

View file

@ -107,7 +107,7 @@ void FTextureManager::DeleteAll()
// all CCMDs triggering a flush can be executed while a wipe is in progress
//
// This now also deletes the software textures because having the software
// renderer use the texture scalers is a planned feature and that is the
// renderer can also use the texture scalers and that is the
// main reason to call this outside of the destruction code.
//
//==========================================================================
@ -121,6 +121,7 @@ void FTextureManager::FlushAll()
Textures[i].Texture->GetTexture()->CleanHardwareTextures(true);
delete Textures[i].Texture->GetTexture()->SoftwareTexture;
Textures[i].Texture->GetTexture()->SoftwareTexture = nullptr;
calcShouldUpscale(Textures[i].Texture);
}
}
}
@ -229,7 +230,7 @@ FTextureID FTextureManager::CheckForTexture (const char *name, ETextureType uset
if (tex == NO_TEXTURE) return FTextureID(-1);
if (tex != NULL) return tex->GetID();
if (flags & TEXMAN_DontCreate) return FTextureID(-1); // we only want to check, there's no need to create a texture if we don't have one yet.
tex = MakeGameTexture(FTexture::CreateTexture("", lump, ETextureType::Override));
tex = MakeGameTexture(FTexture::CreateTexture("", lump, ETextureType::Override), ETextureType::Override);
if (tex != NULL)
{
tex->AddAutoMaterials();
@ -383,6 +384,7 @@ FTextureID FTextureManager::AddGameTexture (FGameTexture *texture, bool addtohas
if (texture == NULL) return FTextureID(-1);
// Later textures take precedence over earlier ones
calcShouldUpscale(texture); // calculate this once at insertion
// Textures without name can't be looked for
if (addtohash && texture->GetName().IsNotEmpty())
@ -417,7 +419,7 @@ FTextureID FTextureManager::CreateTexture (int lumpnum, ETextureType usetype)
{
FString str;
fileSystem.GetFileShortName(str, lumpnum);
auto out = MakeGameTexture(FTexture::CreateTexture(str, lumpnum, usetype));
auto out = MakeGameTexture(FTexture::CreateTexture(str, lumpnum, usetype), usetype);
if (out != NULL) return AddGameTexture (out);
else
@ -557,10 +559,9 @@ void FTextureManager::AddHiresTextures (int wadnum)
if (amount == 0)
{
// A texture with this name does not yet exist
auto newtex = MakeGameTexture(FTexture::CreateTexture (Name, firsttx, ETextureType::Any));
auto newtex = MakeGameTexture(FTexture::CreateTexture (Name, firsttx, ETextureType::Any), ETextureType::Override);
if (newtex != NULL)
{
newtex->SetUseType(ETextureType::Override);
AddGameTexture(newtex);
}
}
@ -580,7 +581,7 @@ void FTextureManager::AddHiresTextures (int wadnum)
newtex->_LeftOffset[1] = int(oldtex->GetDisplayLeftOffset(1) * newtex->Scale.X);
newtex->_TopOffset[0] = int(oldtex->GetDisplayTopOffset(0) * newtex->Scale.Y);
newtex->_TopOffset[1] = int(oldtex->GetDisplayTopOffset(1) * newtex->Scale.Y);
ReplaceTexture(tlist[i], MakeGameTexture(newtex), true);
ReplaceTexture(tlist[i], MakeGameTexture(newtex, ETextureType::Override), true);
}
}
}
@ -677,7 +678,7 @@ void FTextureManager::ParseTextureDef(int lump, FMultipatchTextureBuilder &build
newtex->_LeftOffset[1] = int(oldtex->GetDisplayLeftOffset(1) * newtex->Scale.X);
newtex->_TopOffset[0] = int(oldtex->GetDisplayTopOffset(0) * newtex->Scale.Y);
newtex->_TopOffset[1] = int(oldtex->GetDisplayTopOffset(1) * newtex->Scale.Y);
ReplaceTexture(tlist[i], MakeGameTexture(newtex), true);
ReplaceTexture(tlist[i], MakeGameTexture(newtex, ETextureType::Override), true);
}
}
}
@ -706,7 +707,7 @@ void FTextureManager::ParseTextureDef(int lump, FMultipatchTextureBuilder &build
if (lumpnum>=0)
{
auto newtex = MakeGameTexture(FTexture::CreateTexture(src, lumpnum, ETextureType::Override));
auto newtex = MakeGameTexture(FTexture::CreateTexture(src, lumpnum, ETextureType::Override), ETextureType::Override);
if (newtex != NULL)
{
@ -926,7 +927,7 @@ void FTextureManager::AddTexturesForWad(int wadnum, FMultipatchTextureBuilder &b
// Try to create a texture from this lump and add it.
// Unfortunately we have to look at everything that comes through here...
auto out = MakeGameTexture(FTexture::CreateTexture(Name, i, skin ? ETextureType::SkinGraphic : ETextureType::MiscPatch));
auto out = MakeGameTexture(FTexture::CreateTexture(Name, i, ETextureType::MiscPatch), skin ? ETextureType::SkinGraphic : ETextureType::MiscPatch);
if (out != NULL)
{
@ -1082,7 +1083,7 @@ void FTextureManager::AddLocalizedVariants()
// FTextureManager :: Init
//
//==========================================================================
FTexture *CreateShaderTexture(bool, bool);
FGameTexture *CreateShaderTexture(bool, bool);
void InitBuildTiles();
FImageSource* CreateEmptyTexture();
@ -1093,18 +1094,17 @@ void FTextureManager::Init(void (*progressFunc_)(), void (*checkForHacks)(BuildI
//if (BuildTileFiles.Size() == 0) CountBuildTiles ();
// Texture 0 is a dummy texture used to indicate "no texture"
auto nulltex = MakeGameTexture(new FImageTexture(nullptr, ""));
nulltex->SetUseType(ETextureType::Null);
auto nulltex = MakeGameTexture(new FImageTexture(nullptr, ""), ETextureType::Null);
AddGameTexture (nulltex);
// This is for binding to unused texture units, because accessing an unbound texture unit is undefined. It's a one pixel empty texture.
auto emptytex = MakeGameTexture(new FImageTexture(CreateEmptyTexture(), ""));
auto emptytex = MakeGameTexture(new FImageTexture(CreateEmptyTexture(), ""), ETextureType::Override);
emptytex->SetSize(1, 1);
AddGameTexture(emptytex);
// some special textures used in the game.
AddGameTexture(MakeGameTexture(CreateShaderTexture(false, false)));
AddGameTexture(MakeGameTexture(CreateShaderTexture(false, true)));
AddGameTexture(MakeGameTexture(CreateShaderTexture(true, false)));
AddGameTexture(MakeGameTexture(CreateShaderTexture(true, true)));
AddGameTexture(CreateShaderTexture(false, false));
AddGameTexture(CreateShaderTexture(false, true));
AddGameTexture(CreateShaderTexture(true, false));
AddGameTexture(CreateShaderTexture(true, true));
int wadcnt = fileSystem.GetNumWads();
@ -1212,7 +1212,7 @@ FTextureID FTextureManager::GetRawTexture(FTextureID texid)
}
// Todo: later this can just link to the already existing texture for this source graphic, once it can be retrieved through the image's SourceLump index
auto RawTexture = MakeGameTexture(new FImageTexture(source, ""));
auto RawTexture = MakeGameTexture(new FImageTexture(source, ""), ETextureType::Wall);
texid = TexMan.AddGameTexture(RawTexture);
Textures[texidx].RawTexture = texid.GetIndex();
Textures[texid.GetIndex()].RawTexture = texid.GetIndex();
@ -1244,7 +1244,7 @@ FTextureID FTextureManager::GetFrontSkyLayer(FTextureID texid)
// Set this up so that it serializes to the same info as the base texture - this is needed to restore it on load.
// But do not link the new texture into the hash chain!
auto FrontSkyLayer = MakeGameTexture(new FImageTexture(image, tex->GetName()));
auto FrontSkyLayer = MakeGameTexture(new FImageTexture(image, tex->GetName()), ETextureType::Wall);
FrontSkyLayer->SetUseType(tex->GetUseType());
FrontSkyLayer->GetTexture()->bNoRemap0 = true;
texid = TexMan.AddGameTexture(FrontSkyLayer, false);

View file

@ -250,7 +250,7 @@ public:
SpritePositioningInfo *spi = nullptr;
IHardwareTexture* GetHardwareTexture(int translation, int scaleflags);
static FTexture *CreateTexture(const char *name, int lumpnum, ETextureType usetype);
static FTexture *CreateTexture(const char *name, int lumpnum, ETextureType UseType);
virtual ~FTexture ();
virtual FImageSource *GetImage() const { return nullptr; }
void AddAutoMaterials();
@ -273,8 +273,6 @@ public:
int GetTexelTopOffset(int adjusted) { return _TopOffset[adjusted]; }
bool isValid() const { return UseType != ETextureType::Null; }
bool isSWCanvas() const { return UseType == ETextureType::SWCanvas; }
bool isSkybox() const { return bSkybox; }
bool isFullbrightDisabled() const { return bDisableFullbright; }
bool isHardwareCanvas() const { return bHasCanvas; } // There's two here so that this can deal with software canvases in the hardware renderer later.
@ -283,7 +281,6 @@ public:
int GetRotations() const { return Rotations; }
float GetShaderSpeed() const { return shaderspeed; }
void SetRotations(int rot) { Rotations = int16_t(rot); }
bool isSprite() const { return UseType == ETextureType::Sprite || UseType == ETextureType::SkinSprite || UseType == ETextureType::Decal; }
const FString &GetName() const { return Name; }
void SetNoDecals(bool on) { bNoDecals = on; }
@ -301,11 +298,8 @@ public:
bool isAutoGlowing() const { return bAutoGlowing; }
int GetGlowHeight() const { return GlowHeight; }
bool isFullbright() const { return bFullbright; }
void CreateDefaultBrightmap();
bool FindHoles(const unsigned char * buffer, int w, int h);
void SetUseType(ETextureType type) { UseType = type; }
int GetSourceLump() const { return SourceLump; }
ETextureType GetUseType() const { return UseType; }
void SetSpeed(float fac) { shaderspeed = fac; }
bool UseWorldPanning() const { return bWorldPanning; }
void SetWorldPanning(bool on) { bWorldPanning = on; }
@ -382,7 +376,6 @@ protected:
protected:
FString Name;
ETextureType UseType; // This texture's primary purpose
uint8_t bNoDecals:1; // Decals should not stick to texture
uint8_t bNoRemap0:1; // Do not remap color 0 (used by front layer of parallax skies)
@ -500,7 +493,6 @@ public:
bHasCanvas = true;
bTranslucent = false;
bExpandSprite = false;
UseType = ETextureType::Wall;
}
void NeedUpdate() { bNeedsUpdate = true; }
@ -632,11 +624,15 @@ public:
class FGameTexture
{
FTexture *wrapped;
int8_t shouldUpscaleFlag = -1;
int8_t shouldUpscaleFlag = 0; // Without explicit setup, scaling is disabled for a texture.
ETextureType UseType = ETextureType::Wall; // This texture's primary purpose
public:
FGameTexture(FTexture* wrap) : wrapped(wrap) {}
~FGameTexture();
void CreateDefaultBrightmap();
ETextureType GetUseType() const { return UseType; }
void SetUpscaleFlag(int what) { shouldUpscaleFlag = what; }
int GetUpscaleFlag() { return shouldUpscaleFlag; }
@ -653,13 +649,13 @@ public:
double GetDisplayLeftOffset(int adjusted = 0) /*const*/ { return wrapped->GetDisplayLeftOffsetDouble(adjusted); }
double GetDisplayTopOffset(int adjusted = 0) /*const*/ { return wrapped->GetDisplayTopOffsetDouble(adjusted); }
bool isValid() { return wrapped->isValid(); }
bool isValid() const { return UseType != ETextureType::Null; }
int isWarped() { return wrapped->isWarped(); }
void SetWarpStyle(int style) { wrapped->bWarped = style; }
bool isMasked() { return wrapped->isMasked(); }
bool isHardwareCanvas() const { return wrapped->isHardwareCanvas(); } // There's two here so that this can deal with software canvases in the hardware renderer later.
bool isSoftwareCanvas() const { return wrapped->isCanvas(); }
bool isMiscPatch() const { return wrapped->GetUseType() == ETextureType::MiscPatch; } // only used by the intermission screen to decide whether to tile the background image or not.
bool isMiscPatch() const { return GetUseType() == ETextureType::MiscPatch; } // only used by the intermission screen to decide whether to tile the background image or not.
bool isMultiPatch() const { return wrapped->bMultiPatch; }
bool isFullbrightDisabled() const { return wrapped->isFullbrightDisabled(); }
bool isFullbright() const { return wrapped->isFullbright(); }
@ -670,8 +666,7 @@ public:
bool allowNoDecals() const { return wrapped->allowNoDecals(); }
void SetNoDecals(bool on) { wrapped->bNoDecals = on; }
void SetTranslucent(bool on) { wrapped->bTranslucent = on; }
ETextureType GetUseType() const { return wrapped->GetUseType(); }
void SetUseType(ETextureType type) { wrapped->SetUseType(type); }
void SetUseType(ETextureType type) { UseType = type; }
int GetShaderIndex() const { return wrapped->shaderindex; }
float GetShaderSpeed() const { return wrapped->GetShaderSpeed(); }
uint16_t GetRotations() const { return wrapped->GetRotations(); }
@ -753,21 +748,31 @@ public:
}
};
inline FGameTexture* MakeGameTexture(FTexture* tex)
inline FGameTexture* MakeGameTexture(FTexture* tex, ETextureType useType)
{
if (!tex) return nullptr;
return new FGameTexture(tex);
auto t = new FGameTexture(tex);
t->SetUseType(useType);
return t;
}
bool calcShouldUpscale(FGameTexture* tex, ETextureType UseType);
inline bool shouldUpscale(FGameTexture* tex, ETextureType UseType)
enum EUpscaleFlags
{
auto f = tex->GetUpscaleFlag();
// Cache this value in the texture to save time because it is very frequently polled.
if (f != -1) return f;
auto res = calcShouldUpscale(tex, UseType);
tex->SetUpscaleFlag(res);
return res;
UF_None = 0,
UF_Texture = 1,
UF_Sprite = 2,
UF_Font = 4
};
extern int upscalemask;
void UpdateUpscaleMask();
int calcShouldUpscale(FGameTexture* tex);
inline int shouldUpscale(FGameTexture* tex, EUpscaleFlags UseType)
{
// This only checks the global scale mask and the texture's validation for upscaling. Everything else has been done up front elsewhere.
if (!(upscalemask & UseType)) return 0;
return tex->GetUpscaleFlag();
}
#endif