diff --git a/source/common/rendering/hwrenderer/data/hw_renderstate.h b/source/common/rendering/hwrenderer/data/hw_renderstate.h index 2ff77c53d..1f5e08d4c 100644 --- a/source/common/rendering/hwrenderer/data/hw_renderstate.h +++ b/source/common/rendering/hwrenderer/data/hw_renderstate.h @@ -625,6 +625,7 @@ private: public: void SetMaterial(FGameTexture* tex, EUpscaleFlags upscalemask, int scaleflags, int clampmode, int translation, int overrideshader) { + tex->setSeen(); if (!sysCallbacks.PreBindTexture || !sysCallbacks.PreBindTexture(this, tex, upscalemask, scaleflags, clampmode, translation, overrideshader)) { if (shouldUpscale(tex, upscalemask)) scaleflags |= CTF_Upscale; diff --git a/source/common/textures/gametexture.h b/source/common/textures/gametexture.h index 4a1d4d2f3..814d14702 100644 --- a/source/common/textures/gametexture.h +++ b/source/common/textures/gametexture.h @@ -61,6 +61,7 @@ enum EGameTexFlags GTexf_AutoMaterialsAdded = 256, // AddAutoMaterials has been called on this texture. GTexf_OffsetsNotForFont = 512, // The offsets must be ignored when using this texture in a font. GTexf_NoTrim = 1024, // Don't perform trimming on this texture. + GTexf_Seen = 2024, // Set to true when the texture is being used for rendering. Must be cleared manually if the check is needed. }; struct FMaterialLayers @@ -185,6 +186,13 @@ public: void SetRotations(int rot) { Rotations = int16_t(rot); } void SetSkyOffset(int offs) { SkyOffset = offs; } int GetSkyOffset() const { return SkyOffset; } + void setSeen() { flags |= GTexf_Seen; } + bool isSeen(bool reset) + { + int v = flags & GTexf_Seen; + if (reset) flags &= ~GTexf_Seen; + return v; + } ISoftwareTexture* GetSoftwareTexture() { diff --git a/source/core/textures/buildtiles.cpp b/source/core/textures/buildtiles.cpp index 5aec9f331..74fc23ce0 100644 --- a/source/core/textures/buildtiles.cpp +++ b/source/core/textures/buildtiles.cpp @@ -393,29 +393,14 @@ FGameTexture* BuildTiles::ValidateCustomTile(int tilenum, ReplacementType type) // B) the pin display in Redneck Rampage's bowling lanes. // C) Exhumed's menu plus one special effect tile. if (tile->GetTexelWidth() == 0 || tile->GetTexelHeight() == 0) return nullptr; // The base must have a size for this to work. - // todo: invalidate hardware textures for tile. replacement = new FImageTexture(new FRestorableTile(tile->GetTexture()->GetImage())); } else if (type == ReplacementType::Canvas) { - // necessary fuckery thanks to SW considering camera textures the same as mirrors and deleting them if opportune. - // If we do not remember them this would create new ones over and over again. - auto check = cameratextures.CheckKey(tilenum); - if (check) - { - // if this once was a camera texture but now isn't anymore, grab that camera texture from the cache and reuse it. - AddTile(tilenum, *check); - return *check; - } - replacement = new FCanvasTexture(1, 1); } else return nullptr; auto rep = MakeGameTexture(replacement, tile->GetName(), ETextureType::Override); - if (type == ReplacementType::Canvas) - { - cameratextures.Insert(tilenum, rep); - } AddTile(tilenum, rep); return rep; } diff --git a/source/core/textures/buildtiles.h b/source/core/textures/buildtiles.h index 681f265df..0de3db504 100644 --- a/source/core/textures/buildtiles.h +++ b/source/core/textures/buildtiles.h @@ -303,7 +303,6 @@ struct BuildTiles TileDesc tiledata[MAXTILES]; TArray addedArt; TArray maptilesadded; - TMap cameratextures; TMap nametoindex; bool locked; // if this is true, no more tile modifications are allowed. diff --git a/source/games/sw/src/jsector.cpp b/source/games/sw/src/jsector.cpp index 024427d6c..4c3e94087 100644 --- a/source/games/sw/src/jsector.cpp +++ b/source/games/sw/src/jsector.cpp @@ -480,29 +480,18 @@ void JS_DrawCameras(PLAYER* pp, const DVector3& campos, double smoothratio) { if (!mirror[cnt].ismagic) continue; // these are definitely not camera textures. - if (testgotpic(cnt + MIRRORLABEL) || ((unsigned)mirror[cnt].campic < MAXTILES && testgotpic(mirror[cnt].campic))) + auto tex = tileGetTexture(mirror[cnt].campic); + if (tex && tex->isSeen(true)) { - // Do not change any global state here! - bIsWallMirror = testgotpic(cnt + MIRRORLABEL); - - DVector2 vec; - if (bIsWallMirror) - { - vec = mirror[cnt].mirrorWall->pos - campos.XY(); - } - else - { - DSWActor* camactor = mirror[cnt].camspriteActor; - - vec = camactor->spr.pos - campos.XY(); - } + DSWActor* camactor = mirror[cnt].camspriteActor; + DVector2 vec = camactor->spr.pos - campos.XY(); dist = abs(vec.X) + abs(vec.Y); short w; - DSWActor *camactor = mirror[cnt].cameraActor; - assert(camactor); + camactor = mirror[cnt].cameraActor; + if (!camactor) continue; // Calculate the angle of the mirror wall auto wal = mirror[cnt].mirrorWall;