Facepunch / garrysmod-requests

Feature requests for Garry's Mod
86 stars 24 forks source link

Deleting cached textures #2463

Open cat-marislav opened 2 months ago

cat-marislav commented 2 months ago

The ITexture generated by calling Material() with a png/jpg file gets cached and can't be deleted afterwards. If I were to create an IMaterial object with a certain png file, then replace that png file with another one that has the same name, the ITexture will not be replaced upon recalling the Material() function. This will cause the material to have incorrect width and height, for example. A few things to note:

robotboy655 commented 2 months ago

First of all, I question what you are trying to do in the first place. If you are replacing the $basetexture of a loaded .png/.jpg file, why are you not just using CreateMaterial() instead? You really shouldn't be modifying those materials.

Secondly, I am unable to reproduce the issue you describe. image

Please provide minimal code to reproduce the issue you describe.

As for the removal of cached textures, they are removed automatically when they are no longer used.

local mat = Material( "icon16/monkey.png" )
print(mat, mat:Width(), mat:Height() )

local ma2t = Material( "gm_construct/construct_concrete_ground" )
mat:SetTexture( "$basetexture", ma2t:GetTexture( "$basetexture" ) )
print(mat, mat:Width(), mat:Height() )
cat-marislav commented 2 months ago

I am not replacing the $basetexture of materials loaded with Material(), I am in fact using CreateMaterial(). What I am trying to do in a nutshell is create a UI that allows users to save some png/vtf/jpg files in the data folder under a chosen name for later usage. The user can also delete existing files if he wants, which is where the problem comes in: if a player were to remove a file named "test.png", for instance, and then replace it with another "test.png" that has different contents, he will run into an issue. Here are the steps required to reproduce this issue:

After following these steps, you will notice that the texture drawn in the top left corner has not been replaced with the new one, and obviously the :Width() and :Height() functions return values corresponding to the old texture. Calling :Recompute() on the IMaterial or :Download() on the ITexture do not change much, apart from maybe messing up the original texture a bit. Attempting to recreate the ITexture by calling Material() is not helpful since the texture has been cached. Removing the rendering hook for a while to make the cached texture automatically disappear (as it is no longer in use) doesn't work neither.

Update: Apparently replacing a file with the one that has the same name and extension does update the texture, but :Width() and :Height() will still return old values. In order to get the same issue as above, the old and new files should have the same name, but different extensions (test.jpg and test.png, for instance).