- moved hightile replacements out of the texture class.

This commit is contained in:
Christoph Oelckers 2020-05-24 08:47:45 +02:00
parent 498b19873d
commit 0c029750b6
6 changed files with 111 additions and 80 deletions

View file

@ -312,9 +312,9 @@ int32_t polymost_maskWallHasTranslucency(uwalltype const * const wall)
return true; return true;
auto tex = TileFiles.tiles[wall->picnum]; auto tex = TileFiles.tiles[wall->picnum];
auto si = tex->FindReplacement(wall->pal); auto si = TileFiles.FindReplacement(wall->picnum, wall->pal);
if (si && hw_hightile) tex = si->faces[0]; if (si && hw_hightile) tex = si->faces[0];
if (tex->Get8BitPixels()) return false; if (tex->GetTexelWidth() == 0 || tex->GetTexelHeight() == 0) return false;
return tex && tex->GetTranslucency(); return tex && tex->GetTranslucency();
} }
@ -325,7 +325,7 @@ int32_t polymost_spriteHasTranslucency(tspritetype const * const tspr)
return true; return true;
auto tex = TileFiles.tiles[tspr->picnum]; auto tex = TileFiles.tiles[tspr->picnum];
auto si = tex->FindReplacement(tspr->shade, 0); auto si = TileFiles.FindReplacement(tspr->picnum, tspr->shade, 0);
if (si && hw_hightile) tex = si->faces[0]; if (si && hw_hightile) tex = si->faces[0];
if (tex->GetTexelWidth() == 0 || tex->GetTexelHeight() == 0) return false; if (tex->GetTexelWidth() == 0 || tex->GetTexelHeight() == 0) return false;
return tex && tex->GetTranslucency(); return tex && tex->GetTranslucency();

View file

