Better asset processor selection, process subassets

This commit is contained in:
Simon Lübeß
2024-06-13 15:44:27 +02:00
parent 36e98311c6
commit cd434d64f9
22 changed files with 356 additions and 292 deletions
@@ -2,36 +2,10 @@
AssetLoader = null, AssetLoader = null,
Config = null, Config = null,
Importer = "TextureImporter", Importer = "TextureImporter",
ImporterConfig = (GlitchyEditor.Assets.Importers.TextureImporterConfig){ ImporterConfig = null,
_isSrgb = false Processor = null,
}, ProcessorConfig = null,
Processor = "TextureProcessor", Exporter = null,
ProcessorConfig = (GlitchyEditor.Assets.Processors.TextureProcessorConfig){ ExporterConfig = null,
_generateMipMaps = .No, AssetHandle = 17408033053158961990
_samplerStateDescription = {
MinFilter = .Linear,
MagFilter = .Linear,
MipFilter = .Linear,
FilterMode = .Default,
ComparisonFunction = .Never,
AddressModeU = .Clamp,
AddressModeV = .Clamp,
AddressModeW = .Clamp,
MipLODBias = 0,
MipMinLOD = -3.40282347e+38,
MipMaxLOD = 3.40282347e+38,
MaxAnisotropy = 1,
BorderColor = {
R = 1,
G = 1,
B = 1,
A = 1
}
}
},
Exporter = "TextureExporter",
ExporterConfig = {
_compression = .LZ4
},
AssetHandle = 17972970543152031508
} }
@@ -5,21 +5,21 @@
ImporterConfig = (GlitchyEditor.Assets.Importers.TextureImporterConfig){ ImporterConfig = (GlitchyEditor.Assets.Importers.TextureImporterConfig){
_isSrgb = false _isSrgb = false
}, },
Processor = "TextureProcessor", Processor = null,
ProcessorConfig = (GlitchyEditor.Assets.Processors.TextureProcessorConfig){ ProcessorConfig = (GlitchyEditor.Assets.Processors.TextureProcessorConfig){
_generateMipMaps = .No, _generateMipMaps = .No,
_samplerStateDescription = { _samplerStateDescription = {
MinFilter = .Point, MinFilter = .Linear,
MagFilter = .Point, MagFilter = .Linear,
MipFilter = .Point, MipFilter = .Linear,
FilterMode = .Default, FilterMode = .Default,
ComparisonFunction = .Never, ComparisonFunction = .Never,
AddressModeU = .Clamp, AddressModeU = .Clamp,
AddressModeV = .Clamp, AddressModeV = .Clamp,
AddressModeW = .Clamp, AddressModeW = .Clamp,
MipLODBias = 0, MipLODBias = 0,
MipMinLOD = -3.40282347e+38, MipMinLOD = -Infinity,
MipMaxLOD = 3.40282347e+38, MipMaxLOD = Infinity,
MaxAnisotropy = 1, MaxAnisotropy = 1,
BorderColor = { BorderColor = {
R = 1, R = 1,
@@ -27,11 +27,14 @@
B = 1, B = 1,
A = 1 A = 1
} }
}
}, },
Exporter = "TextureExporter", _textureType = .Texture,
_sprites = [
]
},
Exporter = null,
ExporterConfig = { ExporterConfig = {
_compression = .None _compression = .None
}, },
AssetHandle = 8620184366354358183 AssetHandle = 6043007137039118289
} }
@@ -5,7 +5,7 @@
ImporterConfig = (GlitchyEditor.Assets.Importers.TextureImporterConfig){ ImporterConfig = (GlitchyEditor.Assets.Importers.TextureImporterConfig){
_isSrgb = false _isSrgb = false
}, },
Processor = "TextureProcessor", Processor = null,
ProcessorConfig = (GlitchyEditor.Assets.Processors.TextureProcessorConfig){ ProcessorConfig = (GlitchyEditor.Assets.Processors.TextureProcessorConfig){
_generateMipMaps = .No, _generateMipMaps = .No,
_samplerStateDescription = { _samplerStateDescription = {
@@ -18,8 +18,8 @@
AddressModeV = .Clamp, AddressModeV = .Clamp,
AddressModeW = .Clamp, AddressModeW = .Clamp,
MipLODBias = 0, MipLODBias = 0,
MipMinLOD = -3.40282347e+38, MipMinLOD = -Infinity,
MipMaxLOD = 3.40282347e+38, MipMaxLOD = Infinity,
MaxAnisotropy = 1, MaxAnisotropy = 1,
BorderColor = { BorderColor = {
R = 1, R = 1,
@@ -27,11 +27,14 @@
B = 1, B = 1,
A = 1 A = 1
} }
}
}, },
Exporter = "TextureExporter", _textureType = .Texture,
_sprites = [
]
},
Exporter = null,
ExporterConfig = { ExporterConfig = {
_compression = .None _compression = .None
}, },
AssetHandle = 7647313657967374590 AssetHandle = 1772897904610089584
} }
+17 -12
View File
@@ -63,7 +63,7 @@ class AssetFile
public EditorContentManager ContentManager => _contentManager; public EditorContentManager ContentManager => _contentManager;
public bool UseNewAssetPipeline => _assetConfig?.ImporterConfig != null; public bool UseNewAssetPipeline => _assetConfig?.Importer != null;
[AllowAppend] [AllowAppend]
public this(EditorContentManager contentManager, AssetNode assetNode) public this(EditorContentManager contentManager, AssetNode assetNode)
@@ -141,8 +141,8 @@ class AssetFile
GenerateAssetHandle(); GenerateAssetHandle();
IAssetImporter assetImporter = _contentManager.GetAssetImporter(fileExtension); IAssetImporter assetImporter = _contentManager.GetAssetImporter(fileExtension);
IAssetProcessor assetProcessor = ?; //_contentManager.GetAssetProcessor(assetImporter.); //IAssetProcessor assetProcessor = ?; //_contentManager.GetAssetProcessor(assetImporter.);
IAssetExporter assetExporter = ?; //_contentManager.GetAssetProcessor(assetImporter.); //IAssetExporter assetExporter = ?; //_contentManager.GetAssetProcessor(assetImporter.);
// TODO! // TODO!
//if (assetPipeline case .Err) //if (assetPipeline case .Err)
@@ -165,15 +165,6 @@ class AssetFile
_assetConfig.Importer = new String(); _assetConfig.Importer = new String();
assetImporter?.GetType()?.GetName(_assetConfig.Importer); assetImporter?.GetType()?.GetName(_assetConfig.Importer);
_assetConfig.ImporterConfig = assetImporter?.CreateDefaultConfig();
_assetConfig.Processor = new String();
assetProcessor?.GetType()?.GetName(_assetConfig.Processor);
_assetConfig.ProcessorConfig = assetProcessor.CreateDefaultConfig();
_assetConfig.Exporter = new String();
assetExporter?.GetType()?.GetName(_assetConfig.Exporter);
_assetConfig.ExporterConfig = assetExporter.CreateDefaultConfig();
SaveAssetConfig(); SaveAssetConfig();
} }
@@ -195,6 +186,17 @@ class AssetFile
_assetConfig = newAssetConfig; _assetConfig = newAssetConfig;
} }
public void SaveAssetConfigIfChanged()
{
if (_assetConfig.Config?.Changed == true ||
_assetConfig.ImporterConfig?.Changed == true ||
_assetConfig.ProcessorConfig?.Changed == true ||
_assetConfig.ExporterConfig?.Changed == true)
{
SaveAssetConfig();
}
}
public void SaveAssetConfig() public void SaveAssetConfig()
{ {
//BonEnvironment bonEnv = scope .(); //BonEnvironment bonEnv = scope .();
@@ -206,6 +208,9 @@ class AssetFile
Bon.SerializeIntoFile(_assetConfig, _assetConfigPath); Bon.SerializeIntoFile(_assetConfig, _assetConfigPath);
_assetConfig.Config?.[Friend]_changed = false; _assetConfig.Config?.[Friend]_changed = false;
_assetConfig.ImporterConfig?.[Friend]_changed = false;
_assetConfig.ProcessorConfig?.[Friend]_changed = false;
_assetConfig.ExporterConfig?.[Friend]_changed = false;
gBonEnv.serializeFlags = oldFlags; gBonEnv.serializeFlags = oldFlags;
} }
+48 -27
View File
@@ -46,36 +46,21 @@ class AssetConverter
private void Process(AssetFile assetFile) private void Process(AssetFile assetFile)
{ {
IAssetImporter importer = _contentManager.GetAssetImporter(assetFile); Result<ImportedResource> importResult = ImportResource(assetFile);
IAssetProcessor processor = _contentManager.GetAssetProcessor(assetFile);
if (importer == null) ImportedResource importedResource = null;
{ defer { delete importedResource; }
Log.EngineLogger.Error("Importer is null!");
return;
}
if (processor == null) if (!(importResult case .Ok(out importedResource)))
{
Log.EngineLogger.Error("Processor is null!");
return;
}
Result<ImportedResource> importResult = importer.Import(assetFile.AssetFile.Path,
assetFile.AssetFile.Identifier, assetFile.AssetConfig.ImporterConfig);
if (importResult case .Err)
{ {
Log.EngineLogger.Error("Failed to import asset!"); Log.EngineLogger.Error("Failed to import asset!");
return; return;
} }
defer { delete importResult.Value; } List<ProcessedResource> processedResources = scope .();
defer { ClearAndDeleteItems!(processedResources); }
List<ProcessedResource> resources = scope .(); Result<void> processResult = ProcessResource(assetFile, importedResource, processedResources);
defer { ClearAndDeleteItems!(resources); }
Result<void> processResult = processor.Process(importResult.Value, assetFile.AssetConfig.ProcessorConfig, resources);
if (processResult case .Err) if (processResult case .Err)
{ {
@@ -83,11 +68,40 @@ class AssetConverter
return; return;
} }
for (ProcessedResource resource in resources) for (ProcessedResource resource in processedResources)
{ {
TrySilent!(ExportResource(assetFile, resource)); if (ExportResource(assetFile, resource) case .Err)
{
Log.EngineLogger.Error("Failed to export asset.");
} }
} }
}
private Result<ImportedResource> ImportResource(AssetFile assetFile)
{
IAssetImporter importer = _contentManager.GetAssetImporter(assetFile);
if (importer == null)
{
Log.EngineLogger.Error("Importer is null!");
return .Err;
}
return importer.Import(assetFile.AssetFile.Path, assetFile.AssetFile.Identifier, assetFile.AssetConfig);
}
private Result<void> ProcessResource(AssetFile assetFile, ImportedResource importedResource, List<ProcessedResource> outProcessedResources)
{
IAssetProcessor processor = _contentManager.GetAssetProcessor(importedResource.GetType());
if (processor == null)
{
Log.EngineLogger.Error($"No asset processor for type {importedResource.GetType()} found.");
return .Err;
}
return processor.Process(importedResource, assetFile.AssetConfig, outProcessedResources);
}
private Result<void> ExportResource(AssetFile assetFile, ProcessedResource resource) private Result<void> ExportResource(AssetFile assetFile, ProcessedResource resource)
{ {
@@ -101,7 +115,7 @@ class AssetConverter
MemoryStream memoryStream = scope .(); MemoryStream memoryStream = scope .();
Result<void> exportResult = exporter.Export(memoryStream, resource, assetFile.AssetConfig.ExporterConfig); Result<void> exportResult = exporter.Export(memoryStream, resource, assetFile.AssetConfig);
if (exportResult case .Err) if (exportResult case .Err)
{ {
@@ -109,11 +123,16 @@ class AssetConverter
return .Err; return .Err;
} }
if (assetFile.AssetConfig.ExporterConfig == null)
{
assetFile.AssetConfig.ExporterConfig = new AssetExporterConfig();
}
CachedAsset assetInfo = scope CachedAsset(); CachedAsset assetInfo = scope CachedAsset();
assetInfo.Handle = assetFile.AssetConfig.AssetHandle; assetInfo.Handle = resource.AssetHandle;
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(resource.AssetIdentifier);
assetInfo.AssetType = resource.AssetType; assetInfo.AssetType = resource.AssetType;
if (_contentManager.AssetCache.SaveAsset(assetInfo, memoryStream.Memory) case .Err) if (_contentManager.AssetCache.SaveAsset(assetInfo, memoryStream.Memory) case .Err)
@@ -122,6 +141,8 @@ class AssetConverter
return .Err; return .Err;
} }
assetFile.SaveAssetConfigIfChanged();
return .Ok; return .Ok;
} }
} }
+1
View File
@@ -2,6 +2,7 @@ using System;
using System.Collections; using System.Collections;
using GlitchyEngine.Renderer; using GlitchyEngine.Renderer;
using GlitchyEngine.Content; using GlitchyEngine.Content;
namespace GlitchyEditor.Assets; namespace GlitchyEditor.Assets;
// TODO: Why exactly are AssetFile and AssetNode separated? // TODO: Why exactly are AssetFile and AssetNode separated?
@@ -0,0 +1,39 @@
using System;
using System.IO;
using GlitchyEngine.Renderer;
using GlitchyEditor.Assets.Processors;
using GlitchyEngine;
using GlitchyEditor.Assets.Importers;
using GlitchyEngine.Content;
namespace GlitchyEditor.Assets.Exporters;
class SpriteExporter : IAssetExporter
{
public static AssetType ExportedAssetType => .Sprite;
public AssetExporterConfig CreateDefaultConfig()
{
return new AssetExporterConfig();
}
public Result<void> Export(Stream stream, ProcessedResource processedResource, AssetConfig config)
{
Log.EngineLogger.AssertDebug(processedResource is ProcessedSprite);
ProcessedSprite processedSprite = (.)processedResource;
/*
File Format:
TextureHandle (8 bytes)
TextureCoords (16 bytes) [float4]
*/
Try!(stream.Write(processedSprite.TextureHandle));
Try!(stream.Write(processedSprite.TextureCoordinates));
return .Ok;
}
}
@@ -17,7 +17,7 @@ class TextureExporter : IAssetExporter
return new AssetExporterConfig(); return new AssetExporterConfig();
} }
public Result<void> Export(Stream stream, ProcessedResource processedResource, AssetExporterConfig config) public Result<void> Export(Stream stream, ProcessedResource processedResource, AssetConfig config)
{ {
Log.EngineLogger.AssertDebug(processedResource is ProcessedTexture); Log.EngineLogger.AssertDebug(processedResource is ProcessedTexture);
+1 -1
View File
@@ -8,7 +8,7 @@ namespace GlitchyEditor.Assets.Importers;
abstract class Config abstract class Config
{ {
[BonIgnore] [BonIgnore]
protected bool _changed; protected bool _changed = true;
public bool Changed => _changed; public bool Changed => _changed;
@@ -15,7 +15,7 @@ interface IAssetImporter
/// The type that ImportedResource returns. /// The type that ImportedResource returns.
static Type ProcessedAssetType { get; } static Type ProcessedAssetType { get; }
Result<ImportedResource> Import(StringView fullFileName, AssetIdentifier assetIdentifier, AssetImporterConfig config); Result<ImportedResource> Import(StringView fullFileName, AssetIdentifier assetIdentifier, AssetConfig config);
} }
interface IAssetProcessor interface IAssetProcessor
@@ -25,7 +25,7 @@ interface IAssetProcessor
/// The asset type that this processor can process. /// The asset type that this processor can process.
static Type ProcessedAssetType { get; } static Type ProcessedAssetType { get; }
Result<void> Process(ImportedResource importedResource, AssetProcessorConfig config, List<ProcessedResource> outProcessedResources); Result<void> Process(ImportedResource importedResource, AssetConfig config, List<ProcessedResource> outProcessedResources);
} }
interface IAssetExporter interface IAssetExporter
@@ -35,5 +35,5 @@ interface IAssetExporter
/// The asset type that this exporter can export. /// The asset type that this exporter can export.
static AssetType ExportedAssetType { get; } static AssetType ExportedAssetType { get; }
Result<void> Export(Stream stream, ProcessedResource processedObject, AssetExporterConfig config); Result<void> Export(Stream stream, ProcessedResource processedObject, AssetConfig config);
} }
@@ -6,6 +6,7 @@ using GlitchyEngine.Content;
using GlitchyEngine; using GlitchyEngine;
using GlitchyEngine.Renderer; using GlitchyEngine.Renderer;
using GlitchyEngine.Math; using GlitchyEngine.Math;
//using System.Threading;
using GlitchyEditor.Assets.Processors; using GlitchyEditor.Assets.Processors;
using ImGui; using ImGui;
@@ -53,22 +54,29 @@ class TextureImporterConfig : AssetImporterConfig
} }
} }
class TextureImporter : IAssetImporter class TextureImporter : IAssetImporter
{ {
private static readonly List<StringView> _fileExtensions = new .(){".png", ".dds"} ~ delete _; private static readonly List<StringView> _fileExtensions = new .(){".png", ".dds"} ~ delete _;
public static List<StringView> FileExtensions => _fileExtensions; public static List<StringView> FileExtensions => _fileExtensions;
public static Type ProcessedAssetType => typeof(ImportedTexture);
public AssetImporterConfig CreateDefaultConfig() public AssetImporterConfig CreateDefaultConfig()
{ {
return new TextureImporterConfig(); return new TextureImporterConfig();
} }
public Result<ImportedResource> Import(StringView fullFileName, AssetIdentifier assetIdentifier, AssetImporterConfig config) public Result<ImportedResource> Import(StringView fullFileName, AssetIdentifier assetIdentifier, AssetConfig config)
{ {
//Thread.Sleep(1000);
Log.EngineLogger.AssertDebug(config is TextureImporterConfig); TextureImporterConfig textureImporterConfig = config.ImporterConfig as TextureImporterConfig;
if (textureImporterConfig == null)
{
config.ImporterConfig = textureImporterConfig = new TextureImporterConfig();
}
ImportedTexture importedData = new ImportedTexture(new AssetIdentifier(assetIdentifier.FullIdentifier)); ImportedTexture importedData = new ImportedTexture(new AssetIdentifier(assetIdentifier.FullIdentifier));
@@ -76,7 +84,7 @@ class TextureImporter : IAssetImporter
FileStream stream = scope FileStream(); FileStream stream = scope FileStream();
Try!(stream.Open(fullFileName, .Read, .Read)); Try!(stream.Open(fullFileName, .Read, .Read));
Result<void> importResult = ImportTexture(stream, importedData, (TextureImporterConfig)config); Result<void> importResult = ImportTexture(stream, importedData, (TextureImporterConfig)textureImporterConfig);
stream.Close(); stream.Close();
@@ -6,12 +6,17 @@ abstract class ProcessedResource
{ {
private AssetIdentifier _assetIdentifier ~ delete _; private AssetIdentifier _assetIdentifier ~ delete _;
private AssetHandle _assetHandle;
public AssetIdentifier AssetIdentifier => _assetIdentifier; public AssetIdentifier AssetIdentifier => _assetIdentifier;
public AssetHandle AssetHandle => _assetHandle;
public abstract AssetType AssetType {get;} public abstract AssetType AssetType {get;}
public this(AssetIdentifier ownAssetIdentifier) public this(AssetIdentifier ownAssetIdentifier, AssetHandle assetHandle)
{ {
_assetIdentifier = ownAssetIdentifier; _assetIdentifier = ownAssetIdentifier;
_assetHandle = assetHandle;
} }
} }
@@ -60,6 +60,12 @@ class TextureProcessorConfig : AssetProcessorConfig
public List<SpriteDesc> Sprites => _sprites; public List<SpriteDesc> Sprites => _sprites;
public void AddSprite(SpriteDesc sprite)
{
_sprites.Add(sprite);
_changed = true;
}
public override void ShowEditor(AssetFile assetFile) public override void ShowEditor(AssetFile assetFile)
{ {
if (ImGui.BeginPopupModal("Apply Changes", null, .AlwaysAutoResize)) if (ImGui.BeginPopupModal("Apply Changes", null, .AlwaysAutoResize))
@@ -227,11 +233,18 @@ class TextureProcessorConfig : AssetProcessorConfig
} }
} }
[BonTarget]
enum TextureCoordinates
{
case Pixel(int2 Min, int2 Max);
case Relative(float2 Offset, float2 Size);
}
[BonTarget]
public class SpriteDesc public class SpriteDesc
{ {
public String Name ~ delete _; public String Name ~ delete _;
public int2 TopLeft; public TextureCoordinates TextureCoordinates;
public int2 Size;
public AssetHandle AssetHandle; public AssetHandle AssetHandle;
} }
@@ -308,7 +321,7 @@ class ProcessedTexture : ProcessedResource
public TextureSurface[,] Surfaces; public TextureSurface[,] Surfaces;
public this(AssetIdentifier ownAssetIdentifier) : base(ownAssetIdentifier) public this(AssetIdentifier ownAssetIdentifier, AssetHandle assetHandle) : base(ownAssetIdentifier, assetHandle)
{ {
} }
@@ -358,21 +371,18 @@ class ProcessedSprite : ProcessedResource
{ {
public override AssetType AssetType => .Sprite; public override AssetType AssetType => .Sprite;
private AssetHandle _texture; private AssetHandle Handle;
private int2 _topLeft; private float4 _textureCoordinates;
private int2 _size;
public AssetHandle Texture => _texture; public AssetHandle TextureHandle => Handle;
public int2 TopLeft => _topLeft; public float4 TextureCoordinates => _textureCoordinates;
public int2 Size => _size;
public this(AssetIdentifier ownAssetIdentifier, AssetHandle texture, int2 topLeft, int2 size) : base(ownAssetIdentifier) public this(AssetIdentifier ownAssetIdentifier, AssetHandle assetHandle, AssetHandle textureHandle, float4 textureCoordinates) : base(ownAssetIdentifier, assetHandle)
{ {
_texture = texture; Handle = textureHandle;
_topLeft = topLeft; _textureCoordinates = textureCoordinates;
_size = size;
} }
} }
@@ -385,17 +395,23 @@ class TextureProcessor : IAssetProcessor
return new TextureProcessorConfig(); return new TextureProcessorConfig();
} }
public Result<void> Process(ImportedResource importedObject, AssetProcessorConfig config, List<ProcessedResource> outProcessedResources) public Result<void> Process(ImportedResource importedObject, AssetConfig config, List<ProcessedResource> outProcessedResources)
{ {
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, outProcessedResources)); TextureProcessorConfig textureProcessorConfig = config.ProcessorConfig as TextureProcessorConfig;
if (textureProcessorConfig == null)
{
config.ProcessorConfig = textureProcessorConfig = new TextureProcessorConfig();
} }
private Result<void> ProcessTexture(ImportedTexture importedTexture, TextureProcessorConfig config, List<ProcessedResource> outProcessedResources) return Try!(ProcessTexture(importedObject as ImportedTexture, config, textureProcessorConfig, outProcessedResources));
}
private Result<void> ProcessTexture(ImportedTexture importedTexture, AssetConfig assetConfig, TextureProcessorConfig textureConfig, List<ProcessedResource> outProcessedResources)
{ {
ProcessedTexture processedTexture = new ProcessedTexture(new AssetIdentifier(importedTexture.AssetIdentifier.FullIdentifier)); ProcessedTexture processedTexture = new ProcessedTexture(new AssetIdentifier(importedTexture.AssetIdentifier.FullIdentifier), assetConfig.AssetHandle);
processedTexture.Dimension = importedTexture.TextureInfo.Dimension; processedTexture.Dimension = importedTexture.TextureInfo.Dimension;
processedTexture.PixelFormat = (.)importedTexture.TextureInfo.PixelFormat; processedTexture.PixelFormat = (.)importedTexture.TextureInfo.PixelFormat;
@@ -404,7 +420,7 @@ class TextureProcessor : IAssetProcessor
processedTexture.Height = importedTexture.TextureInfo.Height; processedTexture.Height = importedTexture.TextureInfo.Height;
processedTexture.Depth = importedTexture.TextureInfo.Depth; processedTexture.Depth = importedTexture.TextureInfo.Depth;
processedTexture.SamplerStateDescription = config.SamplerStateDescription; processedTexture.SamplerStateDescription = textureConfig.SamplerStateDescription;
processedTexture.SetSurfaceCount(importedTexture.TextureInfo.ArraySize, importedTexture.TextureInfo.MipMapCount); processedTexture.SetSurfaceCount(importedTexture.TextureInfo.ArraySize, importedTexture.TextureInfo.MipMapCount);
@@ -416,22 +432,25 @@ class TextureProcessor : IAssetProcessor
processedTexture.Surfaces[loadedSurface.ArrayIndex * (processedTexture.IsCubeMap ? 6 : 1) + loadedSurface.CubeFace, loadedSurface.MipLevel] = surface; processedTexture.Surfaces[loadedSurface.ArrayIndex * (processedTexture.IsCubeMap ? 6 : 1) + loadedSurface.CubeFace, loadedSurface.MipLevel] = surface;
} }
if (!(config.GenerateMipMaps case .No)) if (!(textureConfig.GenerateMipMaps case .No))
{ {
// TODO: Unpack BC-Formats to RGBA // TODO: Unpack BC-Formats to RGBA
GenerateMipMaps(processedTexture, config); GenerateMipMaps(processedTexture, textureConfig);
} }
outProcessedResources.Add(processedTexture);
// TODO: Pack to BC-Format or what ever was selected. // TODO: Pack to BC-Format or what ever was selected.
if (config.TextureType == .Sprite) if (textureConfig.TextureType == .Sprite)
{ {
CreateSprites(processedTexture, textureConfig, outProcessedResources);
} }
return .Ok; return .Ok;
} }
private void CreateSprites(ProcessedTexture processedTexture, TextureProcessorConfig config, List<ProcessedResource> outProcessedResources) private void CreateSprites(ProcessedTexture processedTexture, TextureProcessorConfig textureConfig, List<ProcessedResource> outProcessedResources)
{ {
if (processedTexture.Dimension != .Texture2D) if (processedTexture.Dimension != .Texture2D)
{ {
@@ -439,15 +458,41 @@ class TextureProcessor : IAssetProcessor
return; return;
} }
if (config.Sprites.Count == 0) if (textureConfig.Sprites.Count == 0)
{ {
/*ProcessedSprite sprite = new ProcessedSprite(processedTexture.); textureConfig.AddSprite(new SpriteDesc(){
processedTexture.Sprites.Add(new SpriteDesc(){
Name = new String("Sprite"), Name = new String("Sprite"),
TopLeft = .(0, 0), // TODO: Maybe add a switch for pixel perfect or relative texture coordinates
Size = .((.)processedTexture.Width, (.)processedTexture.Height) TextureCoordinates = .Pixel(.(0, 0), .((.)processedTexture.Width, (.)processedTexture.Height)),
});*/ // TODO: Get handle from central authority (contentmanager?)
AssetHandle = AssetHandle()
});
}
float2 textureResolution = .(processedTexture.Width, processedTexture.Height);
for (SpriteDesc spriteDesc in textureConfig.Sprites)
{
float4 textureCoordinates = .();
if (spriteDesc.TextureCoordinates case .Pixel(let min, let max))
{
textureCoordinates = float4((float2)min / textureResolution, (float2)max / textureResolution);
}
else if (spriteDesc.TextureCoordinates case .Relative(let offset, let size))
{
textureCoordinates = .(offset, size);
}
else
{
Log.EngineLogger.Error($"Unknown texture coordinate type {spriteDesc.TextureCoordinates}");
return;
}
ProcessedSprite sprite = new ProcessedSprite(new AssetIdentifier(processedTexture.AssetIdentifier, spriteDesc.Name), spriteDesc.AssetHandle, processedTexture.AssetHandle,
textureCoordinates);
outProcessedResources.Add(sprite);
} }
} }
+2 -1
View File
@@ -24,6 +24,7 @@ namespace GlitchyEditor
{ {
_contentManager = new EditorContentManager(); _contentManager = new EditorContentManager();
// TODO: Get rid of legacy loaders
_contentManager.RegisterAssetLoader<ModelAssetLoader>(); _contentManager.RegisterAssetLoader<ModelAssetLoader>();
_contentManager.SetAsDefaultAssetLoader<ModelAssetLoader>(".glb", ".gltf"); _contentManager.SetAsDefaultAssetLoader<ModelAssetLoader>(".glb", ".gltf");
_contentManager.SetAssetPropertiesEditor<ModelAssetLoader>(=> ModelAssetPropertiesEditor.Factory); _contentManager.SetAssetPropertiesEditor<ModelAssetLoader>(=> ModelAssetPropertiesEditor.Factory);
@@ -40,7 +41,7 @@ namespace GlitchyEditor
_contentManager.RegisterAssetProcessor<TextureProcessor>(); _contentManager.RegisterAssetProcessor<TextureProcessor>();
_contentManager.RegisterAssetExporter<TextureExporter>(); _contentManager.RegisterAssetExporter<TextureExporter>();
_contentManager.ConfigureDefaultProcessing<TextureImporter, TextureProcessor, TextureExporter>(".png", ".dds"); _contentManager.RegisterAssetExporter<SpriteExporter>();
_contentManager.SetGlobalAssetCacheDirectory(".cache"); _contentManager.SetGlobalAssetCacheDirectory(".cache");
_contentManager.SetResourcesDirectory("Resources"); _contentManager.SetResourcesDirectory("Resources");
+43 -154
View File
@@ -198,15 +198,6 @@ class EditorContentManager : IContentManager
return null; return null;
} }
// TODO: This type sucks!
public Result<(IAssetImporter Importer, IAssetProcessor Processor, IAssetExporter Exporter)> GetDefaultProcessors(StringView fileExtension)
{
if (_defaultAssetProcessors.TryGetValue(fileExtension, let value))
return value;
return .Err;
}
private append List<String> _supportedExtensions = .() ~ ClearAndDeleteItems!(_); private append List<String> _supportedExtensions = .() ~ ClearAndDeleteItems!(_);
private append List<IAssetLoader> _assetLoaders = .() ~ ClearAndDeleteItems!(_); private append List<IAssetLoader> _assetLoaders = .() ~ ClearAndDeleteItems!(_);
private append Dictionary<StringView, IAssetLoader> _defaultAssetLoaders = .(); private append Dictionary<StringView, IAssetLoader> _defaultAssetLoaders = .();
@@ -220,12 +211,8 @@ class EditorContentManager : IContentManager
private append List<IAssetImporter> _assetImporters = .() ~ ClearAndDeleteItems!(_); private append List<IAssetImporter> _assetImporters = .() ~ ClearAndDeleteItems!(_);
private append Dictionary<StringView, IAssetImporter> _extensionToAssetImporter = .(); private append Dictionary<StringView, IAssetImporter> _extensionToAssetImporter = .();
private append List<IAssetProcessor> _assetProcessors = .() ~ ClearAndDeleteItems!(_); private append Dictionary<Type, IAssetProcessor> _importedResourceToAssetProcessor = .() ~ ClearDictionaryAndDeleteValues!(_);
private append Dictionary<Type, IAssetProcessor> _importedResourceToAssetProcessor = .(); private append Dictionary<AssetType, IAssetExporter> _assetTypeToAssetExporter = .() ~ ClearDictionaryAndDeleteValues!(_);
//private append List<IAssetExporter> _assetExporters = .() ~ ClearAndDeleteItems!(_);
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
{ {
@@ -242,7 +229,6 @@ class EditorContentManager : IContentManager
public void RegisterAssetImporter<T>() where T : new, class, IAssetImporter public void RegisterAssetImporter<T>() where T : new, class, IAssetImporter
{ {
T assetImporter = new T(); T assetImporter = new T();
_assetImporters.Add(assetImporter); _assetImporters.Add(assetImporter);
for (StringView ext in T.FileExtensions) for (StringView ext in T.FileExtensions)
@@ -255,18 +241,16 @@ class EditorContentManager : IContentManager
public void RegisterAssetProcessor<T>() where T : new, class, IAssetProcessor public void RegisterAssetProcessor<T>() where T : new, class, IAssetProcessor
{ {
T assetProcessor = new T(); Log.EngineLogger.AssertDebug(!_importedResourceToAssetProcessor.ContainsKey(T.ProcessedAssetType), "Cannot register multiple processor for the same imported resource type.");
_assetProcessors.Add(assetProcessor); _importedResourceToAssetProcessor.Add(T.ProcessedAssetType, new T());
} }
public void RegisterAssetExporter<T>() where T : new, class, IAssetExporter public void RegisterAssetExporter<T>() where T : new, class, IAssetExporter
{ {
T assetExporter = new T(); Log.EngineLogger.AssertDebug(!_assetTypeToAssetExporter.ContainsKey(T.ExportedAssetType), "Cannot register multiple exporters for one asset type.");
Log.EngineLogger.AssertDebug(_assetExporters.ContainsKey(T.ExportedAssetType), "Cannot register multiple exporters for one asset type."); _assetTypeToAssetExporter.Add(T.ExportedAssetType, new T());
_assetExporters.Add(T.ExportedAssetType, assetExporter);
} }
public IAssetImporter GetAssetImporter(StringView fileExtension) public IAssetImporter GetAssetImporter(StringView fileExtension)
@@ -279,11 +263,41 @@ class EditorContentManager : IContentManager
return null; return null;
} }
public IAssetImporter GetAssetProcessor(Type importedResourceType) public IAssetImporter GetAssetImporter(AssetFile file)
{ {
if (_extensionToAssetImporter.TryGetValue(fileExtension, let importer)) IAssetImporter result = null;
String typeName = scope .(128);
for (IAssetImporter importer in _extensionToAssetImporter.Values)
{ {
return importer; importer.GetType().GetName(typeName..Clear());
if (typeName == file.AssetConfig.Importer)
{
result = importer;
break;
}
}
return result;
}
public IAssetProcessor GetAssetProcessor(Type importedResourceType)
{
if (_importedResourceToAssetProcessor.TryGetValue(importedResourceType, let processor))
{
return processor;
}
return null;
}
public IAssetExporter GetAssetExporter(AssetType assetType)
{
if (_assetTypeToAssetExporter.TryGetValue(assetType, let exporter))
{
return exporter;
} }
return null; return null;
@@ -318,64 +332,6 @@ class EditorContentManager : IContentManager
} }
} }
public void ConfigureDefaultProcessing<TImport, TProcess, TExport>(params Span<StringView> fileExtensions) where TImport : IAssetImporter where TProcess : IAssetProcessor where TExport : IAssetExporter
{
for (var ext in fileExtensions)
{
// Find file extension in registered file extensions
String foundExtension = null;
for (var supportedExt in _supportedExtensions)
{
if (supportedExt == ext)
{
foundExtension = supportedExt;
break;
}
}
Log.EngineLogger.Assert(foundExtension != null, "File Extension is not registered.");
//IAssetImporter importer = _assetImporters.Where((i) => i.GetType() == typeof(TImport)).First();
//IAssetProcessor processor = _assetProcessors.Where((i) => i.GetType() == typeof(TProcess)).First();
//IAssetExporter exporter = _assetExporters.Where((i) => i.GetType() == typeof(TExport)).First();
IAssetImporter importer = null;
IAssetProcessor processor = null;
IAssetExporter exporter = null;
for (var i in _assetImporters)
{
if (i.GetType() == typeof(TImport))
{
importer = i;
break;
}
}
for (var i in _assetProcessors)
{
if (i.GetType() == typeof(TProcess))
{
processor = i;
break;
}
}
// TODO: How do we get the exporter for the config?
/*for (var i in _assetExporters)
{
if (i.GetType() == typeof(TExport))
{
exporter = i;
break;
}
}*/
_defaultAssetProcessors[foundExtension] = (importer, processor, exporter);
}
}
public void SetAssetPropertiesEditor(Type assetLoaderType, function AssetPropertiesEditor(AssetFile) editorFactory) public void SetAssetPropertiesEditor(Type assetLoaderType, function AssetPropertiesEditor(AssetFile) editorFactory)
{ {
String loaderTypeName = new String(); String loaderTypeName = new String();
@@ -602,7 +558,7 @@ class EditorContentManager : IContentManager
if (resultNode case .Err) if (resultNode case .Err)
{ {
Log.EngineLogger.Error($"Could not find asset with handle {handle}."); Log.EngineLogger.Error($"Could not find asset with handle {handle} in hierarchy.");
return .Invalid; return .Invalid;
} }
@@ -748,76 +704,6 @@ class EditorContentManager : IContentManager
return assetLoader; return assetLoader;
} }
public IAssetImporter GetAssetImporter(AssetFile file)
{
IAssetImporter result = null;
String typeName = scope .(128);
for (IAssetImporter importer in _assetImporters)
{
importer.GetType().GetName(typeName..Clear());
if (typeName == file.AssetConfig.Importer)
{
result = importer;
break;
}
}
return result;
}
public IAssetProcessor GetAssetProcessor(AssetFile file)
{
IAssetProcessor result = null;
String typeName = scope .(128);
for (IAssetProcessor processor in _assetProcessors)
{
processor.GetType().GetName(typeName..Clear());
if (typeName == file.AssetConfig.Processor)
{
result = processor;
break;
}
}
return result;
}
/*
public IAssetExporter GetAssetExporter(AssetFile file)
{
IAssetExporter result = null;
String typeName = scope .(128);
for (IAssetExporter exporter in _assetExporters)
{
exporter.GetType().GetName(typeName..Clear());
if (typeName == file.AssetConfig.Exporter)
{
result = exporter;
break;
}
}
return result;
}
*/
public IAssetExporter GetAssetExporter(AssetType assetType)
{
if (_assetExporters.TryGetValue(assetType, let exporter))
{
return exporter;
}
return null;
}
public enum SaveAssetError public enum SaveAssetError
{ {
case Unknown; case Unknown;
@@ -1057,6 +943,7 @@ class EditorContentManager : IContentManager
// TODO: obviously use a map or something... // TODO: obviously use a map or something...
TextureLoader textureLoader = new .() ~ delete _; TextureLoader textureLoader = new .() ~ delete _;
SpriteLoader spriteLoader = new .() ~ delete _;
private IProcessedAssetLoader GetLoader(AssetType assetType) private IProcessedAssetLoader GetLoader(AssetType assetType)
{ {
@@ -1064,6 +951,8 @@ class EditorContentManager : IContentManager
{ {
case .Texture: case .Texture:
return textureLoader; return textureLoader;
case .Sprite:
return spriteLoader;
default: default:
return null; return null;
} }
+4 -4
View File
@@ -35,13 +35,13 @@ public class AssetIdentifier
[AllowAppend] [AllowAppend]
public this(StringView assetIdentifier, StringView subAssetIdentifier) public this(StringView assetIdentifier, StringView subAssetIdentifier)
{ {
String identifier = append String(assetIdentifier.Length + 1 + subAssetIdentifier.Length); String fullIdentifier = append String(assetIdentifier.Length + 1 + subAssetIdentifier.Length);
identifier.AppendF($"{assetIdentifier}:{subAssetIdentifier}"); fullIdentifier.AppendF($"{assetIdentifier}:{subAssetIdentifier}");
Fixup(identifier); Fixup(fullIdentifier);
_fullIdentifier = fullIdentifier;
_subassetSeperator = _fullIdentifier.IndexOf(':', 0); _subassetSeperator = _fullIdentifier.IndexOf(':', 0);
} }
public static StringView operator implicit(AssetIdentifier identifier) => identifier.FullIdentifier; public static StringView operator implicit(AssetIdentifier identifier) => identifier.FullIdentifier;
@@ -106,6 +106,19 @@ namespace GlitchyEngine.Content
return (T)asset; return (T)asset;
} }
/// Loads the specified asset with the given contentManager or the current applications content manager.
public static Asset GetAsset(AssetHandle handle, IContentManager contentManager = null)
{
var contentManager;
if (contentManager == null)
contentManager = Application.Instance.ContentManager;
Asset asset = contentManager.GetAsset(null, handle);
return asset;
}
public static AssetHandle ManageAsset(Asset asset, IContentManager contentManager = null) public static AssetHandle ManageAsset(Asset asset, IContentManager contentManager = null)
{ {
var contentManager; var contentManager;
+19
View File
@@ -0,0 +1,19 @@
using System;
using System.IO;
using System.Collections;
using GlitchyEngine.Math;
using GlitchyEngine.Renderer;
using System.Threading;
namespace GlitchyEngine.Content;
class SpriteLoader : IProcessedAssetLoader
{
public Result<Asset> Load(Stream dataStream)
{
AssetHandle textureHandle = Try!(dataStream.Read<AssetHandle>());
float4 textureCoordinates = Try!(dataStream.Read<float4>());
return new Sprite(textureHandle, textureCoordinates);
}
}
@@ -3,6 +3,7 @@ using System.IO;
using System.Collections; using System.Collections;
using GlitchyEngine.Math; using GlitchyEngine.Math;
using GlitchyEngine.Renderer; using GlitchyEngine.Renderer;
using System.Threading;
namespace GlitchyEngine.Content; namespace GlitchyEngine.Content;
@@ -73,6 +74,8 @@ class TextureLoader : IProcessedAssetLoader
result.SamplerState = samplerState; result.SamplerState = samplerState;
} }
//Thread.Sleep(1000);
return result; return result;
} }
+16 -1
View File
@@ -1091,7 +1091,22 @@ namespace GlitchyEngine.Renderer
public static void DrawSprite(Matrix transform, SpriteRendererComponent* spriteRenderer, uint32 entityId) public static void DrawSprite(Matrix transform, SpriteRendererComponent* spriteRenderer, uint32 entityId)
{ {
DrawQuad(transform, spriteRenderer.Sprite.Get() ?? s_whiteTexture, spriteRenderer.Color, spriteRenderer.UvTransform, entityId); Asset asset = Content.GetAsset(spriteRenderer.Sprite);
Texture2D spriteTexture = null;
float4 uvTransform = spriteRenderer.UvTransform;
if (Texture2D texture = asset as Texture2D)
{
spriteTexture = texture;
}
else if (Sprite sprite = asset as Sprite)
{
spriteTexture = Content.GetAsset<Texture2D>(sprite.TextureHandle);
uvTransform = sprite.TextureCoordinates;
}
DrawQuad(transform, spriteTexture ?? s_whiteTexture, spriteRenderer.Color, uvTransform, entityId);
} }
public static void DrawCircle(Matrix transform, CircleRendererComponent* spriteRenderer, uint32 entityId) public static void DrawCircle(Matrix transform, CircleRendererComponent* spriteRenderer, uint32 entityId)
+20
View File
@@ -0,0 +1,20 @@
using GlitchyEngine.Content;
using GlitchyEngine.Math;
namespace GlitchyEngine.Renderer;
class Sprite : Asset
{
private AssetHandle _textureHandle;
private float4 _textureCoordinates;
public AssetHandle TextureHandle => _textureHandle;
public float4 TextureCoordinates => _textureCoordinates;
public this(AssetHandle textureHandle, float4 textureCoordinates)
{
_textureHandle = textureHandle;
_textureCoordinates = textureCoordinates;
}
}
@@ -45,7 +45,7 @@ namespace GlitchyEngine.World
[Component("Sprite Renderer")] [Component("Sprite Renderer")]
struct SpriteRendererComponent struct SpriteRendererComponent
{ {
public AssetHandle<Texture2D> Sprite = .Invalid; public AssetHandle Sprite = .Invalid;
public ColorRGBA Color = .White; public ColorRGBA Color = .White;
public float4 UvTransform = .(0, 0, 1, 1); public float4 UvTransform = .(0, 0, 1, 1);