- Moved the raw texture handling into the texture manager as well.

This commit is contained in:
Christoph Oelckers 2020-04-16 00:45:14 +02:00
parent 5352682697
commit c5e81c54a2
8 changed files with 80 additions and 48 deletions

View file

@ -41,8 +41,18 @@ class FMultiPatchTexture : public FImageSource
friend class FGameTexture; friend class FGameTexture;
public: public:
FMultiPatchTexture(int w, int h, const TArray<TexPart> &parts, bool complex, bool textual); FMultiPatchTexture(int w, int h, const TArray<TexPart> &parts, bool complex, bool textual);
bool SupportRemap0() override;
int GetNumParts() const { return NumParts; } int GetNumParts() const { return NumParts; }
// Query some needed info for texture hack support.
bool SupportRemap0() override;
bool IsRawCompatible() override
{
return NumParts != 1 || Parts[0].OriginY == 0 || bTextual;
}
FImageSource* GetImageForPart(int num)
{
if (num >= 0 && num < NumParts) return Parts[num].Image;
return nullptr;
}
protected: protected:
int NumParts; int NumParts;

View file

@ -57,7 +57,8 @@ protected:
public: public:
virtual bool SupportRemap0() { return false; } // Unfortunate hackery that's needed for Hexen's skies. virtual bool SupportRemap0() { return false; } // Unfortunate hackery that's needed for Hexen's skies. Only the image can know about the needed parameters
virtual bool IsRawCompatible() { return true; } // Same thing for mid texture compatibility handling. Can only be determined by looking at the composition data which is private to the image.
void CopySize(FImageSource &other) void CopySize(FImageSource &other)
{ {

View file

@ -181,42 +181,6 @@ FBitmap FTexture::GetBgraBitmap(const PalEntry *remap, int *ptrans)
return bmp; return bmp;
} }
//==========================================================================
//
//
//
//==========================================================================
FGameTexture *FGameTexture::GetRawTexture()
{
auto tex = GetTexture();
if (tex->OffsetLess) return tex->OffsetLess;
// Reject anything that cannot have been a single-patch multipatch texture in vanilla.
auto image = static_cast<FMultiPatchTexture *>(tex->GetImage());
if (tex->bMultiPatch != 1 || GetUseType() != ETextureType::Wall || tex->Scale.X != 1 || tex->Scale.Y != 1 ||
useWorldPanning() || image == nullptr || image->GetNumParts() != 1 || tex->_TopOffset[0] == 0)
{
tex->OffsetLess = this;
return this;
}
// Set up a new texture that directly references the underlying patch.
// From here we cannot retrieve the original texture made for it, so just create a new one.
FImageSource *source = image->Parts[0].Image;
// Size must match for this to work as intended
if (source->GetWidth() != GetTexelWidth() || source->GetHeight() != GetTexelHeight())
{
tex->OffsetLess = this;
return this;
}
tex->OffsetLess = MakeGameTexture(new FImageTexture(source, ""));
// todo: This must also copy all layers from the base texture.
TexMan.AddGameTexture(tex->OffsetLess);
return tex->OffsetLess;
}
void FTexture::SetDisplaySize(int fitwidth, int fitheight) void FTexture::SetDisplaySize(int fitwidth, int fitheight)
{ {
Scale.X = double(Width) / fitwidth; Scale.X = double(Width) / fitwidth;

View file

@ -396,7 +396,7 @@ FTextureID FTextureManager::AddGameTexture (FGameTexture *texture, bool addtohas
hash = -1; hash = -1;
} }
TextureHash hasher = { texture, -1, -1, hash }; TextureHash hasher = { texture, -1, -1, -1, hash };
int trans = Textures.Push (hasher); int trans = Textures.Push (hasher);
Translation.Push (trans); Translation.Push (trans);
if (bucket >= 0) HashFirst[bucket] = trans; if (bucket >= 0) HashFirst[bucket] = trans;
@ -1176,6 +1176,50 @@ void FTextureManager::InitPalettedVersions()
} }
} }
//==========================================================================
//
//
//
//==========================================================================
FTextureID FTextureManager::GetRawTexture(FTextureID texid)
{
int texidx = texid.GetIndex();
if ((unsigned)texidx >= Textures.Size()) return texid;
if (Textures[texidx].FrontSkyLayer != -1) return FSetTextureID(Textures[texidx].FrontSkyLayer);
// Reject anything that cannot have been a front layer for the sky in original Hexen, i.e. it needs to be an unscaled wall texture only using Doom patches.
auto tex = Textures[texidx].Texture;
auto ttex = tex->GetTexture();
auto image = tex->GetTexture()->GetImage();
// Reject anything that cannot have been a single-patch multipatch texture in vanilla.
if (image == nullptr || image->IsRawCompatible() || tex->GetUseType() != ETextureType::Wall || tex->GetTexelWidth() != tex->GetDisplayWidth() ||
tex->GetTexelHeight() != tex->GetDisplayHeight())
{
Textures[texidx].RawTexture = texidx;
return texid;
}
// Let the hackery begin
auto mptimage = static_cast<FMultiPatchTexture*>(image);
auto source = mptimage->GetImageForPart(0);
// Size must match for this to work as intended
if (source->GetWidth() != tex->GetTexelWidth() || source->GetHeight() != tex->GetTexelHeight())
{
Textures[texidx].RawTexture = texidx;
return 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, ""));
texid = TexMan.AddGameTexture(RawTexture);
Textures[texidx].RawTexture = texid.GetIndex();
Textures[texid.GetIndex()].RawTexture = texid.GetIndex();
return texid;
}
//========================================================================== //==========================================================================
// //
// Same shit for a different hack, this time Hexen's front sky layers. // Same shit for a different hack, this time Hexen's front sky layers.
@ -1185,7 +1229,7 @@ void FTextureManager::InitPalettedVersions()
FTextureID FTextureManager::GetFrontSkyLayer(FTextureID texid) FTextureID FTextureManager::GetFrontSkyLayer(FTextureID texid)
{ {
int texidx = texid.GetIndex(); int texidx = texid.GetIndex();
if (texidx >= Textures.Size()) return texid; if ((unsigned)texidx >= Textures.Size()) return texid;
if (Textures[texidx].FrontSkyLayer != -1) return FSetTextureID(Textures[texidx].FrontSkyLayer); if (Textures[texidx].FrontSkyLayer != -1) return FSetTextureID(Textures[texidx].FrontSkyLayer);
// Reject anything that cannot have been a front layer for the sky in original Hexen, i.e. it needs to be an unscaled wall texture only using Doom patches. // Reject anything that cannot have been a front layer for the sky in original Hexen, i.e. it needs to be an unscaled wall texture only using Doom patches.
@ -1199,10 +1243,11 @@ 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. // 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()));
FrontSkyLayer->SetUseType(tex->GetUseType()); FrontSkyLayer->SetUseType(tex->GetUseType());
FrontSkyLayer->GetTexture()->bNoRemap0 = true; FrontSkyLayer->GetTexture()->bNoRemap0 = true;
texid = TexMan.AddGameTexture(FrontSkyLayer); texid = TexMan.AddGameTexture(FrontSkyLayer, false);
Textures[texidx].FrontSkyLayer = texid.GetIndex(); Textures[texidx].FrontSkyLayer = texid.GetIndex();
Textures[texid.GetIndex()].FrontSkyLayer = texid.GetIndex(); // also let it refer to itself as its front sky layer, in case for repeated InitSkyMap calls. Textures[texid.GetIndex()].FrontSkyLayer = texid.GetIndex(); // also let it refer to itself as its front sky layer, in case for repeated InitSkyMap calls.
return texid; return texid;
@ -1443,3 +1488,9 @@ FTextureID FTextureID::operator +(int offset) throw()
if (texnum + offset >= TexMan.NumTextures()) return FTextureID(-1); if (texnum + offset >= TexMan.NumTextures()) return FTextureID(-1);
return FTextureID(texnum + offset); return FTextureID(texnum + offset);
} }
CCMD(texinfo)
{
Printf("Sizeof texture = %d\n", sizeof(FTexture));
}

