Add **Web platform with Emscripten**

This commit is contained in:
Wojtek Figat
2026-02-14 00:07:21 +01:00
parent fd0584b406
commit f12ad5c874
80 changed files with 1529 additions and 61 deletions

View File

@@ -141,6 +141,11 @@ API_ENUM() enum class BuildPlatform
/// </summary>
API_ENUM(Attributes="EditorDisplay(null, \"Windows ARM64\")")
WindowsARM64 = 15,
/// <summary>
/// Web
/// </summary>
Web = 16,
};
/// <summary>

View File

@@ -69,6 +69,10 @@
#include "Platform/iOS/iOSPlatformTools.h"
#include "Engine/Platform/iOS/iOSPlatformSettings.h"
#endif
#if PLATFORM_TOOLS_WEB
#include "Platform/Web/WebPlatformTools.h"
#include "Engine/Platform/Web/WebPlatformSettings.h"
#endif
namespace GameCookerImpl
{
@@ -151,6 +155,8 @@ const Char* ToString(const BuildPlatform platform)
return TEXT("iOS ARM64");
case BuildPlatform::WindowsARM64:
return TEXT("Windows ARM64");
case BuildPlatform::Web:
return TEXT("Web");
default:
return TEXT("");
}
@@ -307,6 +313,10 @@ void CookingData::GetBuildPlatformName(const Char*& platform, const Char*& archi
platform = TEXT("Windows");
architecture = TEXT("ARM64");
break;
case BuildPlatform::Web:
platform = TEXT("Web");
architecture = TEXT("x86");
break;
default:
LOG(Fatal, "Unknown or unsupported build platform.");
}
@@ -461,6 +471,11 @@ PlatformTools* GameCooker::GetTools(BuildPlatform platform)
case BuildPlatform::iOSARM64:
result = New<iOSPlatformTools>();
break;
#endif
#if PLATFORM_TOOLS_WEB
case BuildPlatform::Web:
result = New<WebPlatformTools>();
break;
#endif
}
Tools.Add(platform, result);
@@ -604,6 +619,9 @@ void GameCooker::GetCurrentPlatform(PlatformType& platform, BuildPlatform& build
case PlatformType::iOS:
buildPlatform = BuildPlatform::iOSARM64;
break;
case PlatformType::Web:
buildPlatform = BuildPlatform::Web;
break;
default: ;
}
}

View File

@@ -106,6 +106,7 @@ namespace FlaxEditor
case BuildPlatform.MacOSARM64:
case BuildPlatform.MacOSx64: return PlatformType.Mac;
case BuildPlatform.iOSARM64: return PlatformType.iOS;
case BuildPlatform.Web: return PlatformType.Web;
default: throw new ArgumentOutOfRangeException(nameof(buildPlatform), buildPlatform, null);
}
}

View File

@@ -0,0 +1,60 @@
// Copyright (c) Wojciech Figat. All rights reserved.
#if PLATFORM_TOOLS_WEB
#include "WebPlatformTools.h"
#include "Engine/Platform/File.h"
#include "Engine/Platform/FileSystem.h"
#include "Engine/Platform/Web/WebPlatformSettings.h"
#include "Engine/Core/Config/GameSettings.h"
#include "Engine/Core/Config/BuildSettings.h"
#include "Engine/Content/Content.h"
#include "Engine/Content/JsonAsset.h"
#include "Engine/Graphics/PixelFormatExtensions.h"
IMPLEMENT_SETTINGS_GETTER(WebPlatformSettings, WebPlatform);
const Char* WebPlatformTools::GetDisplayName() const
{
return TEXT("Web");
}
const Char* WebPlatformTools::GetName() const
{
return TEXT("Web");
}
PlatformType WebPlatformTools::GetPlatform() const
{
return PlatformType::Web;
}
ArchitectureType WebPlatformTools::GetArchitecture() const
{
return ArchitectureType::x86;
}
DotNetAOTModes WebPlatformTools::UseAOT() const
{
return DotNetAOTModes::MonoAOTStatic;
}
PixelFormat WebPlatformTools::GetTextureFormat(CookingData& data, TextureBase* texture, PixelFormat format)
{
// TODO: texture compression for Web (eg. ASTC for mobile and BC for others?)
return PixelFormatExtensions::FindUncompressedFormat(format);
}
bool WebPlatformTools::IsNativeCodeFile(CookingData& data, const String& file)
{
String extension = FileSystem::GetExtension(file);
return extension.IsEmpty() || extension == TEXT("html") || extension == TEXT("js") || extension == TEXT("wams");
}
bool WebPlatformTools::OnPostProcess(CookingData& data)
{
// TODO: customizable HTML templates
return false;
}
#endif

View File

