- make FGameTexture a separate object owning an FTexture instead of merely using a type cast to access it.

This commit is contained in:
Christoph Oelckers 2020-04-16 19:34:56 +02:00
parent 095a5e2c0a
commit a81bb2a136
3 changed files with 93 additions and 83 deletions

View file

@ -148,8 +148,6 @@ FTexture::FTexture (const char *name, int lumpnum)
FTexture::~FTexture () FTexture::~FTexture ()
{ {
FGameTexture *link = fileSystem.GetLinkedTexture(SourceLump);
if (link->GetTexture() == this) fileSystem.SetLinkedTexture(SourceLump, nullptr);
if (areas != nullptr) delete[] areas; if (areas != nullptr) delete[] areas;
areas = nullptr; areas = nullptr;
@ -1084,9 +1082,16 @@ FWrapperTexture::FWrapperTexture(int w, int h, int bits)
} }
FGameTexture::~FGameTexture()
{
FGameTexture* link = fileSystem.GetLinkedTexture(GetSourceLump());
if (link == this) fileSystem.SetLinkedTexture(GetSourceLump(), nullptr);
delete wrapped;
}
bool FGameTexture::isUserContent() const bool FGameTexture::isUserContent() const
{ {
int filenum = fileSystem.GetFileContainer(wrapped.GetSourceLump()); int filenum = fileSystem.GetFileContainer(wrapped->GetSourceLump());
return (filenum > fileSystem.GetMaxIwadNum()); return (filenum > fileSystem.GetMaxIwadNum());
} }

View file

@ -205,7 +205,3 @@ public:
extern FTextureManager TexMan; extern FTextureManager TexMan;
inline FGameTexture* MakeGameTexture(FTexture* tex)
{
return reinterpret_cast<FGameTexture*>(tex);
}

View file

