• Use a jpg/png file that is located in the data folde as a material for entities?
    11 replies, posted
I don't know if its possible but I am trying to use a jpg/png file that is located in the data folder as a material that can be used on entities. I've been able to get it to show on your screen like a HUD, but I can't seem to get it to work on entities. I would apprecaiate it if anyone could guide me in the right direction. Thank you! local params = {     ["$basetexture"] = Material("../data/slob.png"):GetTexture("$basetexture"),     ["$nodecal"] = 1,     ["$model"] = 1,     ["$additive"] = 1,     ["$nocull"] = 1,     Proxies = {         TextureScroll = {             texturescrollvar = "$basetexturetransform",             texturescrollrate = 33.3,             texturescrollangle = 60,         }     } } local new_material = CreateMaterial("MyMaterial","VertexLitGeneric",params); for k, v in pairs(ents.GetAll()) do   v:SetMaterial(Material("MyMaterial")) end
As documented on the wiki - Unlike IMaterial:SetTexture, this table will not accept ITexture values. Instead, use the texture's name (see ITexture:GetName) To do this, put the path to your file inside Material and then use GetName on that to grab it: local pngMat = Material("slob.png"):GetName() Then we replace the "slob.png" part with that value: CreateMaterial("pleasework", "VertexLitGeneric", { ["$basetexture"] = pngMat, -- Use it here! ["$model"] = 1, }) Instead of defining our material name above, we can also do this: CreateMaterial("pleasework", "VertexLitGeneric", { ["$basetexture"] = Material("slob.png"):GetName(), -- Instead of defining the variable above ["$model"] = 1, }) for k, v in pairs(ents.GetAll()) do v:SetMaterial("!pleasework") v:SetSubMaterial( 0, "!pleasework") end Testing my own willy.png CreateMaterial("willy", "VertexLitGeneric", {     ["$basetexture"] = Material("willy.png"):GetName(),     ["$model"] = 1,  }) for k, v in pairs(ents.GetAll()) do     v:SetMaterial("!willy")     v:SetSubMaterial( 0, "!willy") end
I wonder if there's any reason not to just make every texture in a content heavy gamemode a png. Pngs are so much smaller than VTFs
Thank you so much for the thorough reply! Is it possible to fetch a png file that is located in the data directory and use it in this method? I'll try playing around more with it now. Thank you again!
Yep. You can simply just switch out Material("slob.png") --> Material("data/filename.png") You can use "../data/filename.png" if you really want to, but it's not necessary.
Pngs are much small because they are compressed. VTF uncompressed so they are faster. It's a pretty minimal speed difference so unless your optimizing for completly potato computers you're better off with PNGs because you can save a lot of bandwidth.
Thank you so much! I was dumbfounded to do that as I was using ../ (data/) for old methods I was using and thought it wouldn't work. So I thought to myself reading the png file with file.Read and use it like that but it didn't seem to work. However, your method did! Thank you again so much! If I may ask another question on this thread, is there a way to reload all materials? The reason behind it is because when a player joins the server, an http request gets sent and downloads a few png files in the data directory. Say I have an entity that is set to a material called '!example'. I would set the entities material to 'ENT:SetSubMaterial(0, '!example'). This works if the player already has the material but he would have to rejoin the server. The entity sets its material to '!example' before the material is even created. How would I reload all the materials so it would show for the player without rejoining? I'm still new at LUA so I apologize for stupid questions,
VTF's allows some tricky effects (e.g. from the alpha-level) and animations, that the engine can use. But other then that; You could use CreateMaterial convert pngs for use in-game. And save a lot of space. You can't "recreate" a material after it's created with CreateMaterial. Once its created, it can't be destroyed. You can create a new one with another name, but a better solution to dynamic materials, would be RenderTargets. There is a guide on the old wiki. However RenderTargets are advanced and will crash if it errors in-between the rendering.
I understand that. I'd really like to continue doing it the way I've been doing it. The only problem I'm having now is that when a player joins the server, he sees the material. If that player rejoins the server, its a missing purple texture error. If the player restarts his game and rejoins, the materials there.
im having the same problem
I recorded what happens - and the code I use is below the video. A player joins the server(I have code that downloads the .png files into their data folder), it works. If that player rejoins the server, doesn't work. They would have to restart their game in order to see the materials again. -- lua/autorun/client concommand.Add('setmat', function(ply, cmd, args)   CreateMaterial('work', "VertexLitGeneric", {       ["$basetexture"] = Material('data/mat/bob.png'):GetName(), -- tried using materials/ folder instead but same issue happens       ["$model"] = 1,   })   for k, v in pairs(ents.GetAll()) do     v:SetMaterial('!work')     v:SetSubMaterial(0, '!work')   end end)
Material:GetName() Won't work GetName returns the or path. Gmod generates a material from a png when using the Material function. You need to get the basetexture it generated. Aka Material("mypng.png"):GetTexture("$basetexture")
Sorry, you need to Log In to post a reply to this thread.