@@ -0,0 +1,26 @@
// Copyright (c) Wojciech Figat. All rights reserved.
#pragma once
#if PLATFORM_TOOLS_WEB
#include "../../PlatformTools.h"
/// <summary>
/// The Web platform support tools.
/// </summary>
class WebPlatformTools : public PlatformTools
{
public:
// [PlatformTools]
const Char* GetDisplayName() const override;
const Char* GetName() const override;
PlatformType GetPlatform() const override;
ArchitectureType GetArchitecture() const override;
DotNetAOTModes UseAOT() const override;
PixelFormat GetTextureFormat(CookingData& data, TextureBase* texture, PixelFormat format) override;
bool IsNativeCodeFile(CookingData& data, const String& file) override;
bool OnPostProcess(CookingData& data) override;
};
#endif

View File

@@ -572,6 +572,14 @@ bool ProcessShaderBase(CookAssetsStep::AssetCookData& data, ShaderAssetBase* ass
COMPILE_PROFILE(Vulkan_SM5, SHADER_FILE_CHUNK_INTERNAL_VULKAN_SM5_CACHE);
break;
}
#endif
#if PLATFORM_TOOLS_WEB
case BuildPlatform::Web:
{
const char* platformDefineName = "PLATFORM_WEB";
// TODO: compile shaders for WebGPU
break;
}
#endif
default:
{

View File

@@ -87,6 +87,7 @@ public class Editor : EditorModule
AddPlatformTools(options, platformToolsRoot, platformToolsRootExternal, "Android", "PLATFORM_TOOLS_ANDROID");
AddPlatformTools(options, platformToolsRoot, platformToolsRootExternal, "iOS", "PLATFORM_TOOLS_IOS");
}
AddPlatformTools(options, platformToolsRoot, platformToolsRootExternal, "Web", "PLATFORM_TOOLS_WEB");
// Visual Studio integration
if (options.Platform.Target == TargetPlatform.Windows && Flax.Build.Platform.BuildTargetPlatform == TargetPlatform.Windows)

View File

@@ -93,6 +93,7 @@ namespace FlaxEditor.GUI
new PlatformData(PlatformType.PS5, icons.PS5Icon128, "PlayStation 5"),
new PlatformData(PlatformType.Mac, icons.MacOSIcon128, "macOS"),
new PlatformData(PlatformType.iOS, icons.IOSIcon128, "iOS"),
new PlatformData(PlatformType.Web, icons.Flax64, "Web"),
};
const float IconSize = 64.0f;

View File

@@ -1603,9 +1603,9 @@ namespace FlaxEditor.Surface.Archetypes
Title = "Platform Switch",
Description = "Gets the input value based on the runtime-platform type",
Flags = NodeFlags.AllGraphs,
Size = new Float2(220, 240),
Size = new Float2(220, 260),
ConnectionsHints = ConnectionsHint.Value,
IndependentBoxes = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 },
IndependentBoxes = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
DependentBoxes = new[] { 0 },
Elements = new[]
{
@@ -1622,6 +1622,7 @@ namespace FlaxEditor.Surface.Archetypes
NodeElementArchetype.Factory.Input(9, "PlayStation 5", true, null, 10),
NodeElementArchetype.Factory.Input(10, "Mac", true, null, 11),
NodeElementArchetype.Factory.Input(11, "iOS", true, null, 12),
NodeElementArchetype.Factory.Input(12, "Web", true, null, 13),
}
},
new NodeArchetype

View File

@@ -52,6 +52,7 @@ namespace FlaxEditor.Windows
{ PlatformType.PS5, new PS5() },
{ PlatformType.Mac, new Mac() },
{ PlatformType.iOS, new iOS() },
{ PlatformType.Web, new Web() },
};
public BuildTabProxy(GameCookerWindow win, PlatformSelector platformSelector)
@@ -165,6 +166,7 @@ namespace FlaxEditor.Windows
case BuildPlatform.UWPx64:
case BuildPlatform.LinuxX64:
case BuildPlatform.AndroidARM64:
case BuildPlatform.Web:
text += "\nUse Flax Launcher and download the required package.";
break;
#endif
@@ -538,6 +540,11 @@ namespace FlaxEditor.Windows
protected override BuildPlatform BuildPlatform => BuildPlatform.iOSARM64;
}
class Web : Platform
{
protected override BuildPlatform BuildPlatform => BuildPlatform.Web;
}
class Editor : CustomEditor
{
private PlatformType _platform;
@@ -592,6 +599,9 @@ namespace FlaxEditor.Windows
case PlatformType.iOS:
name = "iOS";
break;
case PlatformType.Web:
name = "Web";
break;
default:
name = Utilities.Utils.GetPropertyNameUI(_platform.ToString());
break;