@ -178,6 +178,57 @@ void BuildTiles::AddTiles (int firsttile, TArray<uint8_t>& RawData, bool permap)
} }
} }
//===========================================================================
//
// Replacement textures
//
//===========================================================================
void BuildTiles::AddReplacement(int picnum, const HightileReplacement& replace)
{
auto& Hightiles = tiledata[picnum].Hightiles;
for (auto& ht : Hightiles)
{
if (replace.palnum == ht.palnum && (replace.faces[1] == nullptr) == (ht.faces[1] == nullptr))
{
ht = replace;
return;
}
}
Hightiles.Push(replace);
}
void BuildTiles::DeleteReplacement(int picnum, int palnum)
{
auto& Hightiles = tiledata[picnum].Hightiles;
for (int i = Hightiles.Size() - 1; i >= 0; i--)
{
if (Hightiles[i].palnum == palnum) Hightiles.Delete(i);
}
}
//===========================================================================
//
//
//
//===========================================================================
HightileReplacement* BuildTiles::FindReplacement(int picnum, int palnum, bool skybox)
{
auto& Hightiles = tiledata[picnum].Hightiles;
for (;;)
{
for (auto& rep : Hightiles)
{
if (rep.palnum == palnum && (rep.faces[1] != nullptr) == skybox) return &rep;
}
if (!palnum || palnum >= MAXPALOOKUPS - RESERVEDPALS) break;
palnum = 0;
}
return nullptr; // no replacement found
}
//=========================================================================== //===========================================================================
// //
// CountTiles // CountTiles
@ -267,7 +318,7 @@ void BuildTiles::InvalidateTile(int num)
{ {
auto tex = tiles[num]; auto tex = tiles[num];
tex->DeleteHardwareTextures(); tex->DeleteHardwareTextures();
for (auto &rep : tex->Hightiles) for (auto &rep : tiledata[num].Hightiles)
{ {
for (auto &reptex : rep.faces) for (auto &reptex : rep.faces)
{ {
@ -631,9 +682,8 @@ void tileDelete(int tile)
void tileRemoveReplacement(int tile) void tileRemoveReplacement(int tile)
{ {
if ((unsigned)tile >= MAXTILES) return;
FTexture *tex = TileFiles.tiles[tile]; FTexture *tex = TileFiles.tiles[tile];
tex->DeleteReplacements(); TileFiles.DeleteReplacements(tile);
} }
//========================================================================== //==========================================================================
@ -795,7 +845,7 @@ int tileSetHightileReplacement(int picnum, int palnum, const char *filename, flo
replace.specfactor = specfactor; // currently unused replace.specfactor = specfactor; // currently unused
replace.flags = flags; replace.flags = flags;
replace.palnum = (uint16_t)palnum; replace.palnum = (uint16_t)palnum;
tex->AddReplacement(replace); TileFiles.AddReplacement(picnum, replace);
return 0; return 0;
} }
@ -830,7 +880,7 @@ int tileSetSkybox(int picnum, int palnum, const char **facenames, int flags )
} }
replace.flags = flags; replace.flags = flags;
replace.palnum = (uint16_t)palnum; replace.palnum = (uint16_t)palnum;
tex->AddReplacement(replace); TileFiles.AddReplacement(picnum, replace);
return 0; return 0;
} }
@ -844,8 +894,7 @@ int tileDeleteReplacement(int picnum, int palnum)
{ {
if ((uint32_t)picnum >= (uint32_t)MAXTILES) return -1; if ((uint32_t)picnum >= (uint32_t)MAXTILES) return -1;
if ((uint32_t)palnum >= (uint32_t)MAXPALOOKUPS) return -1; if ((uint32_t)palnum >= (uint32_t)MAXPALOOKUPS) return -1;
auto tex = TileFiles.tiles[picnum]; TileFiles.DeleteReplacement(picnum, palnum);
tex->DeleteReplacement(palnum);
return 0; return 0;
} }

View file

@ -2,6 +2,22 @@
#include "textures.h" #include "textures.h"
enum class ReplacementType : int
{
Art,
Writable,
Restorable,
Canvas
};
struct HightileReplacement
{
FTexture* faces[6]; // only one gets used by a texture, the other 5 are for skyboxes only
vec2f_t scale;
float alphacut, specpower, specfactor;
uint16_t palnum, flags;
};
class FTileTexture : public FTexture class FTileTexture : public FTexture
{ {
public: public:
@ -187,10 +203,28 @@ struct BuildArtFile
// //
//========================================================================== //==========================================================================
struct RawCacheNode
{
TArray<uint8_t> data;
uint64_t lastUseTime;
};
struct TileDesc
{
FTexture* texture; // the currently active tile
FTexture* backup; // original backup for map tiles
RawCacheNode rawCache; // this is needed for hitscan testing to avoid reloading the texture each time.
picanm_t picanm; // animation descriptor
rottile_t RotTile;// = { -1,-1 };
TArray<HightileReplacement> Hightiles;
ReplacementType replacement;
};
struct BuildTiles struct BuildTiles
{ {
FTexture* Placeholder; FTexture* Placeholder;
TDeletingArray<BuildArtFile*> ArtFiles; TDeletingArray<BuildArtFile*> ArtFiles;
TileDesc tiledata[MAXTILES];
TDeletingArray<BuildArtFile*> PerMapArtFiles; TDeletingArray<BuildArtFile*> PerMapArtFiles;
TDeletingArray<FTexture*> AllTiles; // This is for deleting tiles when shutting down. TDeletingArray<FTexture*> AllTiles; // This is for deleting tiles when shutting down.
TDeletingArray<FTexture*> AllMapTiles; // Same for map tiles; TDeletingArray<FTexture*> AllMapTiles; // Same for map tiles;
@ -243,6 +277,16 @@ struct BuildTiles
void ClearTextureCache(bool artonly = false); void ClearTextureCache(bool artonly = false);
void InvalidateTile(int num); void InvalidateTile(int num);
void MakeCanvas(int tilenum, int width, int height); void MakeCanvas(int tilenum, int width, int height);
HightileReplacement* FindReplacement(int picnum, int palnum, bool skybox = false);
void AddReplacement(int picnum, const HightileReplacement&);
void DeleteReplacement(int picnum, int palnum);
void DeleteReplacements(int picnum)
{
assert(picnum < MAXTILES);
tiledata[picnum].Hightiles.Clear();
}
}; };
int tileGetCRC32(int tileNum); int tileGetCRC32(int tileNum);

View file

@ -376,53 +376,6 @@ void FTexture::Create8BitPixels(uint8_t *buffer)
// The base class does not fill the texture. // The base class does not fill the texture.
} }
//===========================================================================
//
// Replacement textures
//
//===========================================================================
void FTexture::AddReplacement(const HightileReplacement & replace)
{
for (auto &ht : Hightiles)
{
if (replace.palnum == ht.palnum && (replace.faces[1] == nullptr) == (ht.faces[1] == nullptr))
{
ht = replace;
return;
}
}
Hightiles.Push(replace);
}
void FTexture::DeleteReplacement(int palnum)
{
for (int i = Hightiles.Size() -1; i >= 0; i--)
{
if (Hightiles[i].palnum == palnum) Hightiles.Delete(i);
}
}
//===========================================================================
//
//
//
//===========================================================================
HightileReplacement *FTexture::FindReplacement(int palnum, bool skybox)
{
for(;;)
{
for (auto &rep : Hightiles)
{
if (rep.palnum == palnum && (rep.faces[1] != nullptr) == skybox) return &rep;
}
if (!palnum || palnum >= MAXPALOOKUPS - RESERVEDPALS) break;
palnum = 0;
}
return nullptr; // no replacement found
}
//=========================================================================== //===========================================================================
// //
// //

View file

@ -100,14 +100,6 @@ struct rottile_t
int16_t owner; int16_t owner;
}; };
struct HightileReplacement
{
FTexture *faces[6]; // only one gets used by a texture, the other 5 are for skyboxes only
vec2f_t scale;
float alphacut, specpower, specfactor;
uint16_t palnum, flags;
};
class FBitmap; class FBitmap;
struct FRemapTable; struct FRemapTable;
struct FCopyInfo; struct FCopyInfo;
@ -242,12 +234,6 @@ public:
virtual void Reload() {} virtual void Reload() {}
UseType GetUseType() const { return useType; } UseType GetUseType() const { return useType; }
void DeleteHardwareTextures(); void DeleteHardwareTextures();
void AddReplacement(const HightileReplacement &);
void DeleteReplacement(int palnum);
void DeleteReplacements()
{
Hightiles.Clear();
}
void SetHardwareTexture(int palid, FHardwareTexture* htex) void SetHardwareTexture(int palid, FHardwareTexture* htex)
{ {
@ -258,8 +244,6 @@ public:
return HardwareTextures.CheckKey(palid); return HardwareTextures.CheckKey(palid);
} }
HightileReplacement * FindReplacement(int palnum, bool skybox = false);
int alphaThreshold = 128; int alphaThreshold = 128;
picanm_t PicAnim = {}; picanm_t PicAnim = {};
FixedBitArray<256> NoBrightmapFlag{ 0 }; FixedBitArray<256> NoBrightmapFlag{ 0 };
@ -293,7 +277,6 @@ protected:
PalEntry FloorSkyColor; PalEntry FloorSkyColor;
PalEntry CeilingSkyColor; PalEntry CeilingSkyColor;
TArray<uint8_t> CachedPixels; TArray<uint8_t> CachedPixels;
TArray<HightileReplacement> Hightiles;
// Don't waste too much effort on efficient storage here. Polymost performs so many calculations on a single draw call that the minor map lookup hardly matters. // Don't waste too much effort on efficient storage here. Polymost performs so many calculations on a single draw call that the minor map lookup hardly matters.
TMap<int, FHardwareTexture*> HardwareTextures; // Note: These must be deleted by the backend. When the texture manager is taken down it may already be too late to delete them. TMap<int, FHardwareTexture*> HardwareTextures; // Note: These must be deleted by the backend. When the texture manager is taken down it may already be too late to delete them.

