diff --git a/.gitmodules b/.gitmodules
index d0bc96a..3a8c2ee 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -34,3 +34,6 @@
[submodule "vendor/ImGui.NET"]
path = vendor/ImGui.NET
url = https://github.com/aharabada/ImGui.NET.git
+[submodule "GlitchyEngine/vendor/Ultralight-beef"]
+ path = GlitchyEngine/vendor/Ultralight-beef
+ url = git@github.com:kumikumi/Ultralight-beef.git
diff --git a/BeefSpace.toml b/BeefSpace.toml
index b696ccc..ebc3dd2 100644
--- a/BeefSpace.toml
+++ b/BeefSpace.toml
@@ -1,5 +1,5 @@
FileVersion = 1
-Projects = {GlitchyEngine = {Path = "GlitchyEngine"}, GlitchLog = {Path = "GlitchLog"}, DirectX = {Path = "GlitchyEngine/vendor/directx/DirectX"}, LodePng = {Path = "vendor/lodepng-beef/lodepng-beef"}, FreeType = {Path = "GlitchyEngine/vendor/freetype"}, cgltf-beef = {Path = "GlitchyEngine/vendor/gltf/cgltf-beef"}, GlitchyEditor = {Path = "GlitchyEditor"}, msdfgen-beef = {Path = "GlitchyEngine/vendor/msdfgen/msdfgen-beef"}, ImGui = {Path = "GlitchyEngine/vendor/imgui/ImGui"}, ImGuiImplDX11 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplDX11"}, ImGuiImplWin32 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplWin32"}, ImGuizmo = {Path = "GlitchyEngine/vendor/imgui/ImGuizmo"}, GlitchyEngineHelper = {Path = "GlitchyEngineHelper"}, bon = {Path = "GlitchyEngine/vendor/bon"}, box2d-beef = {Path = "GlitchyEngine/vendor/box2D"}, "Beef.Linq" = {Path = "GlitchyEngine/vendor/Beef.Linq/src"}, ScriptCore = {Path = "ScriptCore"}}
+Projects = {GlitchyEngine = {Path = "GlitchyEngine"}, GlitchLog = {Path = "GlitchLog"}, DirectX = {Path = "GlitchyEngine/vendor/directx/DirectX"}, LodePng = {Path = "vendor/lodepng-beef/lodepng-beef"}, FreeType = {Path = "GlitchyEngine/vendor/freetype"}, cgltf-beef = {Path = "GlitchyEngine/vendor/gltf/cgltf-beef"}, GlitchyEditor = {Path = "GlitchyEditor"}, msdfgen-beef = {Path = "GlitchyEngine/vendor/msdfgen/msdfgen-beef"}, ImGui = {Path = "GlitchyEngine/vendor/imgui/ImGui"}, ImGuiImplDX11 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplDX11"}, ImGuiImplWin32 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplWin32"}, ImGuizmo = {Path = "GlitchyEngine/vendor/imgui/ImGuizmo"}, GlitchyEngineHelper = {Path = "GlitchyEngineHelper"}, bon = {Path = "GlitchyEngine/vendor/bon"}, box2d-beef = {Path = "GlitchyEngine/vendor/box2D"}, "Beef.Linq" = {Path = "GlitchyEngine/vendor/Beef.Linq/src"}, ScriptCore = {Path = "ScriptCore"}, Ultralight = {Path = "GlitchyEngine/vendor/Ultralight-beef"}}
WorkspaceFolders = {GlitchyEngine = ["GlitchyEngine", "GlitchLog", "GlitchyEngineHelper", "ScriptCore"], "GlitchyEngine/Dependencies" = ["cgltf-beef", "DirectX", "FreeType", "ImGui", "ImGuiImplDX11", "ImGuiImplWin32", "ImGuizmo", "LodePng", "msdfgen-beef", "bon", "box2d-beef", "Beef.Linq"]}
[Workspace]
diff --git a/GlitchyEditor/BeefProj.toml b/GlitchyEditor/BeefProj.toml
index 2cd40b7..2dcd795 100644
--- a/GlitchyEditor/BeefProj.toml
+++ b/GlitchyEditor/BeefProj.toml
@@ -1,5 +1,5 @@
FileVersion = 1
-Dependencies = {corlib = "*", GlitchLog = "*", GlitchyEngine = "*"}
+Dependencies = {corlib = "*", GlitchLog = "*", GlitchyEngine = "*", Ultralight = "*"}
[Project]
Name = "GlitchyEditor"
diff --git a/GlitchyEditor/src/EditorApp.bf b/GlitchyEditor/src/EditorApp.bf
index fc4a13d..ddf8c68 100644
--- a/GlitchyEditor/src/EditorApp.bf
+++ b/GlitchyEditor/src/EditorApp.bf
@@ -18,6 +18,7 @@ namespace GlitchyEditor
Log.EngineLogger = new EditorLogger() { IsEngineLogger = true };
PushLayer(new EditorLayer(args, _contentManager));
+ PushLayer(new UltralightLayer());
}
protected override IContentManager InitContentManager()
diff --git a/GlitchyEditor/src/UltralightLayer.bf b/GlitchyEditor/src/UltralightLayer.bf
new file mode 100644
index 0000000..326596f
--- /dev/null
+++ b/GlitchyEditor/src/UltralightLayer.bf
@@ -0,0 +1,207 @@
+using System;
+using GlitchyEngine;
+using Ultralight.CAPI;
+
+namespace GlitchyEditor;
+
+class UltralightLayer : Layer
+{
+ public const String htmlString =
+ """
+
+
+
+
+
+
+
Hello World!
+
Welcome to Ultralight!
+
+
+
+ """;
+
+ public this()
+ {
+ RenderToPng();
+ }
+
+ private static bool done = false;
+
+ private static void onFinishLoading(void* user_data, ULView caller,
+ uint64 frame_id, bool is_main_frame, ULString url)
+ {
+ ///
+ /// Our page is done when the main frame is finished loading.
+ ///
+ if (is_main_frame)
+ {
+ ///
+ /// Set our done flag to true to exit the Run loop.
+ ///
+ done = true;
+ }
+ }
+
+ private void RenderToPng()
+ {
+ ///
+ /// Setup our config. The config can be used to customize various
+ /// options within the renderer and WebCore module.
+ ///
+ /// Our config uses 2x DPI scale and "Arial" as the default font.
+ ///
+ ULConfig config = ulCreateConfig();
+
+ ulConfigSetDeviceScale(config, 2.0);
+
+ ULString font_family = ulCreateString("Arial");
+ ulConfigSetFontFamilyStandard(config, font_family);
+ ulDestroyString(font_family);
+
+ ///
+ /// We need to tell config where our resources are so it can load our
+ /// bundled certificate chain and make HTTPS requests.
+ ///
+ ULString resource_path = ulCreateString("./resources/");
+ ulConfigSetResourcePath(config, resource_path);
+ ulDestroyString(resource_path);
+
+ ///
+ /// Make sure the GPU renderer is disabled so we can render to an offscreen
+ /// pixel buffer surface. (This is disabled by default, so not needed here)
+ ///
+ ulConfigSetUseGPURenderer(config, false);
+
+ ///
+ /// Use AppCore's font loader singleton to load fonts from the OS.
+ ///
+ ulEnablePlatformFontLoader();
+
+ ///
+ /// Use AppCore's file system singleton to load file:/// URLs from the OS.
+ ///
+ ULString base_dir = ulCreateString("./assets/");
+ ulEnablePlatformFileSystem(base_dir);
+ ulDestroyString(base_dir);
+
+ ///
+ /// Use AppCore's default logger to write the log file to disk.
+ ///
+ ULString log_path = ulCreateString("./ultralight.log");
+ ulEnableDefaultLogger(log_path);
+ ulDestroyString(log_path);
+
+ ///
+ /// Create our renderer using the Config we just set up.
+ ///
+ /// The Renderer singleton maintains the lifetime of the library and
+ /// is required before creating any Views. It should outlive any Views.
+ ///
+ ULRenderer renderer = ulCreateRenderer(config);
+
+ ///
+ /// Create our View.
+ ///
+ /// Views are sized containers for loading and displaying web content.
+ ///
+ ULView view = ulCreateView(renderer, 1600, 1600, false, null, false);
+
+ ///
+ /// Register OnFinishLoading() callback with our View.
+ ///
+ ulViewSetFinishLoadingCallback(view, => onFinishLoading, null);
+
+ ///
+ /// Load a string of HTML into our View. (For code readability, the string
+ /// is defined in the htmlString() function at the bottom of this file)
+ ///
+ /// **Note**:
+ /// This operation may not complete immediately-- we will call
+ /// Renderer::Update continuously and wait for the OnFinishLoading event
+ /// before rendering our View.
+ ///
+ /// Views can also load remote URLs, try replacing the code below with:
+ ///
+ /// ULString url_string = ulCreateString("https://en.wikipedia.org");
+ /// ulViewLoadURL(view, url_string);
+ /// ulDestroyString(url_string);
+ ///
+ ULString html_string = ulCreateString(htmlString);
+ ulViewLoadHTML(view, html_string);
+ ulDestroyString(html_string);
+
+ Log.ClientLogger.Info("Waiting for page to load...");
+
+ ///
+ /// Continuously update our Renderer until our done flag is set to true.
+ ///
+ /// **Note**:
+ /// Calling Renderer::Update handles any pending network requests,
+ /// resource loads, and JavaScript timers.
+ ///
+ while (!done)
+ {
+ ulUpdate(renderer);
+ ulRender(renderer);
+ }
+
+ ///
+ /// Get our View's rendering surface.
+ ///
+ ULSurface surface = ulViewGetSurface(view);
+
+ ///
+ /// Get the underlying bitmap.
+ ///
+ /// @note We're using the default surface definition which is BitmapSurface,
+ /// you can override the surface implementation via
+ /// ulPlatformSetSurfaceDefinition()
+ ///
+ ULBitmap bitmap = ulBitmapSurfaceGetBitmap(surface);
+
+ ///
+ /// The renderer uses a BGRA pixel format but PNG expects RGBA format,
+ /// let's convert the format by swapping Red and Blue channels.
+ ///
+ ulBitmapSwapRedBlueChannels(bitmap);
+
+ ///
+ /// Write our bitmap to a PNG in the current working directory.
+ ///
+ ulBitmapWritePNG(bitmap, "result.png");
+
+ Log.ClientLogger.Info("Saved a render of our page to result.png.");
+
+ Log.ClientLogger.Info("Finished.");
+ }
+}
\ No newline at end of file
diff --git a/GlitchyEngine/vendor/Ultralight-beef b/GlitchyEngine/vendor/Ultralight-beef
new file mode 160000
index 0000000..63114e2
--- /dev/null
+++ b/GlitchyEngine/vendor/Ultralight-beef
@@ -0,0 +1 @@
+Subproject commit 63114e238a54d670654c2f447ed8ef67c6917a96