@ -640,121 +640,130 @@ public:
// Refactoring helper to allow piece by piece adjustment of the API // Refactoring helper to allow piece by piece adjustment of the API
class FGameTexture class FGameTexture
{ {
FTexture wrapped; FTexture *wrapped;
public: public:
FTexture* GetTexture() { return &wrapped; } FGameTexture(FTexture* wrap) : wrapped(wrap) {}
int GetSourceLump() const { return wrapped.GetSourceLump(); } ~FGameTexture();
void SetBrightmap(FGameTexture* tex) { wrapped.Brightmap = tex->GetTexture(); }
double GetDisplayWidth() /*const*/ { return wrapped.GetDisplayWidthDouble(); } FTexture* GetTexture() { return wrapped; }
double GetDisplayHeight() /*const*/ { return wrapped.GetDisplayHeightDouble(); } int GetSourceLump() const { return wrapped->GetSourceLump(); }
int GetTexelWidth() /*const*/ { return wrapped.GetTexelWidth(); } void SetBrightmap(FGameTexture* tex) { wrapped->Brightmap = tex->GetTexture(); }
int GetTexelHeight() /*const*/ { return wrapped.GetTexelHeight(); }
int GetTexelLeftOffset(int adjusted = 0) /*const*/ { return wrapped.GetTexelLeftOffset(adjusted); }
int GetTexelTopOffset(int adjusted = 0) /*const*/ { return wrapped.GetTexelTopOffset(adjusted); }
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(); } double GetDisplayWidth() /*const*/ { return wrapped->GetDisplayWidthDouble(); }
int isWarped() { return wrapped.isWarped(); } double GetDisplayHeight() /*const*/ { return wrapped->GetDisplayHeightDouble(); }
void SetWarpStyle(int style) { wrapped.bWarped = style; } int GetTexelWidth() /*const*/ { return wrapped->GetTexelWidth(); }
bool isMasked() { return wrapped.isMasked(); } int GetTexelHeight() /*const*/ { return wrapped->GetTexelHeight(); }
bool isHardwareCanvas() const { return wrapped.isHardwareCanvas(); } // There's two here so that this can deal with software canvases in the hardware renderer later. int GetTexelLeftOffset(int adjusted = 0) /*const*/ { return wrapped->GetTexelLeftOffset(adjusted); }
bool isSoftwareCanvas() const { return wrapped.isCanvas(); } int GetTexelTopOffset(int adjusted = 0) /*const*/ { return wrapped->GetTexelTopOffset(adjusted); }
bool isMiscPatch() const { return wrapped.GetUseType() == ETextureType::MiscPatch; } // only used by the intermission screen to decide whether to tile the background image or not. double GetDisplayLeftOffset(int adjusted = 0) /*const*/ { return wrapped->GetDisplayLeftOffsetDouble(adjusted); }
bool isMultiPatch() const { return wrapped.bMultiPatch; } double GetDisplayTopOffset(int adjusted = 0) /*const*/ { return wrapped->GetDisplayTopOffsetDouble(adjusted); }
bool isFullbrightDisabled() const { return wrapped.isFullbrightDisabled(); }
bool isFullbright() const { return wrapped.isFullbright(); } bool isValid() { return wrapped->isValid(); }
bool isFullNameTexture() const { return wrapped.bFullNameTexture; } int isWarped() { return wrapped->isWarped(); }
bool expandSprites() const { return wrapped.bExpandSprite; } void SetWarpStyle(int style) { wrapped->bWarped = style; }
bool useWorldPanning() const { return wrapped.UseWorldPanning(); } bool isMasked() { return wrapped->isMasked(); }
void SetWorldPanning(bool on) { wrapped.SetWorldPanning(on); } bool isHardwareCanvas() const { return wrapped->isHardwareCanvas(); } // There's two here so that this can deal with software canvases in the hardware renderer later.
bool allowNoDecals() const { return wrapped.allowNoDecals(); } bool isSoftwareCanvas() const { return wrapped->isCanvas(); }
void SetNoDecals(bool on) { wrapped.bNoDecals = on; } bool isMiscPatch() const { return wrapped->GetUseType() == ETextureType::MiscPatch; } // only used by the intermission screen to decide whether to tile the background image or not.
void SetTranslucent(bool on) { wrapped.bTranslucent = on; } bool isMultiPatch() const { return wrapped->bMultiPatch; }
ETextureType GetUseType() const { return wrapped.GetUseType(); } bool isFullbrightDisabled() const { return wrapped->isFullbrightDisabled(); }
void SetUseType(ETextureType type) { wrapped.SetUseType(type); } bool isFullbright() const { return wrapped->isFullbright(); }
int GetShaderIndex() const { return wrapped.shaderindex; } bool isFullNameTexture() const { return wrapped->bFullNameTexture; }
float GetShaderSpeed() const { return wrapped.GetShaderSpeed(); } bool expandSprites() const { return wrapped->bExpandSprite; }
uint16_t GetRotations() const { return wrapped.GetRotations(); } bool useWorldPanning() const { return wrapped->UseWorldPanning(); }
void SetRotations(int index) { wrapped.SetRotations(index); } void SetWorldPanning(bool on) { wrapped->SetWorldPanning(on); }
void SetSkyOffset(int ofs) { wrapped.SetSkyOffset(ofs); } bool allowNoDecals() const { return wrapped->allowNoDecals(); }
int GetSkyOffset() const { return wrapped.GetSkyOffset(); } void SetNoDecals(bool on) { wrapped->bNoDecals = on; }
FTextureID GetID() const { return wrapped.GetID(); } void SetTranslucent(bool on) { wrapped->bTranslucent = on; }
ISoftwareTexture* GetSoftwareTexture() { return wrapped.GetSoftwareTexture(); } ETextureType GetUseType() const { return wrapped->GetUseType(); }
void SetSoftwareTexture(ISoftwareTexture* swtex) { wrapped.SetSoftwareTextue(swtex); } void SetUseType(ETextureType type) { wrapped->SetUseType(type); }
void SetScale(DVector2 vec) { wrapped.SetScale(vec); } int GetShaderIndex() const { return wrapped->shaderindex; }
const FString& GetName() const { return wrapped.GetName(); } float GetShaderSpeed() const { return wrapped->GetShaderSpeed(); }
void SetShaderSpeed(float speed) { wrapped.shaderspeed = speed; } uint16_t GetRotations() const { return wrapped->GetRotations(); }
void SetShaderIndex(int index) { wrapped.shaderindex = index; } void SetRotations(int index) { wrapped->SetRotations(index); }
void SetSkyOffset(int ofs) { wrapped->SetSkyOffset(ofs); }
int GetSkyOffset() const { return wrapped->GetSkyOffset(); }
FTextureID GetID() const { return wrapped->GetID(); }
ISoftwareTexture* GetSoftwareTexture() { return wrapped->GetSoftwareTexture(); }
void SetSoftwareTexture(ISoftwareTexture* swtex) { wrapped->SetSoftwareTextue(swtex); }
void SetScale(DVector2 vec) { wrapped->SetScale(vec); }
const FString& GetName() const { return wrapped->GetName(); }
void SetShaderSpeed(float speed) { wrapped->shaderspeed = speed; }
void SetShaderIndex(int index) { wrapped->shaderindex = index; }
void SetShaderLayers(MaterialLayers& lay) void SetShaderLayers(MaterialLayers& lay)
{ {
// Only update layers that have something defind. // Only update layers that have something defind.
if (lay.Glossiness > -1000) wrapped.Glossiness = lay.Glossiness; if (lay.Glossiness > -1000) wrapped->Glossiness = lay.Glossiness;
if (lay.SpecularLevel > -1000) wrapped.SpecularLevel = lay.SpecularLevel; if (lay.SpecularLevel > -1000) wrapped->SpecularLevel = lay.SpecularLevel;
if (lay.Brightmap) wrapped.Brightmap = lay.Brightmap->GetTexture(); if (lay.Brightmap) wrapped->Brightmap = lay.Brightmap->GetTexture();
if (lay.Normal) wrapped.Normal = lay.Normal->GetTexture(); if (lay.Normal) wrapped->Normal = lay.Normal->GetTexture();
if (lay.Specular) wrapped.Specular = lay.Specular->GetTexture(); if (lay.Specular) wrapped->Specular = lay.Specular->GetTexture();
if (lay.Metallic) wrapped.Metallic = lay.Metallic->GetTexture(); if (lay.Metallic) wrapped->Metallic = lay.Metallic->GetTexture();
if (lay.Roughness) wrapped.Roughness = lay.Roughness->GetTexture(); if (lay.Roughness) wrapped->Roughness = lay.Roughness->GetTexture();
if (lay.AmbientOcclusion) wrapped.AmbientOcclusion = lay.AmbientOcclusion->GetTexture(); if (lay.AmbientOcclusion) wrapped->AmbientOcclusion = lay.AmbientOcclusion->GetTexture();
for (int i = 0; i < MAX_CUSTOM_HW_SHADER_TEXTURES; i++) for (int i = 0; i < MAX_CUSTOM_HW_SHADER_TEXTURES; i++)
{ {
if (lay.CustomShaderTextures[i]) wrapped.CustomShaderTextures[i] = lay.CustomShaderTextures[i]->GetTexture(); if (lay.CustomShaderTextures[i]) wrapped->CustomShaderTextures[i] = lay.CustomShaderTextures[i]->GetTexture();
} }
} }
float GetGlossiness() const { return wrapped.Glossiness; } float GetGlossiness() const { return wrapped->Glossiness; }
float GetSpecularLevel() const { return wrapped.SpecularLevel; } float GetSpecularLevel() const { return wrapped->SpecularLevel; }
void CopySize(FGameTexture* BaseTexture) void CopySize(FGameTexture* BaseTexture)
{ {
wrapped.CopySize(&BaseTexture->wrapped); wrapped->CopySize(BaseTexture->wrapped);
} }
// 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(); }
bool isAutoGlowing() const { return wrapped.isAutoGlowing(); } bool isAutoGlowing() const { return wrapped->isAutoGlowing(); }
int GetGlowHeight() const { return wrapped.GetGlowHeight(); } int GetGlowHeight() const { return wrapped->GetGlowHeight(); }
void SetAutoGlowing() { auto tex = GetTexture(); tex->bAutoGlowing = tex->bGlowing = tex->bFullbright = true; } void SetAutoGlowing() { auto tex = GetTexture(); tex->bAutoGlowing = tex->bGlowing = tex->bFullbright = true; }
void SetGlowHeight(int v) { wrapped.GlowHeight = v; } void SetGlowHeight(int v) { wrapped->GlowHeight = v; }
void SetFullbright() { wrapped.bFullbright = true; } void SetFullbright() { wrapped->bFullbright = true; }
void SetDisableFullbright(bool on) { wrapped.bDisableFullbright = on; } void SetDisableFullbright(bool on) { wrapped->bDisableFullbright = on; }
void SetGlowing(PalEntry color) { auto tex = GetTexture(); tex->bAutoGlowing = false; tex->bGlowing = true; tex->GlowColor = color; } void SetGlowing(PalEntry color) { auto tex = GetTexture(); tex->bAutoGlowing = false; tex->bGlowing = true; tex->GlowColor = color; }
bool isUserContent() const; bool isUserContent() const;
void AddAutoMaterials() { wrapped.AddAutoMaterials(); } void AddAutoMaterials() { wrapped->AddAutoMaterials(); }
int CheckRealHeight() { return wrapped.CheckRealHeight(); } int CheckRealHeight() { return wrapped->CheckRealHeight(); }
bool isSkybox() const { return wrapped.isSkybox(); } bool isSkybox() const { return wrapped->isSkybox(); }
void SetSize(int x, int y) { wrapped.SetSize(x, y); } void SetSize(int x, int y) { wrapped->SetSize(x, y); }
void SetDisplaySize(float w, float h) { wrapped.SetSize((int)w, (int)h); } void SetDisplaySize(float w, float h) { wrapped->SetSize((int)w, (int)h); }
void SetSpriteRect() { wrapped.SetSpriteRect(); } void SetSpriteRect() { wrapped->SetSpriteRect(); }
const SpritePositioningInfo& GetSpritePositioning(int which) { if (wrapped.spi == nullptr) wrapped.SetupSpriteData(); return wrapped.spi[which]; } const SpritePositioningInfo& GetSpritePositioning(int which) { if (wrapped->spi == nullptr) wrapped->SetupSpriteData(); return wrapped->spi[which]; }
int GetAreas(FloatRect** pAreas) const { return wrapped.GetAreas(pAreas); } int GetAreas(FloatRect** pAreas) const { return wrapped->GetAreas(pAreas); }
PalEntry GetSkyCapColor(bool bottom) { return wrapped.GetSkyCapColor(bottom); } PalEntry GetSkyCapColor(bool bottom) { return wrapped->GetSkyCapColor(bottom); }
bool GetTranslucency() bool GetTranslucency()
{ {
return wrapped.GetTranslucency(); return wrapped->GetTranslucency();
} }
// Since these properties will later piggyback on existing members of FGameTexture, the accessors need to be here. // Since these properties will later piggyback on existing members of FGameTexture, the accessors need to be here.
FGameTexture *GetSkyFace(int num) FGameTexture *GetSkyFace(int num)
{ {
return (isSkybox() ? static_cast<FSkyBox*>(&wrapped)->faces[num] : nullptr); return (isSkybox() ? static_cast<FSkyBox*>(wrapped)->faces[num] : nullptr);
} }
bool GetSkyFlip() { return isSkybox() ? static_cast<FSkyBox*>(&wrapped)->fliptop : false; } bool GetSkyFlip() { return isSkybox() ? static_cast<FSkyBox*>(wrapped)->fliptop : false; }
int GetClampMode(int clampmode) int GetClampMode(int clampmode)
{ {
if (GetUseType() == ETextureType::SWCanvas) clampmode = CLAMP_NOFILTER; if (GetUseType() == ETextureType::SWCanvas) clampmode = CLAMP_NOFILTER;
else if (isHardwareCanvas()) clampmode = CLAMP_CAMTEX; else if (isHardwareCanvas()) clampmode = CLAMP_CAMTEX;
else if ((isWarped() || wrapped.shaderindex >= FIRST_USER_SHADER) && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE; else if ((isWarped() || wrapped->shaderindex >= FIRST_USER_SHADER) && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE;
return clampmode; return clampmode;
} }
}; };
inline FGameTexture* MakeGameTexture(FTexture* tex)
{
if (!tex) return nullptr;
return new FGameTexture(tex);
}
#endif #endif