Replace Magick.NET with stb_image; refactor asset pipeline

- Switched image loading/saving from Magick.NET to native stb_image (Ghost.StbI), removing Magick.NET dependency.
- Added Ghost.StbI project with native DLL, P/Invoke bindings, and wrapper.
- Refactored TextureAssetHandler and TextureProcessor for stb_image, memory-mapped IO, and HDR/16-bit support.
- Split IAssetHandler into IImportableAssetHandler and IPackableAssetHandler; updated interfaces to use FileStream.
- Added shader and mesh asset handlers (GraphicsShaderAssetHandler, ComputeShaderAssetHandler, FBXAssetHandler).
- Improved asset registry/catalog path handling and naming consistency.
- Updated asset import pipeline to use new interfaces and trigger engine reimport.
- Enhanced UI toolbar button styles and EditPage layout.
- Added StbIBindingTest, DisableRuntimeMarshalling, and native wrapper attributes.
- Updated wrapper generator for regex derivesFrom; added stbi.json config.
- Removed Magick.NET reference; added Ghost.StbI and Ghost.Ufbx references.
- Miscellaneous bugfixes and code cleanup.
This commit is contained in:
2026-04-24 00:40:27 +09:00
parent 3533d3367f
commit 4757c0c91a
52 changed files with 8343 additions and 270 deletions

View File

@@ -1,3 +1,4 @@
using Ghost.Editor.Core.Contracts;
using Ghost.Editor.Core.Utilities;
using Ghost.Editor.Models;
using Ghost.Engine;
@@ -64,8 +65,14 @@ internal static class ActivationHandler
};
AllocationManager.Initialize(opts);
App.GetService<EngineCore>();
var assetRegistry = App.GetService<IAssetRegistry>();
var engineCore = App.GetService<EngineCore>();
assetRegistry.OnAssetImported += (sender, e) =>
{
engineCore.AssetManager.ReimportAsset(e);
};
return ValueTask.CompletedTask;
}

View File

@@ -50,10 +50,102 @@
</Style>
<!-- Named Style -->
<Style
x:Key="ToolbarButton"
BasedOn="{StaticResource SubtleButtonStyle}"
TargetType="Button" />
<Style x:Key="ToolbarButton" TargetType="Button">
<Setter Property="Padding" Value="2" />
<Setter Property="Background" Value="{ThemeResource SubtleFillColorTransparentBrush}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid
x:Name="RootGrid"
Padding="10,5"
Background="{TemplateBinding Background}"
CornerRadius="4">
<ContentPresenter
x:Name="ContentPresenter"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="{TemplateBinding Content}" />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="RootGrid.Background" Value="{ThemeResource SubtleFillColorSecondaryBrush}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="RootGrid.Background" Value="{ThemeResource SubtleFillColorTertiaryBrush}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="RootGrid.Background" Value="{ThemeResource SubtleFillColorDisabledBrush}" />
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource ControlStrongFillColorDisabledBrush}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="AccentToolbarButton" TargetType="Button">
<Setter Property="Padding" Value="2" />
<Setter Property="Background" Value="{ThemeResource SubtleFillColorTransparentBrush}" />
<Setter Property="Foreground" Value="{ThemeResource AccentFillColorDefaultBrush}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid
x:Name="RootGrid"
Padding="10,5"
Background="{TemplateBinding Background}"
CornerRadius="4">
<ContentPresenter
x:Name="ContentPresenter"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="{TemplateBinding Content}" />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<VisualState.Setters>
<Setter Target="RootGrid.Background" Value="{ThemeResource SubtleFillColorSecondaryBrush}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Target="RootGrid.Background" Value="{ThemeResource SubtleFillColorTertiaryBrush}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="RootGrid.Background" Value="{ThemeResource SubtleFillColorDisabledBrush}" />
<Setter Target="ContentPresenter.Foreground" Value="{ThemeResource AccentFillColorDisabledBrush}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="VerticalDivider" TargetType="Border">
<Setter Property="BorderBrush" Value="{ThemeResource DividerStrokeColorDefaultBrush}" />

