- 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;
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 (tex->Get8BitPixels()) return false;
if (tex->GetTexelWidth() == 0 || tex->GetTexelHeight() == 0) return false;
return tex && tex->GetTranslucency();
}
@ -325,7 +325,7 @@ int32_t polymost_spriteHasTranslucency(tspritetype const * const tspr)
return true;
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 (tex->GetTexelWidth() == 0 || tex->GetTexelHeight() == 0) return false;
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
@ -267,7 +318,7 @@ void BuildTiles::InvalidateTile(int num)
{
auto tex = tiles[num];
tex->DeleteHardwareTextures();
for (auto &rep : tex->Hightiles)
for (auto &rep : tiledata[num].Hightiles)
{
for (auto &reptex : rep.faces)
{
@ -631,9 +682,8 @@ void tileDelete(int tile)
void tileRemoveReplacement(int tile)
{
if ((unsigned)tile >= MAXTILES) return;
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.flags = flags;
replace.palnum = (uint16_t)palnum;
tex->AddReplacement(replace);
TileFiles.AddReplacement(picnum, replace);
return 0;
}
@ -830,7 +880,7 @@ int tileSetSkybox(int picnum, int palnum, const char **facenames, int flags )
}
replace.flags = flags;
replace.palnum = (uint16_t)palnum;
tex->AddReplacement(replace);
TileFiles.AddReplacement(picnum, replace);
return 0;
}
@ -844,8 +894,7 @@ int tileDeleteReplacement(int picnum, int palnum)
{
if ((uint32_t)picnum >= (uint32_t)MAXTILES) return -1;
if ((uint32_t)palnum >= (uint32_t)MAXPALOOKUPS) return -1;
auto tex = TileFiles.tiles[picnum];
tex->DeleteReplacement(palnum);
TileFiles.DeleteReplacement(picnum, palnum);
return 0;
}

View file

@ -2,6 +2,22 @@
#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
{
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
{
FTexture* Placeholder;
TDeletingArray<BuildArtFile*> ArtFiles;
TileDesc tiledata[MAXTILES];
TDeletingArray<BuildArtFile*> PerMapArtFiles;
TDeletingArray<FTexture*> AllTiles; // This is for deleting tiles when shutting down.
TDeletingArray<FTexture*> AllMapTiles; // Same for map tiles;
@ -243,6 +277,16 @@ struct BuildTiles
void ClearTextureCache(bool artonly = false);
void InvalidateTile(int num);
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);

View file

@ -376,53 +376,6 @@ void FTexture::Create8BitPixels(uint8_t *buffer)
// 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;
};
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;
struct FRemapTable;
struct FCopyInfo;
@ -242,12 +234,6 @@ public:
virtual void Reload() {}
UseType GetUseType() const { return useType; }
void DeleteHardwareTextures();
void AddReplacement(const HightileReplacement &);
void DeleteReplacement(int palnum);
void DeleteReplacements()
{
Hightiles.Clear();
}
void SetHardwareTexture(int palid, FHardwareTexture* htex)
{
@ -258,8 +244,6 @@ public:
return HardwareTextures.CheckKey(palid);
}
HightileReplacement * FindReplacement(int palnum, bool skybox = false);
int alphaThreshold = 128;
picanm_t PicAnim = {};
FixedBitArray<256> NoBrightmapFlag{ 0 };
@ -293,7 +277,6 @@ protected:
PalEntry FloorSkyColor;
PalEntry CeilingSkyColor;
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.
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?
};
#if 0
TexturePick PickTexture(int tilenum, int basepal, int palette)
{
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;
auto& h = hictinting[palette];
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.
bool truecolor = rep || tex->GetUseType() == FTexture::Canvas;
bool applytint = false;
@ -207,10 +208,11 @@ TexturePick PickTexture(int tilenum, int basepal, int palette)
}
return pick;
}
#endif
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 usepalswap = fixpalswap >= 0 ? fixpalswap : palette;
GLInterface.SetPalette(usepalette);
@ -228,7 +230,7 @@ bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int
auto& h = hictinting[palette];
bool applytint = false;
// 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 (usepalette != 0)
@ -295,7 +297,7 @@ bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int
float detscalex = detscale, detscaley = detscale;
if (!(method & DAMETH_MODEL))
{
auto drep = tex->FindReplacement(DETAILPAL);
auto drep = TileFiles.FindReplacement(picnum, DETAILPAL);
if (drep)
{
det = drep->faces[0];
@ -327,7 +329,7 @@ bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int
{
if (!(method & DAMETH_MODEL))
{
auto drep = tex->FindReplacement(GLOWPAL);
auto drep = TileFiles.FindReplacement(picnum, GLOWPAL);
if (drep)
{
glow = drep->faces[0];
@ -346,7 +348,7 @@ bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int
{
if (TextureType == TT_HICREPLACE)
{
auto brep = tex->FindReplacement(BRIGHTPAL);
auto brep = TileFiles.FindReplacement(picnum, BRIGHTPAL);
if (brep)
{
LoadTexture(brep->faces[0], TT_HICREPLACE, 0);