From ea5c5240fc7983aa36a27047c480eb3d9d33e673 Mon Sep 17 00:00:00 2001 From: SirLynix Date: Tue, 6 Dec 2022 08:05:28 +0100 Subject: [PATCH] Improve emscripten support --- examples/PhysicallyBasedRendering/xmake.lua | 4 --- examples/xmake.lua | 4 +++ .../OpenGLRenderer/Wrapper/Web/WebContext.hpp | 2 +- include/Nazara/Utility/BasicMainloop.hpp | 10 +++---- .../OpenGLRenderer/OpenGLShaderModule.cpp | 4 +++ src/Nazara/OpenGLRenderer/Wrapper/Context.cpp | 11 ++++---- src/Nazara/Platform/SDL2/WindowImpl.cpp | 5 ++++ tests/GraphicsTest/xmake.lua | 4 --- xmake.lua | 26 ++++++++++++++----- xmake/rules/compile_shaders.lua | 15 ++++++----- 10 files changed, 53 insertions(+), 32 deletions(-) diff --git a/examples/PhysicallyBasedRendering/xmake.lua b/examples/PhysicallyBasedRendering/xmake.lua index 5093554b6..6af2278d6 100644 --- a/examples/PhysicallyBasedRendering/xmake.lua +++ b/examples/PhysicallyBasedRendering/xmake.lua @@ -1,7 +1,3 @@ target("PBR") add_deps("NazaraGraphics") add_files("main.cpp") - - if is_plat("wasm") then - add_ldflags("--preload-file assets/", {force = true}) - end diff --git a/examples/xmake.lua b/examples/xmake.lua index 5d4fbaf97..d2f72e685 100644 --- a/examples/xmake.lua +++ b/examples/xmake.lua @@ -3,5 +3,9 @@ option("examples", { description = "Build examples", default = true }) if has_config("examples") then set_group("Examples") + if is_plat("wasm") then + add_ldflags("--preload-file assets/", { force = true }) + end + includes("*/xmake.lua") end diff --git a/include/Nazara/OpenGLRenderer/Wrapper/Web/WebContext.hpp b/include/Nazara/OpenGLRenderer/Wrapper/Web/WebContext.hpp index 014f47c76..bcf9610c6 100644 --- a/include/Nazara/OpenGLRenderer/Wrapper/Web/WebContext.hpp +++ b/include/Nazara/OpenGLRenderer/Wrapper/Web/WebContext.hpp @@ -7,12 +7,12 @@ #ifndef NAZARA_OPENGLRENDERER_WRAPPER_WEB_WEBCONTEXT_HPP #define NAZARA_OPENGLRENDERER_WRAPPER_WEB_WEBCONTEXT_HPP -#include #include #include #include #include #include +#include #include #include #include diff --git a/include/Nazara/Utility/BasicMainloop.hpp b/include/Nazara/Utility/BasicMainloop.hpp index 359b5c978..b47a3900d 100644 --- a/include/Nazara/Utility/BasicMainloop.hpp +++ b/include/Nazara/Utility/BasicMainloop.hpp @@ -4,10 +4,10 @@ #pragma once -#ifndef NAZARA_BASIC_MAINLOOP_HPP -#define NAZARA_BASIC_MAINLOOP_HPP +#ifndef NAZARA_UTILITY_BASICMAINLOOP_HPP +#define NAZARA_UTILITY_BASICMAINLOOP_HPP -#include +#include #ifdef NAZARA_PLATFORM_WEB #include @@ -16,7 +16,7 @@ namespace Nz { template - void BasicMainloop(RenderWindow& window, CallbackT&& callback) + void BasicMainloop(Window& window, CallbackT&& callback) { #ifndef NAZARA_PLATFORM_WEB while (window.IsOpen()) @@ -40,4 +40,4 @@ namespace Nz } -#endif // NAZARA_BASIC_MAINLOOP_HPP +#endif // NAZARA_UTILITY_BASICMAINLOOP_HPP diff --git a/src/Nazara/OpenGLRenderer/OpenGLShaderModule.cpp b/src/Nazara/OpenGLRenderer/OpenGLShaderModule.cpp index 1ecfeecb4..23ed670cb 100644 --- a/src/Nazara/OpenGLRenderer/OpenGLShaderModule.cpp +++ b/src/Nazara/OpenGLRenderer/OpenGLShaderModule.cpp @@ -174,6 +174,10 @@ namespace Nz m_states = states; m_states.sanitized = true; //< Shader is always sanitized (because of keywords) +#ifdef NAZARA_PLATFORM_WEB + m_states.optimize = true; //< Always remove unused code with emscripten (prevents errors on draw calls when no buffer is bound on a unused binding) +#endif + nzsl::Ast::SanitizeVisitor::Options options = nzsl::GlslWriter::GetSanitizeOptions(); options.optionValues = states.optionValues; options.moduleResolver = states.shaderModuleResolver; diff --git a/src/Nazara/OpenGLRenderer/Wrapper/Context.cpp b/src/Nazara/OpenGLRenderer/Wrapper/Context.cpp index 6a859b179..0b18659a7 100644 --- a/src/Nazara/OpenGLRenderer/Wrapper/Context.cpp +++ b/src/Nazara/OpenGLRenderer/Wrapper/Context.cpp @@ -147,11 +147,14 @@ namespace Nz::GL GLenum Context::BindFramebuffer(GLuint fbo) const { + // it looks like emscripten wants us to rebind the FBO everytime +#ifndef NAZARA_PLATFORM_WEB if (m_state.boundDrawFBO == fbo) return GL_DRAW_FRAMEBUFFER; else if (m_state.boundReadFBO == fbo) return GL_READ_FRAMEBUFFER; else +#endif { if (!SetCurrentContext(this)) throw std::runtime_error("failed to activate context"); @@ -166,12 +169,10 @@ namespace Nz::GL void Context::BindFramebuffer(FramebufferTarget target, GLuint fbo) const { auto& currentFbo = (target == FramebufferTarget::Draw) ? m_state.boundDrawFBO : m_state.boundReadFBO; -#ifdef NAZARA_PLATFORM_WEB - constexpr bool isWeb = true; -#else - constexpr bool isWeb = false; + // it looks like emscripten wants us to rebind the FBO everytime +#ifndef NAZARA_PLATFORM_WEB + if (currentFbo != fbo) #endif - if (currentFbo != fbo || isWeb); { if (!SetCurrentContext(this)) throw std::runtime_error("failed to activate context"); diff --git a/src/Nazara/Platform/SDL2/WindowImpl.cpp b/src/Nazara/Platform/SDL2/WindowImpl.cpp index 0835c9d25..0d673e60e 100644 --- a/src/Nazara/Platform/SDL2/WindowImpl.cpp +++ b/src/Nazara/Platform/SDL2/WindowImpl.cpp @@ -194,6 +194,10 @@ namespace Nz WindowHandle WindowImpl::GetSystemHandle() const { +#ifdef NAZARA_PLATFORM_WEB + WindowHandle handle; + return handle; +#else SDL_SysWMinfo wmInfo; SDL_VERSION(&wmInfo.version); @@ -256,6 +260,7 @@ namespace Nz } return handle; +#endif } bool WindowImpl::HasFocus() const diff --git a/tests/GraphicsTest/xmake.lua b/tests/GraphicsTest/xmake.lua index 76c04f596..142f8eb6e 100644 --- a/tests/GraphicsTest/xmake.lua +++ b/tests/GraphicsTest/xmake.lua @@ -1,7 +1,3 @@ target("GraphicsTest") add_deps("NazaraGraphics") add_files("main.cpp") - - if is_plat("wasm") then - add_ldflags("--preload-file assets/", {force = true}) - end diff --git a/xmake.lua b/xmake.lua index efecef871..95fd3916f 100644 --- a/xmake.lua +++ b/xmake.lua @@ -176,9 +176,6 @@ if not has_config("embed_rendererbackends") then end end -add_ldflags("-g -s NO_DISABLE_EXCEPTION_CATCHING -s ALLOW_MEMORY_GROWTH=1") -add_cxflags("-g -s NO_DISABLE_EXCEPTION_CATCHING") - NazaraModules = modules includes("xmake/**.lua") @@ -194,12 +191,27 @@ option("unitybuild", { description = "Build the engine using unity build", defau set_project("NazaraEngine") set_xmakever("2.7.3") -add_requires("dr_wav", "entt 3.10.1", "fmt", "frozen", "kiwisolver", "minimp3", "ordered_map", "stb") -if not is_plat("wasm") then - add_requires("chipmunk2d", "libsdl", "libflac", "efsw") +add_requires("chipmunk2d", "dr_wav", "entt 3.10.1", "fmt", "frozen", "kiwisolver", "libflac", "minimp3", "ordered_map", "stb") +add_requires("libvorbis", { configs = { with_vorbisenc = false } }) + +if is_plat("wasm") then + -- Enable some flags for emscripten + add_cxflags("-g", "-sNO_DISABLE_EXCEPTION_CATCHING") + add_ldflags("-g", "-sNO_DISABLE_EXCEPTION_CATCHING", "-sALLOW_MEMORY_GROWTH", "-sWASM_BIGINT") + add_ldflags("-sERROR_ON_WASM_CHANGES_AFTER_LINK", { force = true }) + + -- we can't use wasm nzsl to compile shaders + if has_config("compile_shaders") then + add_requires("nzsl~host", { kind = "binary" }) + end +else + -- these libraries have ports in emscripten + add_requires("libsdl") add_requires("freetype", { configs = { bzip2 = true, png = true, woff2 = true, zlib = true, debug = is_mode("debug") } }) - add_requires("libvorbis", { configs = { with_vorbisenc = false } }) add_requires("openal-soft", { configs = { shared = true }}) + + -- these libraries aren't supported on emscripten + add_requires("efsw") add_requires("newtondynamics3", { debug = is_plat("windows") and is_mode("debug") }) -- Newton doesn't like compiling in Debug on Linux end diff --git a/xmake/rules/compile_shaders.lua b/xmake/rules/compile_shaders.lua index 0920ad744..346fcbff2 100644 --- a/xmake/rules/compile_shaders.lua +++ b/xmake/rules/compile_shaders.lua @@ -1,16 +1,19 @@ -- Compile shaders to includables headers rule("nzsl.compile.shaders") - on_load(function (target) - target:add("packages", "nzsl") - end) + set_extensions(".nzsl", ".nzslb") before_buildcmd_file(function (target, batchcmds, shaderfile, opt) + import("core.project.project") import("core.tool.toolchain") - local nzslc = path.join(target:pkg("nzsl"):installdir(), "bin", "nzslc") + local nzsl = project.required_package("nzsl~host") or project.required_package("nzsl") + assert(nzsl, "nzsl package not found") + + -- warning: project.required_package is not a stable interface, this may break in the future + local nzslc = path.join(nzsl:installdir(), "bin", "nzslc") -- add commands - batchcmds:show_progress(opt.progress, "${color.build.object}compiling shader %s", shaderfile) + batchcmds:show_progress(opt.progress, "${color.build.object}compiling.shader %s", shaderfile) local argv = { "--compile=nzslb-header", "--partial", "--optimize" } -- handle --log-format @@ -21,6 +24,7 @@ rule("nzsl.compile.shaders") table.insert(argv, shaderfile) + -- on mingw we need run envs because of .dll dependencies which may be not part of the PATH local envs if is_plat("mingw") then local mingw = toolchain.load("mingw") @@ -28,7 +32,6 @@ rule("nzsl.compile.shaders") envs = mingw:runenvs() end end - batchcmds:vrunv(nzslc, argv, { curdir = ".", envs = envs }) local outputFile = path.join(path.directory(shaderfile), path.basename(shaderfile) .. ".nzslb.h")