reepblue Posted October 22, 2023 Share Posted October 22, 2023 It seems I can't generate a texture without the editor also making a normal map for each texture which I do not want. I decided to make an extension that would convert the image to a DDS using the code found below. But I'm now getting the "Mipchain contains mipmaps with dimensions smaller than the format's block size" error. How would I fix my code? local extension = {} function CreateNewMaterial() local defaultpath = CurrentDir().."Materials/" local file = RequestFile("Select Material Location", defaultpath, "Ultra Engine Material File (*.mat):mat", 0, true) if file ~= nil then local mat = CreateMaterial() if mat ~= nil then mat:SetColor(1,1,1,1) local shaderfamily = LoadShaderFamily("Shaders/PBR.fam") if shaderfamily then mat:SetShaderFamily(shaderfamily) shaderfamily = nil end mat:Save(file); end end end function GenerateTexture() local defaultpath = CurrentDir().."Materials/" local file = RequestFile("Select Image", defaultpath, "Image:png,tga,jpg,jpeg,bmp", 0, false) --Load image local pixmap = LoadPixmap(file) if pixmap==nil then Print("Error: Failed to generate texture " ..file) return end local mipchain = {} table.insert(mipchain,pixmap) --Generate mipmaps local w = pixmap.size.x local h = pixmap.size.y local mipmap = pixmap while (w > 1 and h > 1) do w = math.max(1, w / 2) h = math.max(1, h / 2) mipmap = mipmap:Resize(w,h) table.insert(mipchain,mipmap) end --Convert each image to BC7 compression for n=1, #mipchain do mipchain[n] = mipchain[n]:Convert(TEXTURE_BC7) end --Save mipchain to texture file local output = StripExt(file)..".dds" SaveTexture(output, TEXTURE_2D, mipchain, 1, SAVE_DEFAULT) end function extension.hook(event, extension) if event.id == EVENT_WIDGETACTION then if event.source == extension.menuitem_newmaterial then CreateNewMaterial() elseif event.source == extension.menuitem_newDDS then GenerateTexture() end end end -------------------------------------------------------------------- -- Add menu item -------------------------------------------------------------------- local menu = program.menu:FindChild("Scripting", false) if menu == nil then Print("Error: Could not find \"Scripting\" menu.") return end local submenu = menu:FindChild("Utilities", false) if submenu == nil then submenu = CreateMenu("Utilities", menu) end extension.menuitem_newmaterial = CreateMenu("Create blank material", submenu) extension.menuitem_newDDS = CreateMenu("Convert image to DDS", submenu) ListenEvent(EVENT_WIDGETACTION, extension.menuitem_newmaterial, extension.hook, extension) ListenEvent(EVENT_WIDGETACTION, extension.menuitem_newDDS, extension.hook, extension) 1 Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
Josh Posted October 22, 2023 Share Posted October 22, 2023 If you are using a compressed texture format then the smallest mipmap should be 4x4. while (w > 4 and h > 4) do w = math.max(4, w / 2) h = math.max(4, h / 2) mipmap = mipmap:Resize(w,h) table.insert(mipchain,mipmap) end 18 minutes ago, reepblue said: It seems I can't generate a texture without the editor also making a normal map for each texture which I do not want. I don't understand this. 1 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
reepblue Posted October 22, 2023 Author Share Posted October 22, 2023 19 minutes ago, Josh said: If you are using a compressed texture format then the smallest mipmap should be 4x4. while (w > 4 and h > 4) do w = math.max(4, w / 2) h = math.max(4, h / 2) mipmap = mipmap:Resize(w,h) table.insert(mipchain,mipmap) end I don't understand this. Everytime I right click on a PNG image to generate a material, it creates the DDS and a normal map. I just want to simply convert the image to a texture. Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
Josh Posted October 22, 2023 Share Posted October 22, 2023 You can open the PNG file in the asset window, select the File > Save As menu item, and choose DDS as the save file type. 1 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
reepblue Posted October 22, 2023 Author Share Posted October 22, 2023 I guess I'm just so used making textures in Leadwerks. That makes my life easier! Code is still useful regardless. Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
reepblue Posted October 23, 2023 Author Share Posted October 23, 2023 It works better as a converter. Works exactly how Leadwerks behaves. I understand the reason for texture creation for being manual since DDS doesn't cover all needs. local converter = {} converter.informat = "png" converter.outformat = "dds" function converter:Convert(path, output) --Load image local pixmap = LoadPixmap(path) if pixmap==nil then Print("Error: Failed to generate texture " ..path) return false end local mipchain = {} table.insert(mipchain,pixmap) --Generate mipmaps local w = pixmap.size.x local h = pixmap.size.y local mipmap = pixmap while (w > 4 and h > 4) do w = math.max(4, w / 2) h = math.max(4, h / 2) mipmap = mipmap:Resize(w,h) table.insert(mipchain,mipmap) end --Convert each image to BC1 (DXT1) compression for n=1, #mipchain do mipchain[n] = mipchain[n]:Convert(TEXTURE_BC1) end --Save mipchain to texture file SaveTexture(output, TEXTURE_2D, mipchain, 1, SAVE_DEFAULT) return true end program:AddConverter(converter) Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
reepblue Posted October 23, 2023 Author Share Posted October 23, 2023 Revisited my extension to generate basic materials from images and textures. This is good if you want non-game image formats part of your file blacklist. It was very helpful with the conversion script above to convert ten or so basic textures. local extension = {} function extension:CreateBlankMaterial() local defaultpath = CurrentDir().."/Materials/" local file = RequestFile("Select Material Location", defaultpath, "Ultra Engine Material File (*.mat):mat", 0, true) if file ~= nil then local mat = CreateMaterial() if mat ~= nil then mat:SetColor(1,1,1,1) local shaderfamily = LoadShaderFamily("Shaders/PBR.fam") if shaderfamily then mat:SetShaderFamily(shaderfamily) shaderfamily = nil end mat:Save(file); end end end function extension:Image2DDS(path) --Load image local pixmap = LoadPixmap(path) if pixmap==nil then Print("Error: Failed to generate texture \"" .. FixPath(output) .. "\"") return false end local mipchain = {} table.insert(mipchain,pixmap) --Generate mipmaps local w = pixmap.size.x local h = pixmap.size.y local mipmap = pixmap while (w > 4 and h > 4) do w = math.max(4, w / 2) h = math.max(4, h / 2) mipmap = mipmap:Resize(w,h) table.insert(mipchain,mipmap) end --Convert each image to BC1 (DXT1) compression for n=1, #mipchain do mipchain[n] = mipchain[n]:Convert(TEXTURE_BC1) end --Save mipchain to texture file local output = StripExt(path)..".dds" SaveTexture(output, TEXTURE_2D, mipchain, 1, SAVE_DEFAULT) return output end function extension:GenerateMaterialFromTexture() local defaultpath = CurrentDir().."/Materials/" local file = RequestFile("Select Texture", defaultpath, "Supported Files:dds,basis,png,jpg,jpeg,tga,bmp", 0) -- If we're not a texture, convert it if (ExtractExt(file) == "png" or ExtractExt(file) == "jpg" or ExtractExt(file) == "jpeg" or ExtractExt(file) == "tga" or ExtractExt(file) == "bmp") then local image = file file = extension:Image2DDS(image) end local output = StripExt(file)..".mat" if file ~= nil then local mat = CreateMaterial() if mat ~= nil then local tex = LoadTexture(file) if tex~=nil then mat:SetTexture(tex) mat:SetColor(1,1,1,1) local shaderfamily = LoadShaderFamily("Shaders/PBR.fam") if shaderfamily then mat:SetShaderFamily(shaderfamily) shaderfamily = nil end if mat:Save(output) then Print("Successfully saved \"" .. output .. "\"") end else Print("Failed to save \"" .. output .. "\" as texture is invaild!") end end mat = nil else Print("Failed to save \"" .. output .. "\" as file is invaild!") end end function extension.hook(event, extension) if event.id == EVENT_WIDGETACTION then if event.source == extension.menuitem_blankmaterial then extension:CreateBlankMaterial() elseif event.source == extension.menuitem_matfromtex then extension:GenerateMaterialFromTexture() end end end -------------------------------------------------------------------- -- Add menu item -------------------------------------------------------------------- local menu = program.menu:FindChild("Scripting", false) if menu == nil then Print("Error: Could not find \"Scripting\" menu.") return end local submenu = menu:FindChild("Generate Material", false) if submenu == nil then submenu = CreateMenu("Generate Material", menu) end extension.menuitem_blankmaterial = CreateMenu("New Blank Material", submenu) extension.menuitem_matfromtex = CreateMenu("New Material From Texture/Image", submenu) ListenEvent(EVENT_WIDGETACTION, extension.menuitem_blankmaterial, extension.hook, extension) ListenEvent(EVENT_WIDGETACTION, extension.menuitem_matfromtex, extension.hook, extension) 2 Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.