View file

@ -162,6 +162,7 @@ struct TexturePick
PalEntry basepalTint; // can the base palette be done with a global tint effect? PalEntry basepalTint; // can the base palette be done with a global tint effect?
}; };
#if 0
TexturePick PickTexture(int tilenum, int basepal, int palette) TexturePick PickTexture(int tilenum, int basepal, int palette)
{ {
TexturePick pick = { nullptr, 0, -1, 0xffffff, 0xffffff }; TexturePick pick = { nullptr, 0, -1, 0xffffff, 0xffffff };
@ -169,7 +170,7 @@ TexturePick PickTexture(int tilenum, int basepal, int palette)
int usepalswap = fixpalswap >= 0 ? fixpalswap : palette; int usepalswap = fixpalswap >= 0 ? fixpalswap : palette;
auto& h = hictinting[palette]; auto& h = hictinting[palette];
auto tex = TileFiles.tiles[tilenum]; auto tex = TileFiles.tiles[tilenum];
auto rep = (hw_hightile && !(h.f & HICTINT_ALWAYSUSEART)) ? tex->FindReplacement(usepalswap) : nullptr; auto rep = (hw_hightile && !(h.f & HICTINT_ALWAYSUSEART)) ? TileFiles.FindReplacement(tilenum, usepalswap) : nullptr;
// Canvas textures must be treated like hightile replacements in the following code. // Canvas textures must be treated like hightile replacements in the following code.
bool truecolor = rep || tex->GetUseType() == FTexture::Canvas; bool truecolor = rep || tex->GetUseType() == FTexture::Canvas;
bool applytint = false; bool applytint = false;
@ -207,10 +208,11 @@ TexturePick PickTexture(int tilenum, int basepal, int palette)
} }
return pick; return pick;
} }
#endif
bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int method, int sampleroverride, FTexture *det, float detscale, FTexture *glow) bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int method, int sampleroverride, FTexture *det, float detscale, FTexture *glow)
{ {
if (tex->GetWidth() <= 0 || tex->GetHeight() <= 0) return false; if (tex->GetTexelWidth() <= 0 || tex->GetTexelHeight() <= 0) return false;
int usepalette = fixpalette >= 0 ? fixpalette : curbasepal; int usepalette = fixpalette >= 0 ? fixpalette : curbasepal;
int usepalswap = fixpalswap >= 0 ? fixpalswap : palette; int usepalswap = fixpalswap >= 0 ? fixpalswap : palette;
GLInterface.SetPalette(usepalette); GLInterface.SetPalette(usepalette);
@ -228,7 +230,7 @@ bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int
auto& h = hictinting[palette]; auto& h = hictinting[palette];
bool applytint = false; bool applytint = false;
// Canvas textures must be treated like hightile replacements in the following code. // Canvas textures must be treated like hightile replacements in the following code.
auto rep = (hw_hightile && !(h.f & HICTINT_ALWAYSUSEART)) ? tex->FindReplacement(palette) : nullptr; auto rep = (picnum >= 0 && hw_hightile && !(h.f & HICTINT_ALWAYSUSEART)) ? TileFiles.FindReplacement(picnum, palette) : nullptr;
if (rep || tex->GetUseType() == FTexture::Canvas) if (rep || tex->GetUseType() == FTexture::Canvas)
{ {
if (usepalette != 0) if (usepalette != 0)
@ -295,7 +297,7 @@ bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int
float detscalex = detscale, detscaley = detscale; float detscalex = detscale, detscaley = detscale;
if (!(method & DAMETH_MODEL)) if (!(method & DAMETH_MODEL))
{ {
auto drep = tex->FindReplacement(DETAILPAL); auto drep = TileFiles.FindReplacement(picnum, DETAILPAL);
if (drep) if (drep)
{ {
det = drep->faces[0]; det = drep->faces[0];
@ -327,7 +329,7 @@ bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int
{ {
if (!(method & DAMETH_MODEL)) if (!(method & DAMETH_MODEL))
{ {
auto drep = tex->FindReplacement(GLOWPAL); auto drep = TileFiles.FindReplacement(picnum, GLOWPAL);
if (drep) if (drep)
{ {
glow = drep->faces[0]; glow = drep->faces[0];
@ -346,7 +348,7 @@ bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int
{ {
if (TextureType == TT_HICREPLACE) if (TextureType == TT_HICREPLACE)
{ {
auto brep = tex->FindReplacement(BRIGHTPAL); auto brep = TileFiles.FindReplacement(picnum, BRIGHTPAL);
if (brep) if (brep)
{ {
LoadTexture(brep->faces[0], TT_HICREPLACE, 0); LoadTexture(brep->faces[0], TT_HICREPLACE, 0);