Jump to content

reepblue

Developers
  • Posts

    2,500
  • Joined

  • Last visited

Posts posted by reepblue

  1. This simple application will scan your Components directory and create a function that'll register all your components in the engine. Use this in your Pre-Build event and then call the RegisterComponents() on top of your main entry. 

    I didn't battle test this yet, but it seems to work. 

    You are free to fork it, improve it, etc via GitHub

    You can download the exe here.

    • Like 3
  2. 14 minutes ago, Josh said:

    Your little command language looks cool. This is probably more useful than exposing full Lua programming.

    What are the extents/limitations of the syntax? Is it just "command arg1, arg2, arg3?"

    One of the things I don't like is that you need to cut the full line of text by spaces every time. The system I had for Cyclone only had the arguments available in a vector.  This is a limitation of the Event System, but having it event based makes commands less static and it's way easier to do component based commands.

    One thing I still don't like thats in both systems is you need to do size checks on the argument vector before using it to prevent crashing. Other than that, it's a canvas for the programmer to do whatever they need done. 

  3. Although cxxopts looks interesting, I wanted to stay exclusive to the engine's API for this. I didn't want to do anything that could/would change the workflow of how things are normally done with the engine.

    I might consider separating the logs by type though, I already have it sorted by colors at this point. 

  4. Move the camera to the bottom edge of the framebuffer. 0,0 should be the top left of the screen. Then you can use the size of the framebuffer to position the sprite wherever you want like if you were using the Interface class. 

    local size = framebuffer:GetSize()
    cam2:SetPosition(size.x * 0.5, size.y * 0.5f)

     

  5. You're not setting your cam2 or your sprite to a new render layer.

    Not much of a Lua user, but try this.

    --Get the displays
    local displays = GetDisplays()
    
    --Create window
    local window = CreateWindow("Ultra Engine", 0, 0, 1280, 720, displays[1])
    
    --Create framebuffer
    local framebuffer = CreateFramebuffer(window)
    
    --Create world
    local world = CreateWorld()
    
    --env map
    local specmap = LoadTexture("./Materials/Environment/Default/specular.dds")
    local diffmap = LoadTexture("./Materials/Environment/Default/diffuse.dds")
    world:SetEnvironmentMap(specmap, ENVIRONMENTMAP_BACKGROUND)
    world:SetEnvironmentMap(specmap, ENVIRONMENTMAP_SPECULAR)
    world:SetEnvironmentMap(diffmap, ENVIRONMENTMAP_DIFFUSE)
    
    --[[load map
    local mapname = "Maps/scene1.ultra"
    local cl = CommandLine()
    if type(cl["map"]) == "string" then mapname = cl["map"] end
    local scene = LoadMap(world, mapname)
    --]]
    
    --Create light
    local light = CreateBoxLight(world)
    light:SetRange(-10, 10)
    light:SetArea(15, 15)
    light:SetRotation(45, 35, 0)
    light:SetColor(2)
    
    --Load a font
    local font = LoadFont("Fonts/arial.ttf")
    local fontsize = 36
    
    
    -- Create a camera
    local camera = CreateCamera(world,PROJECTION_PERSPECTIVE)
    camera:SetClearColor(0.125)
    camera:SetPosition(0, 5, 0)
    
    --Create second camera
    local cam2 = CreateCamera(world,PROJECTION_ORTHOGRAPHIC)
    cam2:SetPosition(0, 0, 0)
    cam2:SetClearMode(CLEAR_DEPTH)
    cam2:SetRenderLayers(1)
    
    -- Create sprite
    local sprite = CreateSprite(world, font,"HEY YOU !",fontsize) 
    sprite:SetColor(1, 1, 1, 1)
    sprite:SetPosition(0, 0, 0)
    sprite:SetRenderLayers(1)
    
    --Camera controls to look around
    require 'Components/Player/CameraControls'
    camera:AddComponent(CameraControls)
    
    --main loop
    while not window:KeyDown(KEY_ESCAPE) do 
        world:Update()
        world:Render(framebuffer)
    end

    This should spawn the sprite in the center of the screen.

  6. Was playing with this. This truly makes it super easy to get skyboxes into Ultra Engine! 

    If you place the extension within the Engine's Tool Directory, you can use this script to launch the application right from the editor which is much more convenient.

    --[[
        This extention is intended to be used with Klepto2's PBR Texture Generator
        https://www.ultraengine.com/community/topic/62344-pbr-texture-generator/
    ]]--
    local extension = {}
    extension.toolpath = "/Tools/PBRTextureGen/UltraPBRTextureGen.exe"
    
    function extension.hook(event, extension)
        if event.id == EVENT_WIDGETACTION then
            RunFile(AppDir()..extension.toolpath)
        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
    
    if menu ~= nil then
        local submenu = menu:FindChild("Generate", false)
        if submenu == nil then
            submenu = CreateMenu("Generate", menu)
        end
        extension.menuitem = CreateMenu("PBR Texture Generator", submenu)
    end
    
    ListenEvent(EVENT_WIDGETACTION, extension.menuitem, extension.hook, extension)

     

    • Like 3
  7. One thing I noticed when making an extension to the editor is that Windows gets really annoying when saving anything manually to the Program Files folder. Another thing is that you may want certain extensions for specific projects. 

    Maybe move "global" extensions to the user Documents folder, and then have the editor also read extensions within the project folder if it doesn't already. 

    On that note, I also think the blacklist filter should also be extended to be project based with an entry defined within the Ultra.json file. Maybe I don't want to see .dds files in a project that I want to use .basis files, etc.

  8. I didn't want to make a new topic for this but when are the brush measurement information coming back while the brush is being created? I forgot to put that on my list in the opening post. I assumed it was on the back burner because you wanted to think about how to render the text in 3D. 

    • Upvote 1
  9. 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)

     

    • Like 2
  10. 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)

     

  11. 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. 

  12. 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)
    

     

    • Like 1
  13. I've noticed that if you jump into a wall, the velocity distributes into forward movement. However, this makes climbing the stack of boxes in the start map difficult as I keep falling off. I think the player physics needs to be tweaked so I can climb the boxes while the controller still feeling natural.  

  14. 8 minutes ago, Josh said:

    This might be useful to you:
    https://github.com/UltraEngine/IBLSampler

    My copy of the cli.exe program compiled from this project was compressed with UPX and now Windows is aggressively deleting the EXE. I was not able to recompile it...it requires a lot of external libraries and I don't think this project is actively maintained. So I wrote the program linked to above to do the same thing, although it is not very polished:
    https://github.com/KhronosGroup/glTF-IBL-Sampler

    I used this to generate the new default skybox / reflection maps.

    It seems to me with a little elbow grease, this can be converted into a tool in which an extension can be written to use to generate hdr cubemaps.

×
×
  • Create New...