View File

@@ -90,7 +90,7 @@ internal partial class ContentBrowserViewModel : ObservableObject
if (!isDir)
{
var ext = Path.GetExtension(fullPath);
assetType = AssetHandlerRegistry.GetAssetTypeByExtension(ext);
assetType = AssetHandlerRegistry.GetRuntimeAssetTypeByExtension(ext);
}
Files.Add(new ExplorerItem(Path.GetFileName(fullPath), fullPath, isDir, assetType));
}
@@ -144,7 +144,7 @@ internal partial class ContentBrowserViewModel : ObservableObject
}
var ext = Path.GetExtension(file);
var assetType = AssetHandlerRegistry.GetAssetTypeByExtension(ext);
var assetType = AssetHandlerRegistry.GetRuntimeAssetTypeByExtension(ext);
var fileItem = new ExplorerItem(Path.GetFileName(file), file, false, assetType);
Files.Add(fileItem);

View File

@@ -33,8 +33,6 @@ internal sealed partial class ContentBrowser : UserControl
Loaded += ProjectBrowser_Loaded;
Unloaded += ProjectBrowser_Unloaded;
GettingFocus += ProjectBrowser_GettingFocus;
}
private void ProjectBrowser_GettingFocus(UIElement sender, GettingFocusEventArgs args)
@@ -50,11 +48,13 @@ internal sealed partial class ContentBrowser : UserControl
private void ProjectBrowser_Loaded(object sender, RoutedEventArgs e)
{
_inspectorService.OnSelectionChanged += _inspectorService_OnSelectionChanged;
GettingFocus += ProjectBrowser_GettingFocus;
}
private void ProjectBrowser_Unloaded(object sender, RoutedEventArgs e)
{
_inspectorService.OnSelectionChanged -= _inspectorService_OnSelectionChanged;
GettingFocus -= ProjectBrowser_GettingFocus;
if (LastFocused == this)
{

View File

@@ -6,6 +6,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="{ThemeResource LayerFillColorDefaultBrush}"
NavigationCacheMode="Enabled"
mc:Ignorable="d">
<Grid>
@@ -15,49 +16,77 @@
</Grid.RowDefinitions>
<!-- Toolbar -->
<StackPanel
<Grid
Grid.Row="0"
Padding="8,0"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
BorderBrush="{ThemeResource ControlElevationBorderBrush}"
BorderThickness="0,0,0,1"
Orientation="Horizontal">
<ComboBox
Width="200"
BorderThickness="0,0,0,1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel
Grid.Column="0"
VerticalAlignment="Center"
SelectedIndex="0">
<StackPanel Orientation="Horizontal" Spacing="4">
<FontIcon FontSize="{StaticResource ToolbarFontIconFontSize}" Glyph="&#xE8B0;" />
<TextBlock Text="Selection Mode" />
</StackPanel>
<StackPanel Orientation="Horizontal" Spacing="4">
<FontIcon FontSize="{StaticResource ToolbarFontIconFontSize}" Glyph="&#xEC26;" />
<TextBlock Text="Placement Mode" />
</StackPanel>
</ComboBox>
Orientation="Horizontal">
<ComboBox
Width="200"
VerticalAlignment="Center"
SelectedIndex="0">
<StackPanel Orientation="Horizontal" Spacing="4">
<FontIcon FontSize="{StaticResource ToolbarFontIconFontSize}" Glyph="&#xE71D;" />
<TextBlock Text="Hierarchy Mode" />
</StackPanel>
<StackPanel Orientation="Horizontal" Spacing="4">
<FontIcon FontSize="{StaticResource ToolbarFontIconFontSize}" Glyph="&#xEC26;" />
<TextBlock Text="Scatter Mode" />
</StackPanel>
</ComboBox>
<Border Height="12" Style="{StaticResource VerticalDivider}" />
<Border Height="12" Style="{StaticResource VerticalDivider}" />
<MenuBar>
<MenuBarItem Title="File">
<MenuFlyoutItem Text="New" />
<MenuFlyoutItem Text="Open..." />
<MenuFlyoutItem Text="Save" />
<MenuFlyoutItem Text="Exit" />
</MenuBarItem>
<MenuBar>
<MenuBarItem Title="File">
<MenuFlyoutItem Text="New" />
<MenuFlyoutItem Text="Open..." />
<MenuFlyoutItem Text="Save" />
<MenuFlyoutItem Text="Exit" />
</MenuBarItem>
<MenuBarItem Title="Edit">
<MenuFlyoutItem Text="Undo" />
<MenuFlyoutItem Text="Cut" />
<MenuFlyoutItem Text="Copy" />
<MenuFlyoutItem Text="Paste" />
</MenuBarItem>
<MenuBarItem Title="Edit">
<MenuFlyoutItem Text="Undo" />
<MenuFlyoutItem Text="Cut" />
<MenuFlyoutItem Text="Copy" />
<MenuFlyoutItem Text="Paste" />
</MenuBarItem>
<MenuBarItem Title="Help">
<MenuFlyoutItem Text="About" />
</MenuBarItem>
</MenuBar>
</StackPanel>
<MenuBarItem Title="Help">
<MenuFlyoutItem Text="About" />
</MenuBarItem>
</MenuBar>
</StackPanel>
<StackPanel
Grid.Column="0"
Grid.ColumnSpan="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal"
Spacing="4">
<Button Style="{ThemeResource AccentToolbarButton}">
<FontIcon FontSize="{StaticResource ToolbarFontIconFontSize}" Glyph="&#xF5B0;" />
</Button>
<Button Style="{ThemeResource AccentToolbarButton}">
<FontIcon FontSize="{StaticResource ToolbarFontIconFontSize}" Glyph="&#xF8AE;" />
</Button>
<Button IsEnabled="False" Style="{ThemeResource AccentToolbarButton}">
<FontIcon FontSize="{StaticResource ToolbarFontIconFontSize}" Glyph="&#xEE95;" />
</Button>
</StackPanel>
</Grid>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>

View File

@@ -5,17 +5,24 @@ namespace Ghost.Editor.Views.Pages;
public sealed partial class EditPage : Page
{
private readonly ContentBrowser _contentBrowser;
private readonly LogViewer _logViewer;
private ContentBrowser? _contentBrowser;
private LogViewer? _logViewer;
public EditPage()
{
InitializeComponent();
_contentBrowser = new ContentBrowser();
_logViewer = new LogViewer();
ContentBrowserPresenter.Content = GetContentBrowser();
}
ContentBrowserPresenter.Content = _contentBrowser;
private ContentBrowser GetContentBrowser()
{
return _contentBrowser ??= new ContentBrowser();
}
private LogViewer GetLogViewer()
{
return _logViewer ??= new LogViewer();
}
private void SelectorBar_SelectionChanged(SelectorBar sender, SelectorBarSelectionChangedEventArgs args)
@@ -25,10 +32,10 @@ public sealed partial class EditPage : Page
switch (currentSelectedIndex)
{
case 0:
ContentBrowserPresenter.Content = _contentBrowser;
ContentBrowserPresenter.Content = GetContentBrowser();
break;
case 2:
ContentBrowserPresenter.Content = _logViewer;
ContentBrowserPresenter.Content = GetLogViewer();
break;
default:
break;

View File

@@ -66,6 +66,7 @@
Text="Edit" />
<SelectorBarItem x:Name="AnalysisSelectorItem" Text="Analysis" />
<SelectorBarItem x:Name="BuildSelectorItem" Text="Build" />
<SelectorBarItem x:Name="SettingsSelectorItem" Text="Settings" />
</SelectorBar>
</StackPanel>