TextureAsset properties, start of better asset pipeline detection

This commit is contained in:
Simon Lübeß
2024-06-12 16:51:52 +02:00
parent b3dac4a338
commit 36e98311c6
12 changed files with 267 additions and 48 deletions
+11 -9
View File
@@ -140,16 +140,18 @@ class AssetFile
GenerateAssetHandle(); GenerateAssetHandle();
var assetPipeline = _contentManager.GetDefaultProcessors(fileExtension); IAssetImporter assetImporter = _contentManager.GetAssetImporter(fileExtension);
IAssetProcessor assetProcessor = ?; //_contentManager.GetAssetProcessor(assetImporter.);
IAssetExporter assetExporter = ?; //_contentManager.GetAssetProcessor(assetImporter.);
// TODO! // TODO!
//if (assetPipeline case .Err) //if (assetPipeline case .Err)
// return; // return;
var assetLoader = _contentManager.GetDefaultAssetLoader(fileExtension); var assetLoader = _contentManager.GetDefaultAssetLoader(fileExtension);
// We don't have a loader -> we don't need a config // We don't have a loader -> we don't need a config
if (assetLoader == null && assetPipeline case .Err) if (assetLoader == null && assetImporter == null)
return; return;
if (assetLoader != null) if (assetLoader != null)
@@ -162,16 +164,16 @@ class AssetFile
} }
_assetConfig.Importer = new String(); _assetConfig.Importer = new String();
assetPipeline?.Importer?.GetType()?.GetName(_assetConfig.Importer); assetImporter?.GetType()?.GetName(_assetConfig.Importer);
_assetConfig.ImporterConfig = assetPipeline?.Importer.CreateDefaultConfig(); _assetConfig.ImporterConfig = assetImporter?.CreateDefaultConfig();
_assetConfig.Processor = new String(); _assetConfig.Processor = new String();
assetPipeline?.Processor?.GetType()?.GetName(_assetConfig.Processor); assetProcessor?.GetType()?.GetName(_assetConfig.Processor);
_assetConfig.ProcessorConfig = assetPipeline?.Processor.CreateDefaultConfig(); _assetConfig.ProcessorConfig = assetProcessor.CreateDefaultConfig();
_assetConfig.Exporter = new String(); _assetConfig.Exporter = new String();
assetPipeline?.Exporter?.GetType()?.GetName(_assetConfig.Exporter); assetExporter?.GetType()?.GetName(_assetConfig.Exporter);
_assetConfig.ExporterConfig = assetPipeline?.Exporter.CreateDefaultConfig(); _assetConfig.ExporterConfig = assetExporter.CreateDefaultConfig();
SaveAssetConfig(); SaveAssetConfig();
} }
+32 -15
View File
@@ -5,6 +5,8 @@ using System;
using System.IO; using System.IO;
using GlitchyEngine.Content; using GlitchyEngine.Content;
using GlitchyEditor.Assets.Processors; using GlitchyEditor.Assets.Processors;
using System.Threading;
using System.Threading.Tasks;
namespace GlitchyEditor.Assets; namespace GlitchyEditor.Assets;
@@ -14,6 +16,8 @@ class AssetConverter
private EditorContentManager _contentManager; private EditorContentManager _contentManager;
private Dictionary<AssetFile, Task> _processingAssets ~ delete _;
public this(EditorContentManager contentManager) public this(EditorContentManager contentManager)
{ {
_contentManager = contentManager; _contentManager = contentManager;
@@ -21,10 +25,10 @@ class AssetConverter
public void QueueForProcessing(AssetFile assetFile, bool isBlocking = false) public void QueueForProcessing(AssetFile assetFile, bool isBlocking = false)
{ {
if (!isBlocking) if (isBlocking)
_queue.Add(assetFile);
else
Process(assetFile); Process(assetFile);
else
_queue.Add(assetFile);
} }
public void Update() public void Update()
@@ -44,7 +48,6 @@ class AssetConverter
{ {
IAssetImporter importer = _contentManager.GetAssetImporter(assetFile); IAssetImporter importer = _contentManager.GetAssetImporter(assetFile);
IAssetProcessor processor = _contentManager.GetAssetProcessor(assetFile); IAssetProcessor processor = _contentManager.GetAssetProcessor(assetFile);
IAssetExporter exporter = _contentManager.GetAssetExporter(assetFile);
if (importer == null) if (importer == null)
{ {
@@ -57,12 +60,6 @@ class AssetConverter
Log.EngineLogger.Error("Processor is null!"); Log.EngineLogger.Error("Processor is null!");
return; return;
} }
if (exporter == null)
{
Log.EngineLogger.Error("Exporter is null!");
return;
}
Result<ImportedResource> importResult = importer.Import(assetFile.AssetFile.Path, Result<ImportedResource> importResult = importer.Import(assetFile.AssetFile.Path,
assetFile.AssetFile.Identifier, assetFile.AssetConfig.ImporterConfig); assetFile.AssetFile.Identifier, assetFile.AssetConfig.ImporterConfig);
@@ -75,7 +72,10 @@ class AssetConverter
defer { delete importResult.Value; } defer { delete importResult.Value; }
Result<ProcessedResource> processResult = processor.Process(importResult.Value, assetFile.AssetConfig.ProcessorConfig); List<ProcessedResource> resources = scope .();
defer { ClearAndDeleteItems!(resources); }
Result<void> processResult = processor.Process(importResult.Value, assetFile.AssetConfig.ProcessorConfig, resources);
if (processResult case .Err) if (processResult case .Err)
{ {
@@ -83,16 +83,30 @@ class AssetConverter
return; return;
} }
defer { delete processResult.Value; } for (ProcessedResource resource in resources)
{
TrySilent!(ExportResource(assetFile, resource));
}
}
private Result<void> ExportResource(AssetFile assetFile, ProcessedResource resource)
{
IAssetExporter exporter = _contentManager.GetAssetExporter(resource.AssetType);
if (exporter == null)
{
Log.EngineLogger.Error($"No exporter for asset type {resource.AssetType}!");
return .Err;
}
MemoryStream memoryStream = scope .(); MemoryStream memoryStream = scope .();
Result<void> exportResult = exporter.Export(memoryStream, processResult.Value, assetFile.AssetConfig.ExporterConfig); Result<void> exportResult = exporter.Export(memoryStream, resource, assetFile.AssetConfig.ExporterConfig);
if (exportResult case .Err) if (exportResult case .Err)
{ {
Log.EngineLogger.Error("Failed to export asset!"); Log.EngineLogger.Error("Failed to export asset!");
return; return .Err;
} }
CachedAsset assetInfo = scope CachedAsset(); CachedAsset assetInfo = scope CachedAsset();
@@ -100,11 +114,14 @@ class AssetConverter
assetInfo.CreationTimestamp = DateTime.UtcNow; assetInfo.CreationTimestamp = DateTime.UtcNow;
assetInfo.Compression = assetFile.AssetConfig.ExporterConfig.Compression; assetInfo.Compression = assetFile.AssetConfig.ExporterConfig.Compression;
assetInfo.AssetIdentifier = new AssetIdentifier(assetFile.AssetFile.Identifier); assetInfo.AssetIdentifier = new AssetIdentifier(assetFile.AssetFile.Identifier);
assetInfo.AssetType = processResult.Value.AssetType; assetInfo.AssetType = resource.AssetType;
if (_contentManager.AssetCache.SaveAsset(assetInfo, memoryStream.Memory) case .Err) if (_contentManager.AssetCache.SaveAsset(assetInfo, memoryStream.Memory) case .Err)
{ {
Log.EngineLogger.Error("Failed to write asset to cache."); Log.EngineLogger.Error("Failed to write asset to cache.");
return .Err;
} }
return .Ok;
} }
} }
+1 -1
View File
@@ -27,7 +27,7 @@ public class SubAsset
{ {
public AssetNode Asset; public AssetNode Asset;
public String Name ~ delete _; public String Name ~ delete _;
//public String AssetInternalPath ~ delete _; public AssetIdentifier Identifier ~ delete _;
public Texture2D PreviewImage ~ _?.ReleaseRef(); public Texture2D PreviewImage ~ _?.ReleaseRef();
} }
@@ -4,11 +4,14 @@ using GlitchyEngine.Renderer;
using GlitchyEditor.Assets.Processors; using GlitchyEditor.Assets.Processors;
using GlitchyEngine; using GlitchyEngine;
using GlitchyEditor.Assets.Importers; using GlitchyEditor.Assets.Importers;
using GlitchyEngine.Content;
namespace GlitchyEditor.Assets.Exporters; namespace GlitchyEditor.Assets.Exporters;
class TextureExporter : IAssetExporter class TextureExporter : IAssetExporter
{ {
public static AssetType ExportedAssetType => .Texture;
public AssetExporterConfig CreateDefaultConfig() public AssetExporterConfig CreateDefaultConfig()
{ {
return new AssetExporterConfig(); return new AssetExporterConfig();
+4 -4
View File
@@ -23,13 +23,13 @@ abstract class Config
return true; return true;
} }
public abstract void ShowEditor(); public abstract void ShowEditor(AssetFile assetFile);
} }
[BonTarget, BonPolyRegister] [BonTarget, BonPolyRegister]
class AssetImporterConfig : Config class AssetImporterConfig : Config
{ {
public override void ShowEditor() public override void ShowEditor(AssetFile assetFile)
{ {
} }
@@ -38,7 +38,7 @@ class AssetImporterConfig : Config
[BonTarget, BonPolyRegister] [BonTarget, BonPolyRegister]
class AssetProcessorConfig : Config class AssetProcessorConfig : Config
{ {
public override void ShowEditor() public override void ShowEditor(AssetFile assetFile)
{ {
} }
@@ -56,7 +56,7 @@ class AssetExporterConfig : Config
set => SetIfChanged(ref _compression, value); set => SetIfChanged(ref _compression, value);
} }
public override void ShowEditor() public override void ShowEditor(AssetFile assetFile)
{ {
ImGui.PropertyTableStartNewProperty("Compression"); ImGui.PropertyTableStartNewProperty("Compression");
ImGui.AttachTooltip("Specifies the compression method used to compress the processed asset."); ImGui.AttachTooltip("Specifies the compression method used to compress the processed asset.");
@@ -12,19 +12,28 @@ interface IAssetImporter
AssetImporterConfig CreateDefaultConfig(); AssetImporterConfig CreateDefaultConfig();
/// The type that ImportedResource returns.
static Type ProcessedAssetType { get; }
Result<ImportedResource> Import(StringView fullFileName, AssetIdentifier assetIdentifier, AssetImporterConfig config); Result<ImportedResource> Import(StringView fullFileName, AssetIdentifier assetIdentifier, AssetImporterConfig config);
} }
interface IAssetProcessor interface IAssetProcessor
{ {
AssetProcessorConfig CreateDefaultConfig(); AssetProcessorConfig CreateDefaultConfig();
/// The asset type that this processor can process.
static Type ProcessedAssetType { get; }
Result<ProcessedResource> Process(ImportedResource importedResource, AssetProcessorConfig config); Result<void> Process(ImportedResource importedResource, AssetProcessorConfig config, List<ProcessedResource> outProcessedResources);
} }
interface IAssetExporter interface IAssetExporter
{ {
AssetExporterConfig CreateDefaultConfig(); AssetExporterConfig CreateDefaultConfig();
/// The asset type that this exporter can export.
static AssetType ExportedAssetType { get; }
Result<void> Export(Stream stream, ProcessedResource processedObject, AssetExporterConfig config); Result<void> Export(Stream stream, ProcessedResource processedObject, AssetExporterConfig config);
} }
@@ -40,7 +40,7 @@ class TextureImporterConfig : AssetImporterConfig
set => SetIfChanged(ref _isSrgb, value); set => SetIfChanged(ref _isSrgb, value);
} }
public override void ShowEditor() public override void ShowEditor(AssetFile assetFile)
{ {
ImGui.PropertyTableStartNewProperty("Is sRGB"); ImGui.PropertyTableStartNewProperty("Is sRGB");
ImGui.AttachTooltip("If checked, the texture will be forced to be imported as sRGB. Refer to the documentation for an detailed explanation what you should do here."); ImGui.AttachTooltip("If checked, the texture will be forced to be imported as sRGB. Refer to the documentation for an detailed explanation what you should do here.");
@@ -5,6 +5,8 @@ using GlitchyEngine.Renderer;
using GlitchyEngine.Content; using GlitchyEngine.Content;
using GlitchyEngine; using GlitchyEngine;
using ImGui; using ImGui;
using System.Collections;
using GlitchyEngine.Math;
namespace GlitchyEditor.Assets.Processors; namespace GlitchyEditor.Assets.Processors;
@@ -16,14 +18,27 @@ enum GenerateMipMaps
Kaiser Kaiser
} }
enum TextureType
{
Texture,
Sprite
}
[BonTarget, BonPolyRegister] [BonTarget, BonPolyRegister]
class TextureProcessorConfig : AssetProcessorConfig class TextureProcessorConfig : AssetProcessorConfig
{ {
[BonInclude] [BonInclude]
private GenerateMipMaps _generateMipMaps; private GenerateMipMaps _generateMipMaps = .No;
[BonInclude] [BonInclude]
private SamplerStateDescription _samplerStateDescription = .(); private SamplerStateDescription _samplerStateDescription = .();
[BonInclude]
private TextureType _textureType = .Texture;
[BonInclude]
private List<SpriteDesc> _sprites = new .() ~ DeleteContainerAndItems!(_);
public GenerateMipMaps GenerateMipMaps public GenerateMipMaps GenerateMipMaps
{ {
@@ -36,9 +51,64 @@ class TextureProcessorConfig : AssetProcessorConfig
get => _samplerStateDescription; get => _samplerStateDescription;
set => SetIfChanged(ref _samplerStateDescription, value); set => SetIfChanged(ref _samplerStateDescription, value);
} }
public override void ShowEditor() public TextureType TextureType
{ {
get => _textureType;
set => SetIfChanged(ref _textureType, value);
}
public List<SpriteDesc> Sprites => _sprites;
public override void ShowEditor(AssetFile assetFile)
{
if (ImGui.BeginPopupModal("Apply Changes", null, .AlwaysAutoResize))
{
ImGui.Text("The changes have to be applied before you can open the sprite editor.\nDo you want to apply the changes and continue?");
if (ImGui.Button("Apply"))
{
assetFile.SaveAssetConfig();
ImGui.CloseCurrentPopup();
new SpriteEditor(Editor.Instance, assetFile.AssetConfig.AssetHandle);
}
ImGui.SameLine();
if (ImGui.Button("Cancel"))
{
ImGui.CloseCurrentPopup();
}
ImGui.EndPopup();
}
ImGui.PropertyTableStartNewProperty("Texture Type");
TextureType textureType = _textureType;
if (ImGui.EnumCombo("##textureType", ref textureType))
{
TextureType = textureType;
}
ImGui.PropertyTableStartNewRow();
if (textureType == .Sprite)
{
if (ImGui.Button("Open Sprite Editor..."))
{
if (_changed)
{
ImGui.OpenPopup("Apply Changes");
}
else
{
new SpriteEditor(Editor.Instance, assetFile.AssetConfig.AssetHandle);
}
}
}
ImGui.PropertyTableStartNewProperty("Generate Mip Maps", "Specifies the algorithm used to generate mip maps for this texture."); ImGui.PropertyTableStartNewProperty("Generate Mip Maps", "Specifies the algorithm used to generate mip maps for this texture.");
ImGui.BeginDisabled(); ImGui.BeginDisabled();
@@ -157,6 +227,14 @@ class TextureProcessorConfig : AssetProcessorConfig
} }
} }
public class SpriteDesc
{
public String Name ~ delete _;
public int2 TopLeft;
public int2 Size;
public AssetHandle AssetHandle;
}
class ProcessedTexture : ProcessedResource class ProcessedTexture : ProcessedResource
{ {
public Format PixelFormat = .Unknown; public Format PixelFormat = .Unknown;
@@ -276,22 +354,46 @@ class ProcessedTexture : ProcessedResource
} }
} }
class ProcessedSprite : ProcessedResource
{
public override AssetType AssetType => .Sprite;
private AssetHandle _texture;
private int2 _topLeft;
private int2 _size;
public AssetHandle Texture => _texture;
public int2 TopLeft => _topLeft;
public int2 Size => _size;
public this(AssetIdentifier ownAssetIdentifier, AssetHandle texture, int2 topLeft, int2 size) : base(ownAssetIdentifier)
{
_texture = texture;
_topLeft = topLeft;
_size = size;
}
}
class TextureProcessor : IAssetProcessor class TextureProcessor : IAssetProcessor
{ {
public static Type ProcessedAssetType => typeof(ImportedTexture);
public AssetProcessorConfig CreateDefaultConfig() public AssetProcessorConfig CreateDefaultConfig()
{ {
return new TextureProcessorConfig(); return new TextureProcessorConfig();
} }
public Result<ProcessedResource> Process(ImportedResource importedObject, AssetProcessorConfig config) public Result<void> Process(ImportedResource importedObject, AssetProcessorConfig config, List<ProcessedResource> outProcessedResources)
{ {
Log.EngineLogger.AssertDebug(config is TextureProcessorConfig); Log.EngineLogger.AssertDebug(config is TextureProcessorConfig);
Log.EngineLogger.AssertDebug(importedObject is ImportedTexture); Log.EngineLogger.AssertDebug(importedObject is ImportedTexture);
return Try!(ProcessTexture(importedObject as ImportedTexture, config as TextureProcessorConfig)); return Try!(ProcessTexture(importedObject as ImportedTexture, config as TextureProcessorConfig, outProcessedResources));
} }
private Result<ProcessedTexture> ProcessTexture(ImportedTexture importedTexture, TextureProcessorConfig config) private Result<void> ProcessTexture(ImportedTexture importedTexture, TextureProcessorConfig config, List<ProcessedResource> outProcessedResources)
{ {
ProcessedTexture processedTexture = new ProcessedTexture(new AssetIdentifier(importedTexture.AssetIdentifier.FullIdentifier)); ProcessedTexture processedTexture = new ProcessedTexture(new AssetIdentifier(importedTexture.AssetIdentifier.FullIdentifier));
@@ -322,8 +424,31 @@ class TextureProcessor : IAssetProcessor
} }
// TODO: Pack to BC-Format or what ever was selected. // TODO: Pack to BC-Format or what ever was selected.
if (config.TextureType == .Sprite)
{
}
return processedTexture; return .Ok;
}
private void CreateSprites(ProcessedTexture processedTexture, TextureProcessorConfig config, List<ProcessedResource> outProcessedResources)
{
if (processedTexture.Dimension != .Texture2D)
{
Log.ClientLogger.Error("Only 2D textures can be used as sprites.");
return;
}
if (config.Sprites.Count == 0)
{
/*ProcessedSprite sprite = new ProcessedSprite(processedTexture.);
processedTexture.Sprites.Add(new SpriteDesc(){
Name = new String("Sprite"),
TopLeft = .(0, 0),
Size = .((.)processedTexture.Width, (.)processedTexture.Height)
});*/
}
} }
private int CalculateMipMapCount(int width, int height, int depth) private int CalculateMipMapCount(int width, int height, int depth)
+21
View File
@@ -0,0 +1,21 @@
using System;
using GlitchyEditor.EditWindows;
using GlitchyEngine.Content;
using ImGui;
namespace GlitchyEditor.Assets;
class SpriteEditor : ClosableWindow
{
AssetHandle _assetHandle;
public this(Editor editor, AssetHandle assetHandle) : base(editor, "Sprite Editor")
{
_assetHandle = assetHandle;
}
protected override void InternalShow()
{
ImGui.Text("Nothing to see here, yet...");
}
}
@@ -137,9 +137,9 @@ class InspectorWindow : EditorWindow
if (ImGui.BeginPropertyTable("asset_properties", ImGui.GetID("asset_properties"))) if (ImGui.BeginPropertyTable("asset_properties", ImGui.GetID("asset_properties")))
{ {
assetFile.AssetConfig?.ImporterConfig?.ShowEditor(); assetFile.AssetConfig?.ImporterConfig?.ShowEditor(assetFile);
assetFile.AssetConfig?.ProcessorConfig?.ShowEditor(); assetFile.AssetConfig?.ProcessorConfig?.ShowEditor(assetFile);
assetFile.AssetConfig?.ExporterConfig?.ShowEditor(); assetFile.AssetConfig?.ExporterConfig?.ShowEditor(assetFile);
ImGui.EndTable(); ImGui.EndTable();
+47 -6
View File
@@ -219,10 +219,14 @@ class EditorContentManager : IContentManager
}; };
private append List<IAssetImporter> _assetImporters = .() ~ ClearAndDeleteItems!(_); private append List<IAssetImporter> _assetImporters = .() ~ ClearAndDeleteItems!(_);
private append Dictionary<StringView, IAssetImporter> _extensionToAssetImporter = .();
private append List<IAssetProcessor> _assetProcessors = .() ~ ClearAndDeleteItems!(_); private append List<IAssetProcessor> _assetProcessors = .() ~ ClearAndDeleteItems!(_);
private append List<IAssetExporter> _assetExporters = .() ~ ClearAndDeleteItems!(_); private append Dictionary<Type, IAssetProcessor> _importedResourceToAssetProcessor = .();
//private append List<IAssetExporter> _assetExporters = .() ~ ClearAndDeleteItems!(_);
private append Dictionary<StringView, (IAssetImporter Importer, IAssetProcessor Processor, IAssetExporter Exporter)> _defaultAssetProcessors = .() ~ delete:append _; private append Dictionary<StringView, (IAssetImporter Importer, IAssetProcessor Processor, IAssetExporter Exporter)> _defaultAssetProcessors = .() ~ delete:append _;
private append Dictionary<AssetType, IAssetExporter> _assetExporters = .() ~ ClearDictionaryAndDeleteValues!(_);
public void RegisterAssetLoader<T>() where T : new, class, IAssetLoader public void RegisterAssetLoader<T>() where T : new, class, IAssetLoader
{ {
// Log.EngineLogger.AssertDebug(!_assetLoaders.Any((l) => l.GetType() == typeof(T)), "Asset loader already registered."); // Log.EngineLogger.AssertDebug(!_assetLoaders.Any((l) => l.GetType() == typeof(T)), "Asset loader already registered.");
@@ -242,7 +246,11 @@ class EditorContentManager : IContentManager
_assetImporters.Add(assetImporter); _assetImporters.Add(assetImporter);
for (StringView ext in T.FileExtensions) for (StringView ext in T.FileExtensions)
_supportedExtensions.Add(new String(ext)); {
String fileExtension = new String(ext);
_supportedExtensions.Add(fileExtension);
_extensionToAssetImporter.Add(fileExtension, assetImporter);
}
} }
public void RegisterAssetProcessor<T>() where T : new, class, IAssetProcessor public void RegisterAssetProcessor<T>() where T : new, class, IAssetProcessor
@@ -256,7 +264,29 @@ class EditorContentManager : IContentManager
{ {
T assetExporter = new T(); T assetExporter = new T();
_assetExporters.Add(assetExporter); Log.EngineLogger.AssertDebug(_assetExporters.ContainsKey(T.ExportedAssetType), "Cannot register multiple exporters for one asset type.");
_assetExporters.Add(T.ExportedAssetType, assetExporter);
}
public IAssetImporter GetAssetImporter(StringView fileExtension)
{
if (_extensionToAssetImporter.TryGetValue(fileExtension, let importer))
{
return importer;
}
return null;
}
public IAssetImporter GetAssetProcessor(Type importedResourceType)
{
if (_extensionToAssetImporter.TryGetValue(fileExtension, let importer))
{
return importer;
}
return null;
} }
public void SetAsDefaultAssetLoader<T>(params Span<StringView> fileExtensions) where T : IAssetLoader public void SetAsDefaultAssetLoader<T>(params Span<StringView> fileExtensions) where T : IAssetLoader
@@ -332,14 +362,15 @@ class EditorContentManager : IContentManager
} }
} }
for (var i in _assetExporters) // TODO: How do we get the exporter for the config?
/*for (var i in _assetExporters)
{ {
if (i.GetType() == typeof(TExport)) if (i.GetType() == typeof(TExport))
{ {
exporter = i; exporter = i;
break; break;
} }
} }*/
_defaultAssetProcessors[foundExtension] = (importer, processor, exporter); _defaultAssetProcessors[foundExtension] = (importer, processor, exporter);
} }
@@ -756,7 +787,7 @@ class EditorContentManager : IContentManager
return result; return result;
} }
/*
public IAssetExporter GetAssetExporter(AssetFile file) public IAssetExporter GetAssetExporter(AssetFile file)
{ {
IAssetExporter result = null; IAssetExporter result = null;
@@ -776,6 +807,16 @@ class EditorContentManager : IContentManager
return result; return result;
} }
*/
public IAssetExporter GetAssetExporter(AssetType assetType)
{
if (_assetExporters.TryGetValue(assetType, let exporter))
{
return exporter;
}
return null;
}
public enum SaveAssetError public enum SaveAssetError
{ {
+2 -1
View File
@@ -3,5 +3,6 @@ namespace GlitchyEngine.Content;
enum AssetType : uint16 enum AssetType : uint16
{ {
Unknown, Unknown,
Texture Texture,
Sprite
} }