View file

@ -76,6 +76,7 @@ public:
void FlushAll(); void FlushAll();
FTextureID GetFrontSkyLayer(FTextureID); FTextureID GetFrontSkyLayer(FTextureID);
FTextureID GetRawTexture(FTextureID);
enum enum
@ -171,8 +172,9 @@ private:
struct TextureHash struct TextureHash
{ {
FGameTexture* Texture; FGameTexture* Texture;
int Paletted; // redirection to paletted variant int Paletted; // redirection to paletted variant
int FrontSkyLayer; int FrontSkyLayer; // and front sky layer,
int RawTexture;
int HashNext; int HashNext;
bool HasLocalization; bool HasLocalization;
}; };

View file

@ -717,9 +717,6 @@ public:
wrapped.CopySize(&BaseTexture->wrapped); wrapped.CopySize(&BaseTexture->wrapped);
} }
// These substitutions must be done on the material level because their sizes can differ. Substitution must happen before any coordinate calculations take place.
FGameTexture* GetRawTexture();
// Glowing is a pure material property that should not filter down to the actual texture objects. // Glowing is a pure material property that should not filter down to the actual texture objects.
void GetGlowColor(float* data) { wrapped.GetGlowColor(data); } void GetGlowColor(float* data) { wrapped.GetGlowColor(data); }
bool isGlowing() const { return wrapped.isGlowing(); } bool isGlowing() const { return wrapped.isGlowing(); }

View file

@ -2078,7 +2078,9 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_
{ {
if (di->Level->i_compatflags & COMPATF_MASKEDMIDTEX) if (di->Level->i_compatflags & COMPATF_MASKEDMIDTEX)
{ {
tex = tex->GetRawTexture(); auto rawtexid = TexMan.GetRawTexture(tex->GetID());
auto rawtex = TexMan.GetGameTexture(rawtexid);
if (rawtex) tex = rawtex;
} }
texture = tex; texture = tex;
} }

View file

@ -617,7 +617,12 @@ FSoftwareTexture* GetPalettedSWTexture(FTextureID texid, bool animate, bool chec
bool needpal = !vid_nopalsubstitutions && !V_IsTrueColor(); bool needpal = !vid_nopalsubstitutions && !V_IsTrueColor();
auto tex = TexMan.GetPalettedTexture(texid, true, needpal); auto tex = TexMan.GetPalettedTexture(texid, true, needpal);
if (tex == nullptr || (!allownull && !tex->isValid())) return nullptr; if (tex == nullptr || (!allownull && !tex->isValid())) return nullptr;
if (checkcompat) tex = tex->GetRawTexture(); if (checkcompat)
{
auto rawtexid = TexMan.GetRawTexture(tex->GetID());
auto rawtex = TexMan.GetGameTexture(rawtexid);
if (rawtex) tex = rawtex;
}
return GetSoftwareTexture(tex); return GetSoftwareTexture(tex);
} }