mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Use asset pipeline for blocking asset loading, remove old texture loader
This commit is contained in:
@@ -10,3 +10,5 @@ GlitchyEditor/MonoDebugger.log
|
|||||||
|
|
||||||
# Ignore files in build-directory of ScriptCore
|
# Ignore files in build-directory of ScriptCore
|
||||||
GlitchyEditor/Resources/Scripts/*
|
GlitchyEditor/Resources/Scripts/*
|
||||||
|
|
||||||
|
.cache
|
||||||
|
|||||||
@@ -1,14 +1,23 @@
|
|||||||
{
|
{
|
||||||
AssetLoader = "EditorTextureAssetLoader",
|
AssetLoader = null,
|
||||||
Config = (GlitchyEditor.Assets.EditorTextureAssetLoaderConfig){
|
Config = null,
|
||||||
|
Importer = "TextureImporter",
|
||||||
|
ImporterConfig = (GlitchyEditor.Assets.Importers.TextureImporterConfig){
|
||||||
|
_isSrgb = false
|
||||||
|
},
|
||||||
|
Processor = "TextureProcessor",
|
||||||
|
ProcessorConfig = (GlitchyEditor.Assets.Importers.TextureProcessorConfig){
|
||||||
|
_generateMipMaps = .No,
|
||||||
_samplerStateDescription = {
|
_samplerStateDescription = {
|
||||||
MinFilter = .Linear,
|
MinFilter = .Linear,
|
||||||
MagFilter = .Linear,
|
MagFilter = .Linear,
|
||||||
MipFilter = .Linear,
|
MipFilter = .Linear,
|
||||||
|
FilterMode = .Default,
|
||||||
ComparisonFunction = .Never,
|
ComparisonFunction = .Never,
|
||||||
AddressModeU = .Clamp,
|
AddressModeU = .Clamp,
|
||||||
AddressModeV = .Clamp,
|
AddressModeV = .Clamp,
|
||||||
AddressModeW = .Clamp,
|
AddressModeW = .Clamp,
|
||||||
|
MipLODBias = 0,
|
||||||
MipMinLOD = -3.40282347e+38,
|
MipMinLOD = -3.40282347e+38,
|
||||||
MipMaxLOD = 3.40282347e+38,
|
MipMaxLOD = 3.40282347e+38,
|
||||||
MaxAnisotropy = 1,
|
MaxAnisotropy = 1,
|
||||||
@@ -20,5 +29,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
AssetHandle = 16828117378770367285
|
Exporter = "TextureExporter",
|
||||||
|
ExporterConfig = {
|
||||||
|
_compression = .LZ4
|
||||||
|
},
|
||||||
|
AssetHandle = 17972970543152031508
|
||||||
}
|
}
|
||||||
@@ -149,14 +149,17 @@ class AssetFile
|
|||||||
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)
|
if (assetLoader == null && assetPipeline case .Err)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_assetConfig.AssetLoader = new String();
|
if (assetLoader != null)
|
||||||
assetLoader.GetType().GetName(_assetConfig.AssetLoader);
|
{
|
||||||
|
_assetConfig.AssetLoader = new String();
|
||||||
_assetConfig.Config = assetLoader?.GetDefaultConfig();
|
assetLoader.GetType().GetName(_assetConfig.AssetLoader);
|
||||||
_assetConfig.Config?.[Friend]_changed = true;
|
|
||||||
|
_assetConfig.Config = assetLoader?.GetDefaultConfig();
|
||||||
|
_assetConfig.Config?.[Friend]_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
_assetConfig.Importer = new String();
|
_assetConfig.Importer = new String();
|
||||||
assetPipeline?.Importer?.GetType()?.GetName(_assetConfig.Importer);
|
assetPipeline?.Importer?.GetType()?.GetName(_assetConfig.Importer);
|
||||||
|
|||||||
@@ -35,11 +35,13 @@ class AssetCache
|
|||||||
/// Current format version of loose asset file (.laf) file reader and writer.
|
/// Current format version of loose asset file (.laf) file reader and writer.
|
||||||
public const uint16 FormatVersion = 1;
|
public const uint16 FormatVersion = 1;
|
||||||
|
|
||||||
private append String _directory = .();// ~ delete:append _;
|
private append String _projectCacheDirectory = .();// ~ delete:append _;
|
||||||
|
private append String _globalCacheDirectory = .();// ~ delete:append _;
|
||||||
|
|
||||||
private append Dictionary<AssetHandle, CachedAsset> _assets = .();// ~ delete:append _;
|
private append Dictionary<AssetHandle, CachedAsset> _assets = .();// ~ delete:append _;
|
||||||
|
|
||||||
public StringView CacheDirectory => _directory;
|
public StringView ProjectCacheDirectory => _projectCacheDirectory;
|
||||||
|
public StringView GlobalCacheDirectory => _globalCacheDirectory;
|
||||||
|
|
||||||
private bool _cacheLoaded;
|
private bool _cacheLoaded;
|
||||||
|
|
||||||
@@ -60,11 +62,18 @@ class AssetCache
|
|||||||
_cacheLoaded = false;
|
_cacheLoaded = false;
|
||||||
ClearDictionaryAndDeleteValues!(_assets);
|
ClearDictionaryAndDeleteValues!(_assets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the directory in which the processed assets are cached.
|
||||||
|
public void SetGlobalCacheDirectory(StringView directory)
|
||||||
|
{
|
||||||
|
_globalCacheDirectory.Set(directory);
|
||||||
|
ReloadCache();
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the directory in which the processed assets are cached.
|
/// Sets the directory in which the processed assets are cached.
|
||||||
public void SetDirectory(StringView directory)
|
public void SetProjectCacheDirectory(StringView directory)
|
||||||
{
|
{
|
||||||
_directory.Set(directory);
|
_projectCacheDirectory.Set(directory);
|
||||||
ReloadCache();
|
ReloadCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,13 +82,24 @@ class AssetCache
|
|||||||
{
|
{
|
||||||
ClearCache();
|
ClearCache();
|
||||||
|
|
||||||
if (!Directory.Exists(_directory))
|
LoadCache(_globalCacheDirectory);
|
||||||
{
|
LoadCache(_projectCacheDirectory);
|
||||||
Log.EngineLogger.Info($"Asset cache directory doesn't exist, creating directory \"{_directory}\"...");
|
|
||||||
|
|
||||||
if (Directory.CreateDirectory(_directory) case .Err(let error))
|
_cacheLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadCache(StringView directory)
|
||||||
|
{
|
||||||
|
if (directory.IsWhiteSpace)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!Directory.Exists(directory))
|
||||||
|
{
|
||||||
|
Log.EngineLogger.Info($"Asset cache directory doesn't exist, creating directory \"{directory}\"...");
|
||||||
|
|
||||||
|
if (Directory.CreateDirectory(directory) case .Err(let error))
|
||||||
{
|
{
|
||||||
Log.EngineLogger.Critical($"Failed to create cache directory \"{_directory}\". Reason: {error}.");
|
Log.EngineLogger.Critical($"Failed to create cache directory \"{directory}\". Reason: {error}.");
|
||||||
Log.EngineLogger.Critical($"The engine will not function properly without the asset cache directory. Save your project and restart the engine.");
|
Log.EngineLogger.Critical($"The engine will not function properly without the asset cache directory. Save your project and restart the engine.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,9 +107,9 @@ class AssetCache
|
|||||||
// or we failed and can't do anything anyway.
|
// or we failed and can't do anything anyway.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String filePath = scope .();
|
String filePath = scope .();
|
||||||
for (FileFindEntry file in Directory.EnumerateFiles(_directory))
|
for (FileFindEntry file in Directory.EnumerateFiles(directory))
|
||||||
{
|
{
|
||||||
filePath.Clear();
|
filePath.Clear();
|
||||||
file.GetFilePath(filePath);
|
file.GetFilePath(filePath);
|
||||||
@@ -108,8 +128,6 @@ class AssetCache
|
|||||||
|
|
||||||
_assets.Add(cachedAsset.Handle, cachedAsset);
|
_assets.Add(cachedAsset.Handle, cachedAsset);
|
||||||
}
|
}
|
||||||
|
|
||||||
_cacheLoaded = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result<void> ReadAssetFile(StringView filePath, CachedAsset cachedAsset)
|
private Result<void> ReadAssetFile(StringView filePath, CachedAsset cachedAsset)
|
||||||
@@ -170,9 +188,17 @@ class AssetCache
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GetCacheFilePath(AssetHandle handle, String outFilePath)
|
private void GetProjectCacheFilePath(AssetHandle handle, String outFilePath)
|
||||||
{
|
{
|
||||||
outFilePath.Append(_directory);
|
outFilePath.Append(_projectCacheDirectory);
|
||||||
|
outFilePath.Append(Path.DirectorySeparatorChar);
|
||||||
|
outFilePath.Append(handle);
|
||||||
|
outFilePath.Append(CachedAsset.CacheFileExtension);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GetGlobalCacheFilePath(AssetHandle handle, String outFilePath)
|
||||||
|
{
|
||||||
|
outFilePath.Append(_globalCacheDirectory);
|
||||||
outFilePath.Append(Path.DirectorySeparatorChar);
|
outFilePath.Append(Path.DirectorySeparatorChar);
|
||||||
outFilePath.Append(handle);
|
outFilePath.Append(handle);
|
||||||
outFilePath.Append(CachedAsset.CacheFileExtension);
|
outFilePath.Append(CachedAsset.CacheFileExtension);
|
||||||
@@ -187,7 +213,12 @@ class AssetCache
|
|||||||
asset = new CachedAsset();
|
asset = new CachedAsset();
|
||||||
asset.Handle = assetInfo.Handle;
|
asset.Handle = assetInfo.Handle;
|
||||||
asset.FilePath = new String(128);
|
asset.FilePath = new String(128);
|
||||||
GetCacheFilePath(asset.Handle, asset.FilePath);
|
|
||||||
|
if (assetInfo.AssetIdentifier.IsResource)
|
||||||
|
GetGlobalCacheFilePath(asset.Handle, asset.FilePath);
|
||||||
|
else
|
||||||
|
GetProjectCacheFilePath(asset.Handle, asset.FilePath);
|
||||||
|
|
||||||
_assets[asset.Handle] = asset;
|
_assets[asset.Handle] = asset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,9 +18,12 @@ class AssetConverter
|
|||||||
_contentManager = contentManager;
|
_contentManager = contentManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void QueueForProcessing(AssetFile assetFile)
|
public void QueueForProcessing(AssetFile assetFile, bool isBlocking = false)
|
||||||
{
|
{
|
||||||
_queue.Add(assetFile);
|
if (!isBlocking)
|
||||||
|
_queue.Add(assetFile);
|
||||||
|
else
|
||||||
|
Process(assetFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
|
|||||||
@@ -375,12 +375,12 @@ class AssetHierarchy
|
|||||||
if (assetNode.IsInSubtree(_resourcesDirectoryNode))
|
if (assetNode.IsInSubtree(_resourcesDirectoryNode))
|
||||||
{
|
{
|
||||||
Path.GetRelativePath(assetNode->Path, _resourcesDirectoryNode->Path, identifier);
|
Path.GetRelativePath(assetNode->Path, _resourcesDirectoryNode->Path, identifier);
|
||||||
identifier.Insert(0, "Resources/");
|
identifier.Insert(0, AssetIdentifier.ResourcesPrefix);
|
||||||
}
|
}
|
||||||
else if (assetNode.IsInSubtree(_assetsDirectoryNode))
|
else if (assetNode.IsInSubtree(_assetsDirectoryNode))
|
||||||
{
|
{
|
||||||
Path.GetRelativePath(assetNode->Path, _assetsDirectoryNode->Path, identifier);
|
Path.GetRelativePath(assetNode->Path, _assetsDirectoryNode->Path, identifier);
|
||||||
identifier.Insert(0, "Assets/");
|
identifier.Insert(0, AssetIdentifier.AssetsPrefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete assetNode->Identifier;
|
delete assetNode->Identifier;
|
||||||
|
|||||||
@@ -1,596 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using Bon;
|
|
||||||
using System.IO;
|
|
||||||
using GlitchyEngine;
|
|
||||||
using GlitchyEngine.Content;
|
|
||||||
using GlitchyEngine.Renderer;
|
|
||||||
using GlitchyEngine.Math;
|
|
||||||
using DirectXTK;
|
|
||||||
using ImGui;
|
|
||||||
using GlitchyEditor.Assets.Importers;
|
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace GlitchyEditor.Assets;
|
|
||||||
|
|
||||||
class TextureAssetPropertiesEditor : AssetPropertiesEditor
|
|
||||||
{
|
|
||||||
EditorTextureAssetLoaderConfig _textureConfig;
|
|
||||||
|
|
||||||
public this(AssetFile asset) : base(asset)
|
|
||||||
{
|
|
||||||
_textureConfig = asset.AssetConfig.Config as EditorTextureAssetLoaderConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char8*[3] _filterFuncNames = char8*[]("Point", "Linear", "Anisotropic");
|
|
||||||
|
|
||||||
public override void ShowEditor()
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (_textureConfig == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool generateMips = _textureConfig.GenerateMipMaps;
|
|
||||||
if (ImGui.Checkbox("Generate Mip Maps", &generateMips))
|
|
||||||
_textureConfig.GenerateMipMaps = generateMips;
|
|
||||||
|
|
||||||
bool isSrgb = _textureConfig.IsSRGB;
|
|
||||||
if (ImGui.Checkbox("Is sRGB", &isSrgb))
|
|
||||||
_textureConfig.IsSRGB = isSrgb;
|
|
||||||
|
|
||||||
SamplerStateDescription samplerStateDescription = _textureConfig.SamplerStateDescription;
|
|
||||||
|
|
||||||
void ShowFilterCombo(String label, ref FilterFunction filterFunction)
|
|
||||||
{
|
|
||||||
int32 selectedFilter = filterFunction.Underlying;
|
|
||||||
if (ImGui.Combo(label, &selectedFilter, &_filterFuncNames, 3))
|
|
||||||
filterFunction = (.)selectedFilter;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.Separator();
|
|
||||||
ImGui.TextUnformatted("Texture Filtering:");
|
|
||||||
ImGui.Separator();
|
|
||||||
|
|
||||||
ImGui.EnumCombo("Min Filter", ref samplerStateDescription.MinFilter);
|
|
||||||
ImGui.AttachTooltip("""
|
|
||||||
Sampling method used for minification.
|
|
||||||
If set to "Anisotropic" all Filters are set to "Anisotropic" internally.
|
|
||||||
""");
|
|
||||||
ImGui.EnumCombo("Mag Filter", ref samplerStateDescription.MagFilter);
|
|
||||||
ImGui.AttachTooltip("""
|
|
||||||
Sampling method used for magnification.
|
|
||||||
If set to "Anisotropic" all Filters are set to "Anisotropic" internally.
|
|
||||||
""");
|
|
||||||
ImGui.EnumCombo("Mip Map Filter", ref samplerStateDescription.MipFilter);
|
|
||||||
ImGui.AttachTooltip("""
|
|
||||||
Method used for mip-level sampling.
|
|
||||||
If set to "Anisotropic" all Filters are set to "Anisotropic" internally.
|
|
||||||
""");
|
|
||||||
|
|
||||||
if (samplerStateDescription.MagFilter == .Anisotropic ||
|
|
||||||
samplerStateDescription.MinFilter == .Anisotropic ||
|
|
||||||
samplerStateDescription.MipFilter == .Anisotropic)
|
|
||||||
{
|
|
||||||
ImGui.SliderScalar("Anisotropy Level", ref samplerStateDescription.MaxAnisotropy, 1, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.NewLine();
|
|
||||||
|
|
||||||
ImGui.EnumCombo("Filter Mode", ref samplerStateDescription.FilterMode);
|
|
||||||
ImGui.AttachTooltip("Filtering method to use when sampling a texture.");
|
|
||||||
|
|
||||||
if (samplerStateDescription.FilterMode == .Comparison)
|
|
||||||
{
|
|
||||||
ImGui.EnumCombo("Comparison Function", ref samplerStateDescription.ComparisonFunction);
|
|
||||||
ImGui.AttachTooltip("""
|
|
||||||
The function that is used to compare the sampled data against the existing sampled data.
|
|
||||||
Only applies if Filter Mode is set to FilterMode.Comparison.
|
|
||||||
""");
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.Separator();
|
|
||||||
ImGui.TextUnformatted("Wrapping");
|
|
||||||
ImGui.Separator();
|
|
||||||
|
|
||||||
ImGui.EnumCombo("Wrap Mode U", ref samplerStateDescription.AddressModeU);
|
|
||||||
ImGui.AttachTooltip("Method to use for resolving a u texture coordinate that is outside the 0 to 1 range.");
|
|
||||||
|
|
||||||
ImGui.EnumCombo("Wrap Mode V", ref samplerStateDescription.AddressModeV);
|
|
||||||
ImGui.AttachTooltip("Method to use for resolving a v texture coordinate that is outside the 0 to 1 range.");
|
|
||||||
|
|
||||||
ImGui.EnumCombo("Wrap Mode W", ref samplerStateDescription.AddressModeW);
|
|
||||||
ImGui.AttachTooltip("Method to use for resolving a w texture coordinate that is outside the 0 to 1 range.");
|
|
||||||
|
|
||||||
if (samplerStateDescription.AddressModeU == .Border ||
|
|
||||||
samplerStateDescription.AddressModeV == .Border ||
|
|
||||||
samplerStateDescription.AddressModeW == .Border)
|
|
||||||
{
|
|
||||||
ImGui.ColorEdit4("Border Color", ref samplerStateDescription.BorderColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.Separator();
|
|
||||||
ImGui.TextUnformatted("Mip Maps");
|
|
||||||
ImGui.Separator();
|
|
||||||
|
|
||||||
ImGui.DragFloat("Mip LOD Bias", &samplerStateDescription.MipLODBias, 0.1f);
|
|
||||||
ImGui.AttachTooltip("""
|
|
||||||
Offset from the calculated mipmap level.
|
|
||||||
For example, if the GPU calculates that a texture should be sampled at mipmap level 3 and "Mip LOD Bias" is 2, then the texture will be sampled at mipmap level 5.
|
|
||||||
""");
|
|
||||||
|
|
||||||
ImGui.DragFloat("Min Mip LOD", &samplerStateDescription.MipMinLOD);
|
|
||||||
ImGui.AttachTooltip("Lower end of the mipmap range to clamp access to, where 0 is the largest and most detailed mipmap level and any level higher than that is less detailed.");
|
|
||||||
|
|
||||||
ImGui.DragFloat("Max LOD Bias", &samplerStateDescription.MipMaxLOD);
|
|
||||||
ImGui.AttachTooltip("""
|
|
||||||
Upper end of the mipmap range to clamp access to, where 0 is the largest and most detailed mipmap level and any level higher than that is less detailed.
|
|
||||||
This value must be greater than or equal to "Min Mip LOD". To have no upper limit on LOD set this to a large value.
|
|
||||||
""");
|
|
||||||
|
|
||||||
_textureConfig.SamplerStateDescription = samplerStateDescription;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AssetPropertiesEditor Factory(AssetFile assetFile)
|
|
||||||
{
|
|
||||||
return new TextureAssetPropertiesEditor(assetFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[BonTarget, BonPolyRegister]
|
|
||||||
class EditorTextureAssetLoaderConfig : AssetLoaderConfig
|
|
||||||
{
|
|
||||||
[BonInclude]
|
|
||||||
private bool _generateMipMaps;
|
|
||||||
|
|
||||||
[BonInclude]
|
|
||||||
private bool _isSrgb;
|
|
||||||
|
|
||||||
[BonInclude]
|
|
||||||
private SamplerStateDescription _samplerStateDescription = .();
|
|
||||||
|
|
||||||
public bool GenerateMipMaps
|
|
||||||
{
|
|
||||||
get => _generateMipMaps;
|
|
||||||
set => SetIfChanged(ref _generateMipMaps, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsSRGB
|
|
||||||
{
|
|
||||||
get => _isSrgb;
|
|
||||||
set => SetIfChanged(ref _isSrgb, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SamplerStateDescription SamplerStateDescription
|
|
||||||
{
|
|
||||||
get => _samplerStateDescription;
|
|
||||||
set => SetIfChanged(ref _samplerStateDescription, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
using internal GlitchyEngine.Renderer;
|
|
||||||
using internal GlitchyEngine.Platform.DX11;
|
|
||||||
|
|
||||||
class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
|
||||||
{
|
|
||||||
private static readonly List<StringView> _fileExtensions = new .(){".png", ".dds"} ~ delete _; // ".jpg", ".bmp"
|
|
||||||
|
|
||||||
public static List<StringView> FileExtensions => _fileExtensions;
|
|
||||||
|
|
||||||
public AssetLoaderConfig GetDefaultConfig()
|
|
||||||
{
|
|
||||||
return new EditorTextureAssetLoaderConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Asset LoadAsset(Stream data, AssetLoaderConfig config, StringView assetIdentifier, StringView? subAsset, IContentManager contentManager)
|
|
||||||
{
|
|
||||||
var config;
|
|
||||||
|
|
||||||
if (config == null)
|
|
||||||
{
|
|
||||||
config = GetDefaultConfig();
|
|
||||||
defer:: delete config;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(config is EditorTextureAssetLoaderConfig, "config has wrong type.");
|
|
||||||
|
|
||||||
return LoadTexture(data, (EditorTextureAssetLoaderConfig)config);
|
|
||||||
}
|
|
||||||
|
|
||||||
const String PngMagicWord = "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A";
|
|
||||||
const String DdsMagicWord = "DDS ";
|
|
||||||
|
|
||||||
enum TextureType
|
|
||||||
{
|
|
||||||
Unknown,
|
|
||||||
DDS,
|
|
||||||
PNG
|
|
||||||
}
|
|
||||||
|
|
||||||
private static TextureType GetTextureType(Stream data)
|
|
||||||
{
|
|
||||||
int64 position = data.Position;
|
|
||||||
|
|
||||||
var readResult = data.Read<char8[8]>();
|
|
||||||
|
|
||||||
data.Position = position;
|
|
||||||
|
|
||||||
char8[8] magicWord;
|
|
||||||
if (readResult case .Ok(out magicWord))
|
|
||||||
{
|
|
||||||
StringView strView = .(&magicWord, magicWord.Count);
|
|
||||||
|
|
||||||
if (strView.StartsWith(PngMagicWord))
|
|
||||||
{
|
|
||||||
return .PNG;
|
|
||||||
}
|
|
||||||
else if (strView.StartsWith(DdsMagicWord))
|
|
||||||
{
|
|
||||||
return .DDS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Runtime.FatalError("Unknown image format.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return .Unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief Loads the texture from the specified path.
|
|
||||||
* @param path The path of the texture to load.
|
|
||||||
* @param texture The reference to the pointer that will hold the texture.
|
|
||||||
* @returns true if the texture was loaded successfully; false otherwise.
|
|
||||||
*/
|
|
||||||
protected static bool LoadDdsResourcePlatform(Stream stream)
|
|
||||||
{
|
|
||||||
Debug.Profiler.ProfileResourceFunction!();
|
|
||||||
|
|
||||||
uint8[] ddsData = new:ScopedAlloc! uint8[stream.Length];
|
|
||||||
|
|
||||||
var result = stream.TryRead(ddsData);
|
|
||||||
|
|
||||||
if (result case .Err(let err))
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Error($"Failed to read texture data from stream. Error: {err}");
|
|
||||||
}
|
|
||||||
|
|
||||||
DirectX.D3D11.ID3D11Texture2D* texture = null;
|
|
||||||
DirectX.D3D11.ID3D11ShaderResourceView* view = null;
|
|
||||||
|
|
||||||
DirectX.Common.HResult loadResult = DDSTextureLoader.CreateDDSTextureFromMemory(GlitchyEngine.Platform.DX11.NativeDevice,
|
|
||||||
ddsData.Ptr, (uint)ddsData.Count, (.)&texture, &view);
|
|
||||||
|
|
||||||
view.Release();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Texture LoadTexture(Stream data, EditorTextureAssetLoaderConfig config)
|
|
||||||
{
|
|
||||||
Debug.Profiler.ProfileResourceFunction!();
|
|
||||||
|
|
||||||
List<LoadedSurface> surfaces = scope .();
|
|
||||||
LoadedTextureInfo textureInfo;
|
|
||||||
|
|
||||||
// Make sure we clean up the pixel data
|
|
||||||
defer { delete textureInfo.PixelData; }
|
|
||||||
|
|
||||||
|
|
||||||
switch(GetTextureType(data))
|
|
||||||
{
|
|
||||||
case .DDS:
|
|
||||||
|
|
||||||
var v = data.Position;
|
|
||||||
|
|
||||||
//LoadDdsResourcePlatform(data);
|
|
||||||
|
|
||||||
data.Position = v;
|
|
||||||
|
|
||||||
Result<void> result = LoadDds(data, config, surfaces, out textureInfo);
|
|
||||||
|
|
||||||
if (result case .Err)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
case .PNG:
|
|
||||||
Result<void> result = LoadPng(data, config, surfaces, out textureInfo);
|
|
||||||
|
|
||||||
if (result case .Err)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
case .Unknown:
|
|
||||||
Log.EngineLogger.Error("Unknown texture format.");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make the format SRGB or non-SRGB
|
|
||||||
if (config.IsSRGB)
|
|
||||||
textureInfo.PixelFormat = textureInfo.PixelFormat.GetSRGB();
|
|
||||||
else
|
|
||||||
textureInfo.PixelFormat = textureInfo.PixelFormat.GetNonSRGB();
|
|
||||||
|
|
||||||
Texture texture = CreateTexture(surfaces, textureInfo);
|
|
||||||
|
|
||||||
if (texture != null)
|
|
||||||
{
|
|
||||||
SetSampler(texture, config);
|
|
||||||
texture.[Friend]Complete = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Texture CreateTexture(List<LoadedSurface> surfaces, LoadedTextureInfo textureInfo)
|
|
||||||
{
|
|
||||||
TextureSliceData[] slices = scope TextureSliceData[surfaces.Count];
|
|
||||||
|
|
||||||
for (int i < slices.Count)
|
|
||||||
{
|
|
||||||
slices[i] = .(surfaces[i].Data.Ptr, surfaces[i].Pitch, surfaces[i].SlicePitch);
|
|
||||||
}
|
|
||||||
|
|
||||||
//slices[0].SlicePitch = (.)(surfaces[0].Pitch * textureInfo.Height);
|
|
||||||
|
|
||||||
switch (textureInfo.Dimension)
|
|
||||||
{
|
|
||||||
//case .Texture1D:
|
|
||||||
case .Texture2D:
|
|
||||||
if (textureInfo.IsCubeMap)
|
|
||||||
{
|
|
||||||
Texture2DDesc staging = .();
|
|
||||||
|
|
||||||
staging.Width = (.)textureInfo.Width;
|
|
||||||
staging.Height = (.)textureInfo.Height;
|
|
||||||
|
|
||||||
staging.MipLevels = (.)textureInfo.MipMapCount;
|
|
||||||
staging.ArraySize = (.)textureInfo.ArraySize;
|
|
||||||
|
|
||||||
staging.Format = (.)textureInfo.PixelFormat;
|
|
||||||
|
|
||||||
// TODO: allow enabling read/write
|
|
||||||
staging.CpuAccess = .None;
|
|
||||||
staging.Usage = .Default;
|
|
||||||
|
|
||||||
TextureCube cubeTexture = new TextureCube(staging);
|
|
||||||
|
|
||||||
//cubeTexture.SetData();
|
|
||||||
|
|
||||||
for (let surface in surfaces)
|
|
||||||
{
|
|
||||||
cubeTexture.SetData(surface.Data.Ptr, surface.Pitch / staging.Width, (TextureCubeFace)surface.CubeFace, (.)surface.ArrayIndex, (.)surface.MipLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cubeTexture;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Texture2DDesc staging = .();
|
|
||||||
|
|
||||||
staging.Width = (.)textureInfo.Width;
|
|
||||||
staging.Height = (.)textureInfo.Height;
|
|
||||||
|
|
||||||
staging.MipLevels = (.)textureInfo.MipMapCount;
|
|
||||||
staging.ArraySize = (.)textureInfo.ArraySize;
|
|
||||||
|
|
||||||
staging.Format = (.)textureInfo.PixelFormat;
|
|
||||||
|
|
||||||
// TODO: allow enabling read/write
|
|
||||||
staging.CpuAccess = .None;
|
|
||||||
staging.Usage = .Immutable;
|
|
||||||
|
|
||||||
Texture2D stagingTexture = new Texture2D(staging);
|
|
||||||
|
|
||||||
stagingTexture.SetData(slices);
|
|
||||||
|
|
||||||
/*for (let surface in surfaces)
|
|
||||||
{
|
|
||||||
stagingTexture.[Friend]PlatformSetData(surface.Data.Ptr, surface.Pitch / staging.Width, 0, 0, staging.Width, staging.Height, (.)surface.ArrayIndex, (.)surface.MipLevel, .Write);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
return stagingTexture;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
Runtime.NotImplemented();
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Result<void> LoadPng(Stream data, EditorTextureAssetLoaderConfig config, List<LoadedSurface> surfaces, out LoadedTextureInfo textureInfo)
|
|
||||||
{
|
|
||||||
Debug.Profiler.ProfileResourceFunction!();
|
|
||||||
|
|
||||||
textureInfo = .();
|
|
||||||
|
|
||||||
uint8[] pngData = new:ScopedAlloc! uint8[data.Length];
|
|
||||||
|
|
||||||
var result = data.TryRead(pngData);
|
|
||||||
|
|
||||||
if (result case .Err(let err))
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Error($"Failed to read data from stream. Texture: Error: {err}");
|
|
||||||
return .Err;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8* rawData = null;
|
|
||||||
defer
|
|
||||||
{
|
|
||||||
if (rawData != null)
|
|
||||||
LodePng.LodePng.Free(rawData);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 width = 0, height = 0;
|
|
||||||
|
|
||||||
{
|
|
||||||
Debug.Profiler.ProfileResourceScope!("LodePng.LodePng.Decode32");
|
|
||||||
uint32 errorCode = LodePng.LodePng.Decode32(&rawData, &width, &height, pngData.Ptr, (.)pngData.Count);
|
|
||||||
if (errorCode != 0)
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Error($"Failed to decode PNG file {errorCode}.");
|
|
||||||
return .Err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8[] pixelData = new uint8[4 * width * height];
|
|
||||||
Internal.MemCpy(pixelData.Ptr, rawData, pixelData.Count);
|
|
||||||
|
|
||||||
LoadedSurface surface = .();
|
|
||||||
surface.Data = Span<uint8>(pixelData);
|
|
||||||
surface.Pitch = 4 * width;
|
|
||||||
surface.SlicePitch = 0;
|
|
||||||
surface.ArrayIndex = 0;
|
|
||||||
surface.MipLevel = 0;
|
|
||||||
|
|
||||||
surfaces.Add(surface);
|
|
||||||
|
|
||||||
//Texture2DDesc desc = .(width, height, config.IsSRGB ? .R8G8B8A8_UNorm_SRGB : .R8G8B8A8_UNorm, 1, 1, .Immutable);
|
|
||||||
//Texture2D texture = new Texture2D(desc);
|
|
||||||
//texture.SetData<Color>((.)rawData);
|
|
||||||
|
|
||||||
// TODO: Generate mip maps
|
|
||||||
|
|
||||||
textureInfo.PixelData = pixelData;
|
|
||||||
textureInfo.Width = width;
|
|
||||||
textureInfo.Height = height;
|
|
||||||
textureInfo.Depth = 1;
|
|
||||||
|
|
||||||
textureInfo.ArraySize = 1;
|
|
||||||
textureInfo.MipMapCount = 1;
|
|
||||||
|
|
||||||
textureInfo.Dimension = .Texture2D;
|
|
||||||
|
|
||||||
textureInfo.IsCubeMap = false;
|
|
||||||
|
|
||||||
textureInfo.PixelFormat = config.IsSRGB ? .R8G8B8A8_UNorm_SRGB : .R8G8B8A8_UNorm;
|
|
||||||
|
|
||||||
return .Ok;
|
|
||||||
|
|
||||||
//return texture;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Result<void> LoadDds(Stream data, EditorTextureAssetLoaderConfig config, List<LoadedSurface> surfaces, out LoadedTextureInfo textureInfo)
|
|
||||||
{
|
|
||||||
var result = DdsImporter.LoadDds(data, config.IsSRGB, surfaces, out textureInfo);
|
|
||||||
|
|
||||||
if (result case .Err)
|
|
||||||
return .Err;
|
|
||||||
|
|
||||||
return .Ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void SetSampler(Texture texture, EditorTextureAssetLoaderConfig config)
|
|
||||||
{
|
|
||||||
using (SamplerState samplerState = SamplerStateManager.GetSampler(config.SamplerStateDescription))
|
|
||||||
{
|
|
||||||
texture.SamplerState = samplerState;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Texture2D _placeholder2D;
|
|
||||||
private static TextureCube _placeholderCube;
|
|
||||||
|
|
||||||
private static Texture2D _error2D;
|
|
||||||
private static TextureCube _errorCube;
|
|
||||||
|
|
||||||
public Asset GetPlaceholderAsset(Type assetType)
|
|
||||||
{
|
|
||||||
switch (assetType)
|
|
||||||
{
|
|
||||||
case typeof(TextureCube):
|
|
||||||
if (_placeholderCube == null)
|
|
||||||
{
|
|
||||||
// TODO: immutable
|
|
||||||
Texture2DDesc desc = .(1, 1, .R8G8B8A8_UNorm, 1, 1, .Default, .None);
|
|
||||||
|
|
||||||
_placeholderCube = new TextureCube(desc);
|
|
||||||
_placeholderCube.SamplerState = SamplerStateManager.PointWrap;
|
|
||||||
Color color = Color.Cyan;
|
|
||||||
_placeholderCube.SetData<Color>(&color, .PositiveX);
|
|
||||||
_placeholderCube.SetData<Color>(&color, .NegativeX);
|
|
||||||
_placeholderCube.SetData<Color>(&color, .PositiveY);
|
|
||||||
_placeholderCube.SetData<Color>(&color, .NegativeY);
|
|
||||||
_placeholderCube.SetData<Color>(&color, .PositiveZ);
|
|
||||||
_placeholderCube.SetData<Color>(&color, .NegativeZ);
|
|
||||||
|
|
||||||
Content.ManageAsset(_placeholderCube);
|
|
||||||
_placeholderCube.ReleaseRef();
|
|
||||||
|
|
||||||
_placeholderCube.[Friend]Complete = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _placeholderCube;
|
|
||||||
case typeof(Texture2D):
|
|
||||||
fallthrough;
|
|
||||||
default:
|
|
||||||
if (_placeholder2D == null)
|
|
||||||
{
|
|
||||||
Texture2DDesc desc = .(1, 1, .R8G8B8A8_UNorm, 1, 1, .Immutable, .None);
|
|
||||||
|
|
||||||
_placeholder2D = new Texture2D(desc);
|
|
||||||
_placeholder2D.SamplerState = SamplerStateManager.PointWrap;
|
|
||||||
Color color = Color.Cyan;
|
|
||||||
_placeholder2D.SetData<Color>(&color);
|
|
||||||
|
|
||||||
Content.ManageAsset(_placeholder2D);
|
|
||||||
_placeholder2D.ReleaseRef();
|
|
||||||
|
|
||||||
_placeholder2D.[Friend]Complete = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _placeholder2D;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Asset GetErrorAsset(Type assetType)
|
|
||||||
{
|
|
||||||
switch (assetType)
|
|
||||||
{
|
|
||||||
case typeof(TextureCube):
|
|
||||||
if (_placeholderCube == null)
|
|
||||||
{
|
|
||||||
// TODO: immutable
|
|
||||||
Texture2DDesc desc = .(2, 2, .R8G8B8A8_UNorm, 1, 1, .Default, .None);
|
|
||||||
|
|
||||||
_errorCube = new TextureCube(desc);
|
|
||||||
_errorCube.SamplerState = SamplerStateManager.PointWrap;
|
|
||||||
|
|
||||||
Color[4] color = .(Color.HotPink, Color.Black, Color.Black, Color.HotPink);
|
|
||||||
|
|
||||||
_errorCube.SetData<Color>(&color, .PositiveX);
|
|
||||||
_errorCube.SetData<Color>(&color, .NegativeX);
|
|
||||||
_errorCube.SetData<Color>(&color, .PositiveY);
|
|
||||||
_errorCube.SetData<Color>(&color, .NegativeY);
|
|
||||||
_errorCube.SetData<Color>(&color, .PositiveZ);
|
|
||||||
_errorCube.SetData<Color>(&color, .NegativeZ);
|
|
||||||
|
|
||||||
Content.ManageAsset(_errorCube);
|
|
||||||
_errorCube.ReleaseRef();
|
|
||||||
|
|
||||||
_errorCube.[Friend]Complete = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _placeholderCube;
|
|
||||||
case typeof(Texture2D):
|
|
||||||
fallthrough;
|
|
||||||
default:
|
|
||||||
if (_error2D == null)
|
|
||||||
{
|
|
||||||
Texture2DDesc desc = .(2, 2, .R8G8B8A8_UNorm, 1, 1, .Immutable, .None);
|
|
||||||
|
|
||||||
_error2D = new Texture2D(desc);
|
|
||||||
_error2D.SamplerState = SamplerStateManager.PointWrap;
|
|
||||||
|
|
||||||
Color[4] color = .(Color.HotPink, Color.Black, Color.Black, Color.HotPink);
|
|
||||||
|
|
||||||
_error2D.SetData<Color>(&color);
|
|
||||||
|
|
||||||
Content.ManageAsset(_error2D);
|
|
||||||
_error2D.ReleaseRef();
|
|
||||||
|
|
||||||
_placeholder2D.[Friend]Complete = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _error2D;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -21,9 +21,6 @@ namespace GlitchyEditor
|
|||||||
protected override IContentManager InitContentManager()
|
protected override IContentManager InitContentManager()
|
||||||
{
|
{
|
||||||
_contentManager = new EditorContentManager();
|
_contentManager = new EditorContentManager();
|
||||||
_contentManager.RegisterAssetLoader<EditorTextureAssetLoader>();
|
|
||||||
_contentManager.SetAsDefaultAssetLoader<EditorTextureAssetLoader>(".png", ".dds");
|
|
||||||
_contentManager.SetAssetPropertiesEditor<EditorTextureAssetLoader>(=> TextureAssetPropertiesEditor.Factory);
|
|
||||||
|
|
||||||
_contentManager.RegisterAssetLoader<ModelAssetLoader>();
|
_contentManager.RegisterAssetLoader<ModelAssetLoader>();
|
||||||
_contentManager.SetAsDefaultAssetLoader<ModelAssetLoader>(".glb", ".gltf");
|
_contentManager.SetAsDefaultAssetLoader<ModelAssetLoader>(".glb", ".gltf");
|
||||||
@@ -41,9 +38,10 @@ namespace GlitchyEditor
|
|||||||
_contentManager.RegisterAssetProcessor<TextureProcessor>();
|
_contentManager.RegisterAssetProcessor<TextureProcessor>();
|
||||||
_contentManager.RegisterAssetExporter<TextureExporter>();
|
_contentManager.RegisterAssetExporter<TextureExporter>();
|
||||||
|
|
||||||
_contentManager.ConfigureDefaultProcessing<TextureImporter, TextureProcessor, TextureExporter>(".png");
|
_contentManager.ConfigureDefaultProcessing<TextureImporter, TextureProcessor, TextureExporter>(".png", ".dds");
|
||||||
|
|
||||||
_contentManager.SetResourcesDirectory("./Resources");
|
_contentManager.SetGlobalAssetCacheDirectory(".cache");
|
||||||
|
_contentManager.SetResourcesDirectory("Resources");
|
||||||
|
|
||||||
return _contentManager;
|
return _contentManager;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,10 +94,15 @@ class EditorContentManager : IContentManager
|
|||||||
|
|
||||||
_assetHierarchy.SetAssetsDirectory(_assetsDirectory);
|
_assetHierarchy.SetAssetsDirectory(_assetsDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetGlobalAssetCacheDirectory(StringView fileName)
|
||||||
|
{
|
||||||
|
_assetCache.SetGlobalCacheDirectory(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
public void SetAssetCacheDirectory(StringView fileName)
|
public void SetAssetCacheDirectory(StringView fileName)
|
||||||
{
|
{
|
||||||
_assetCache.SetDirectory(fileName);
|
_assetCache.SetProjectCacheDirectory(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
@@ -494,14 +499,11 @@ class EditorContentManager : IContentManager
|
|||||||
AssetNode assetNode = resultNode->Value;
|
AssetNode assetNode = resultNode->Value;
|
||||||
AssetFile file = assetNode.AssetFile;
|
AssetFile file = assetNode.AssetFile;
|
||||||
|
|
||||||
CachedAsset cacheEntry = _assetCache.GetCacheEntry(handle);
|
|
||||||
|
|
||||||
Asset loadedAsset;
|
Asset loadedAsset;
|
||||||
|
|
||||||
// TODO: Remove this check once we no longer need the old stuff
|
// TODO: Remove this check once we no longer need the old stuff
|
||||||
if (cacheEntry != null)
|
if (file.UseNewAssetPipeline)
|
||||||
{
|
{
|
||||||
// TODO: Load asset with new loaders
|
|
||||||
loadedAsset = LoadFromCache(handle, blocking);
|
loadedAsset = LoadFromCache(handle, blocking);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -522,7 +524,7 @@ class EditorContentManager : IContentManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Support lazy loading for all asset types
|
// TODO: Support lazy loading for all asset types
|
||||||
if (!(assetLoader is EditorTextureAssetLoader) || blocking)
|
if (true || blocking)
|
||||||
{
|
{
|
||||||
Stream stream = OpenStream(filePath, true);
|
Stream stream = OpenStream(filePath, true);
|
||||||
|
|
||||||
@@ -948,22 +950,48 @@ class EditorContentManager : IContentManager
|
|||||||
{
|
{
|
||||||
CachedAsset asset = _assetCache.GetCacheEntry(handle);
|
CachedAsset asset = _assetCache.GetCacheEntry(handle);
|
||||||
|
|
||||||
|
if (asset == null)
|
||||||
|
{
|
||||||
|
Result<TreeNode<AssetNode>> assetNodeResult = AssetHierarchy.GetNodeFromAssetHandle(handle);
|
||||||
|
|
||||||
|
if (assetNodeResult case .Ok(let assetNode))
|
||||||
|
{
|
||||||
|
_assetConverter.QueueForProcessing(assetNode->AssetFile, isBlocking);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isBlocking)
|
||||||
|
{
|
||||||
|
asset = _assetCache.GetCacheEntry(handle);
|
||||||
|
|
||||||
|
Log.EngineLogger.Assert(asset != null, "Failed to load asset.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: Return placeholder!
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Result<Stream> streamResult = _assetCache.OpenStream(asset);
|
Result<Stream> streamResult = _assetCache.OpenStream(asset);
|
||||||
|
|
||||||
// TODO: Actually return a placeholder, but they probably need rework too...
|
|
||||||
if (streamResult case .Err)
|
if (streamResult case .Err)
|
||||||
|
{
|
||||||
|
// Return error
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
Stream dataStream = streamResult.Value;
|
Stream dataStream = streamResult.Value;
|
||||||
defer { delete dataStream; }
|
defer { delete dataStream; }
|
||||||
|
|
||||||
IProcessedAssetLoader loader = GetLoader(asset.AssetType);
|
IProcessedAssetLoader loader = GetLoader(asset.AssetType);
|
||||||
|
|
||||||
switch (loader.Load(dataStream))
|
if (loader.Load(dataStream) case .Ok(let loadedAsset))
|
||||||
{
|
{
|
||||||
case .Ok(let loadedAsset):
|
return loadedAsset;
|
||||||
return loadedAsset;
|
}
|
||||||
case .Err:
|
else
|
||||||
|
{
|
||||||
|
// Return error
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -764,8 +764,8 @@ namespace GlitchyEditor
|
|||||||
_editor.CurrentProject = _currentProject;
|
_editor.CurrentProject = _currentProject;
|
||||||
|
|
||||||
String appAssemblyPath = scope String();
|
String appAssemblyPath = scope String();
|
||||||
_contentManager.SetAssetDirectory(_currentProject.AssetsFolder);
|
|
||||||
_contentManager.SetAssetCacheDirectory(_currentProject.GetScopedPath!(".cache"));
|
_contentManager.SetAssetCacheDirectory(_currentProject.GetScopedPath!(".cache"));
|
||||||
|
_contentManager.SetAssetDirectory(_currentProject.AssetsFolder);
|
||||||
|
|
||||||
_currentProject.PathInProject(appAssemblyPath, scope $"bin/{_currentProject.Name}.dll");
|
_currentProject.PathInProject(appAssemblyPath, scope $"bin/{_currentProject.Name}.dll");
|
||||||
|
|
||||||
|
|||||||
@@ -4,14 +4,21 @@ namespace GlitchyEngine.Content;
|
|||||||
|
|
||||||
public class AssetIdentifier
|
public class AssetIdentifier
|
||||||
{
|
{
|
||||||
|
public const String ResourcesPrefix = "Resources/";
|
||||||
|
public const String AssetsPrefix = "Assets/";
|
||||||
|
|
||||||
private String _fullIdentifier ~ delete:append _;
|
private String _fullIdentifier ~ delete:append _;
|
||||||
|
|
||||||
|
private bool _isResource;
|
||||||
|
|
||||||
private int _subassetSeperator;
|
private int _subassetSeperator;
|
||||||
|
|
||||||
public StringView FullIdentifier => _fullIdentifier;
|
public StringView FullIdentifier => _fullIdentifier;
|
||||||
public StringView AssetIdentifier => _subassetSeperator > 0 ? StringView(_fullIdentifier, 0, _subassetSeperator) : _fullIdentifier;
|
public StringView AssetIdentifier => _subassetSeperator > 0 ? StringView(_fullIdentifier, 0, _subassetSeperator) : _fullIdentifier;
|
||||||
public StringView SubassetIdentifier => _subassetSeperator > 0 ? StringView(_fullIdentifier, _subassetSeperator + 1) : .();
|
public StringView SubassetIdentifier => _subassetSeperator > 0 ? StringView(_fullIdentifier, _subassetSeperator + 1) : .();
|
||||||
|
|
||||||
|
public bool IsResource => _isResource;
|
||||||
|
|
||||||
[AllowAppend]
|
[AllowAppend]
|
||||||
public this(StringView assetIdentifier)
|
public this(StringView assetIdentifier)
|
||||||
{
|
{
|
||||||
@@ -21,6 +28,8 @@ public class AssetIdentifier
|
|||||||
Fixup(_fullIdentifier);
|
Fixup(_fullIdentifier);
|
||||||
|
|
||||||
_subassetSeperator = _fullIdentifier.IndexOf(':', 0);
|
_subassetSeperator = _fullIdentifier.IndexOf(':', 0);
|
||||||
|
|
||||||
|
_isResource = _fullIdentifier.StartsWith(ResourcesPrefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
[AllowAppend]
|
[AllowAppend]
|
||||||
|
|||||||
Reference in New Issue
Block a user