mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
New material loading pipeline almost working
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using GlitchyEngine.Renderer;
|
||||
using GlitchyEditor.Assets.Processors;
|
||||
using GlitchyEngine;
|
||||
using GlitchyEditor.Assets.Importers;
|
||||
using GlitchyEngine.Content;
|
||||
using System.Diagnostics;
|
||||
namespace GlitchyEditor.Assets.Exporters;
|
||||
|
||||
|
||||
class MaterialExporter : IAssetExporter
|
||||
{
|
||||
public static AssetType ExportedAssetType => .Material;
|
||||
|
||||
public AssetExporterConfig CreateDefaultConfig()
|
||||
{
|
||||
return new AssetExporterConfig();
|
||||
}
|
||||
|
||||
public Result<void> Export(Stream stream, ProcessedResource processedResource, AssetConfig config)
|
||||
{
|
||||
Log.EngineLogger.AssertDebug(processedResource is ProcessedMaterial);
|
||||
|
||||
ProcessedMaterial processedMaterial = (.)processedResource;
|
||||
|
||||
Compiler.Assert(sizeof(AssetHandle) == 8);
|
||||
|
||||
/*
|
||||
File Format:
|
||||
Effect Asset Handle (8 byte)
|
||||
Texture Count (uint16)
|
||||
Textures
|
||||
{
|
||||
Texture Handle (8 byte)
|
||||
Texture Name Length (int16)
|
||||
Texture Name Data...
|
||||
}
|
||||
Buffer Count (uint16)
|
||||
Buffers
|
||||
{
|
||||
Buffer Size (int64)
|
||||
Buffer Name Length (int16)
|
||||
Buffer Name Data...
|
||||
Raw Buffer Data...
|
||||
}
|
||||
*/
|
||||
|
||||
Try!(stream.Write((AssetHandle)processedMaterial.EffectHandle));
|
||||
Try!(WriteTextures(stream, processedMaterial));
|
||||
Try!(WriteBuffers(stream, processedMaterial));
|
||||
|
||||
return .Ok;
|
||||
}
|
||||
|
||||
private Result<void> WriteTextures(Stream stream, ProcessedMaterial processedMaterial)
|
||||
{
|
||||
Log.EngineLogger.Assert(processedMaterial.Textures.Count < int16.MaxValue);
|
||||
|
||||
Try!(stream.Write((uint16)processedMaterial.Textures.Count));
|
||||
|
||||
for (let (textureName, textureHandle) in processedMaterial.Textures)
|
||||
{
|
||||
Try!(stream.Write((AssetHandle)textureHandle));
|
||||
|
||||
Log.EngineLogger.Assert(textureName.Length < int16.MaxValue);
|
||||
|
||||
Try!(stream.Write((int16)textureName.Length));
|
||||
Try!(stream.Write(textureName));
|
||||
}
|
||||
|
||||
return .Ok;
|
||||
}
|
||||
|
||||
|
||||
private Result<void> WriteBuffers(Stream stream, ProcessedMaterial processedMaterial)
|
||||
{
|
||||
Log.EngineLogger.Assert(processedMaterial.Buffers.Count < int16.MaxValue);
|
||||
|
||||
Try!(stream.Write((uint16)processedMaterial.Buffers.Count));
|
||||
|
||||
for (let (bufferName, bufferData) in processedMaterial.Buffers)
|
||||
{
|
||||
Try!(stream.Write((int64)bufferData.Count));
|
||||
|
||||
Log.EngineLogger.Assert(bufferName.Length < int16.MaxValue);
|
||||
|
||||
Try!(stream.Write((int16)bufferName.Length));
|
||||
Try!(stream.Write(bufferName));
|
||||
|
||||
Try!(stream.Write(Span<uint8>(bufferData)));
|
||||
}
|
||||
|
||||
return .Ok;
|
||||
}
|
||||
}
|
||||
@@ -30,20 +30,20 @@ class ShaderExporter : IAssetExporter
|
||||
Textures
|
||||
{
|
||||
Texture Dimension (1 byte)
|
||||
Vertex Shader Bind Point (int32, 4 bytes)
|
||||
Pixel Shader Bind Point (int32, 4 bytes)
|
||||
Texture Name Length (16 bytes)
|
||||
Vertex Shader Bind Point (int32, 4 bytes) # TODO: ASSUME same bind point for all shader stages?
|
||||
Pixel Shader Bind Point (int32, 4 bytes) # TODO: ASSUME same bind point for all shader stages?
|
||||
Texture Name Length (uint16)
|
||||
Texture Name Data...
|
||||
}
|
||||
Buffer Count (uint16)
|
||||
Buffers
|
||||
{
|
||||
Buffer Size (int64)
|
||||
Vertex Shader Bind Point (int32, 4 bytes)
|
||||
Pixel Shader Bind Point (int32, 4 bytes)
|
||||
Buffer Name Length (16 bytes)
|
||||
Vertex Shader Bind Point (int32, 4 bytes) # TODO: ASSUME same bind point for all shader stages?
|
||||
Pixel Shader Bind Point (int32, 4 bytes) # TODO: ASSUME same bind point for all shader stages?
|
||||
Buffer Name Length (uint16)
|
||||
Buffer Name Data...
|
||||
Engine Buffer Name Length (16 bytes)
|
||||
Engine Buffer Name Length (uint16)
|
||||
Engine Buffer Name Data...
|
||||
Variable Count (uint16)
|
||||
Variables
|
||||
@@ -55,7 +55,7 @@ class ShaderExporter : IAssetExporter
|
||||
Rows (uint8)
|
||||
Columns (uint8)
|
||||
ArraySize (uint64)
|
||||
Name Length (16 bytes)
|
||||
Name Length (uint16)
|
||||
Name Data...
|
||||
}
|
||||
RawData...
|
||||
|
||||
@@ -5,60 +5,44 @@ using GlitchyEngine.Renderer;
|
||||
using Bon;
|
||||
using GlitchyEngine.Math;
|
||||
using System.IO;
|
||||
using Bon.Integrated;
|
||||
using GlitchyEngine;
|
||||
|
||||
namespace GlitchyEditor.Assets.Importers;
|
||||
|
||||
[BonTarget]
|
||||
class NewMaterialFile : ImportedResource
|
||||
class MaterialVariable
|
||||
{
|
||||
public AssetHandle<Effect> Effect;
|
||||
public ShaderVariableType ElementType;
|
||||
public int MatrixColumns;
|
||||
public int MatrixRows;
|
||||
public int ArrayElements;
|
||||
|
||||
public Dictionary<String, AssetHandle<Texture>> Textures = new .() ~ DeleteDictionaryAndKeys!(_);
|
||||
public Dictionary<String, MaterialVariableValue> Constants = new .() ~ DeleteDictionaryAndKeys!(_);
|
||||
public uint8[] RawData ~ delete _;
|
||||
|
||||
public this(AssetIdentifier ownAssetIdentifier) : base(ownAssetIdentifier)
|
||||
public this()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public this(ShaderVariableType elementType, int matrixColumns, int matrixRows, int arrayElements)
|
||||
{
|
||||
ElementType = elementType;
|
||||
MatrixColumns = matrixColumns;
|
||||
MatrixRows = matrixRows;
|
||||
ArrayElements = arrayElements;
|
||||
|
||||
RawData = new uint8[elementType.ElementSizeInBytes() * matrixColumns * matrixRows * arrayElements];
|
||||
}
|
||||
|
||||
|
||||
[BonTarget]
|
||||
public enum MaterialVariableValue
|
||||
{
|
||||
case bool(bool Value);
|
||||
case bool2(bool2 Value);
|
||||
case bool3(bool3 Value);
|
||||
case bool4(bool4 Value);
|
||||
case int(int Value);
|
||||
case int2(int2 Value);
|
||||
case int3(int3 Value);
|
||||
case int4(int4 Value);
|
||||
case uint(uint Value);
|
||||
case uint2(uint2 Value);
|
||||
case uint3(uint3 Value);
|
||||
case uint4(uint4 Value);
|
||||
case Float(float Value);
|
||||
case Float2(float2 Value);
|
||||
case Float3(float3 Value);
|
||||
case Float4(float4 Value);
|
||||
case Half(half Value);
|
||||
case Half2(half2 Value);
|
||||
case Half3(half3 Value);
|
||||
case Half4(half4 Value);
|
||||
case ColorRGB(ColorRGB Value);
|
||||
case ColorRGBA(ColorRGBA Value);
|
||||
case None;
|
||||
|
||||
/*static this()
|
||||
static this()
|
||||
{
|
||||
gBonEnv.typeHandlers.Add(typeof(Self),
|
||||
((.)new => VariableValueSerialize, (.)new => VariableValueDeserialize));
|
||||
}
|
||||
|
||||
static void VariableValueSerialize(BonWriter writer, ValueView value, BonEnvironment env)
|
||||
static void VariableValueSerialize(BonWriter writer, ValueView value, BonEnvironment env, SerializeValueState state)
|
||||
{
|
||||
Log.EngineLogger.Assert(value.type == typeof(Self));
|
||||
/*Log.EngineLogger.Assert(value.type == typeof(Self));
|
||||
|
||||
let variableValue = value.Get<Self>();
|
||||
|
||||
@@ -69,15 +53,152 @@ public enum MaterialVariableValue
|
||||
Serialize.Value(writer, nameof(MaterialFile.Textures), materialFile.Textures, env);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static Result<void> VariableValueDeserialize(BonReader reader, ValueView val, BonEnvironment env)
|
||||
{
|
||||
return .Ok;
|
||||
}*/
|
||||
}
|
||||
|
||||
static Result<void> VariableValueDeserialize(BonReader reader, ValueView val, BonEnvironment env, DeserializeValueState state)
|
||||
{
|
||||
MaterialVariable output = val.Get<MaterialVariable>();
|
||||
|
||||
StringView typeName = Try!(reader.EnumName());
|
||||
|
||||
// If we don't find a digit, we assume entire type name is element type and rows string ends up being an empty string.
|
||||
int firstDigitIndex = typeName.Length;
|
||||
|
||||
for (char8 c in typeName)
|
||||
{
|
||||
if (c.IsDigit)
|
||||
{
|
||||
firstDigitIndex = @c.Index;
|
||||
}
|
||||
}
|
||||
|
||||
Result<ShaderVariableType> elementTypeResult = Enum.Parse<ShaderVariableType>(typeName.Substring(0, firstDigitIndex), true);
|
||||
|
||||
if (elementTypeResult case .Err)
|
||||
{
|
||||
Deserialize.Error!("Unknown element type.", reader);
|
||||
}
|
||||
|
||||
int xIndex = typeName.LastIndexOf('x');
|
||||
|
||||
StringView rowsString = null;
|
||||
StringView columnsString = null;
|
||||
|
||||
if (xIndex != -1)
|
||||
{
|
||||
rowsString = typeName.Substring(firstDigitIndex ..< xIndex);
|
||||
columnsString = typeName.Substring(xIndex + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
rowsString = typeName.Substring(firstDigitIndex);
|
||||
}
|
||||
|
||||
Result<int, Int.ParseError> rowsResult = int.Parse(rowsString);
|
||||
|
||||
if (rowsResult case .Err(let error))
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
case .NoValue:
|
||||
rowsResult = 1;
|
||||
case .Overflow:
|
||||
Deserialize.Error!("Integer overflow in row count.", reader);
|
||||
case .InvalidChar:
|
||||
Deserialize.Error!("Invalid character in row count.", reader);
|
||||
default:
|
||||
return .Err;
|
||||
}
|
||||
}
|
||||
|
||||
Result<int, Int.ParseError> columnsResult = int.Parse(columnsString);
|
||||
|
||||
if (columnsResult case .Err(let error))
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
case .NoValue:
|
||||
columnsResult = 1;
|
||||
case .Overflow:
|
||||
Deserialize.Error!("Integer overflow in column count.", reader);
|
||||
case .InvalidChar:
|
||||
Deserialize.Error!("Invalid character in column count.", reader);
|
||||
default:
|
||||
return .Err;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Array
|
||||
/*if (reader.[Friend]Check('['))
|
||||
{
|
||||
|
||||
}*/
|
||||
|
||||
output.ElementType = elementTypeResult.Get();
|
||||
output.MatrixRows = rowsResult.Get();
|
||||
output.MatrixColumns = columnsResult.Get();
|
||||
output.ArrayElements = 1;
|
||||
|
||||
int elementSize = output.ElementType.ElementSizeInBytes();
|
||||
int elementCount = output.MatrixColumns * output.MatrixRows;
|
||||
|
||||
output.RawData = new uint8[elementSize * elementCount * output.ArrayElements];
|
||||
|
||||
Try!(reader.ObjectBlock());
|
||||
|
||||
for (int currentElementIndex < elementCount)
|
||||
{
|
||||
switch (output.ElementType)
|
||||
{
|
||||
case .Float:
|
||||
StringView valueString = Try!(reader.Floating());
|
||||
|
||||
float* rawFloats = (float*)output.RawData.Ptr;
|
||||
|
||||
rawFloats[currentElementIndex] = Try!(float.Parse(valueString));
|
||||
case .Bool:
|
||||
// TODO: I'm pretty sure this is wrong, bools in c buffers are usually 32 bit
|
||||
bool value = Try!(reader.Bool());
|
||||
((bool*)&output.RawData)[currentElementIndex] = value;
|
||||
case .Int:
|
||||
StringView valueString = Try!(reader.Integer());
|
||||
((int32*)&output.RawData)[currentElementIndex] = Try!(int32.Parse(valueString));
|
||||
case .UInt:
|
||||
StringView valueString = Try!(reader.Integer());
|
||||
((uint32*)&output.RawData)[currentElementIndex] = Try!(uint32.Parse(valueString));
|
||||
}
|
||||
|
||||
if (reader.ObjectHasMore())
|
||||
{
|
||||
Try!(reader.EntryEnd());
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.EngineLogger.Warning("Vector/Matrix doesn't contain enough elements.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Try!(reader.ObjectBlockEnd());
|
||||
|
||||
return .Ok;
|
||||
}
|
||||
}
|
||||
|
||||
[BonTarget]
|
||||
class NewMaterialFile : ImportedResource
|
||||
{
|
||||
public AssetHandle<Effect> Effect;
|
||||
|
||||
public Dictionary<String, AssetHandle<Texture>> Textures = new .() ~ DeleteDictionaryAndKeys!(_);
|
||||
public Dictionary<String, MaterialVariable> Constants = new .() ~ DeleteDictionaryAndKeysAndValues!(_);
|
||||
|
||||
public this(AssetIdentifier ownAssetIdentifier) : base(ownAssetIdentifier)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class MaterialImporter: IAssetImporter
|
||||
{
|
||||
|
||||
@@ -144,7 +144,7 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
||||
{
|
||||
if (previewType.Get<String>().Equals("Color", .InvariantCultureIgnoreCase))
|
||||
{
|
||||
Log.EngineLogger.AssertDebug(variable.Type == .Float && variable.Rows == 1);
|
||||
Log.EngineLogger.AssertDebug(variable.ElementType == .Float && variable.Rows == 1);
|
||||
|
||||
if (variable.Columns == 3)
|
||||
{
|
||||
@@ -173,7 +173,7 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
||||
}
|
||||
else if (previewType.Get<String>().Equals("ColorHDR", .InvariantCultureIgnoreCase))
|
||||
{
|
||||
Log.EngineLogger.AssertDebug(variable.Type == .Float && variable.Rows == 1);
|
||||
Log.EngineLogger.AssertDebug(variable.ElementType == .Float && variable.Rows == 1);
|
||||
|
||||
if (variable.Columns == 3)
|
||||
{
|
||||
@@ -203,7 +203,7 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
||||
}
|
||||
//ImGui.ColorEdit3("", null, .HDR | .Float)
|
||||
|
||||
else if (variable.Type == .Float && variable.Rows == 1)
|
||||
else if (variable.ElementType == .Float && variable.Rows == 1)
|
||||
{
|
||||
bool hasMin = TryGetValue(arguments, "Min", var min);
|
||||
bool hasMax = TryGetValue(arguments, "Max", var max);
|
||||
@@ -495,7 +495,7 @@ class MaterialAssetLoader : IAssetLoader, IAssetSaver //, IReloadingAssetLoader
|
||||
|
||||
if (hasPreviewType && previewType.Get<String>() == "Color")
|
||||
{
|
||||
Log.EngineLogger.AssertDebug(variable.Type == .Float && variable.Rows == 1);
|
||||
Log.EngineLogger.AssertDebug(variable.ElementType == .Float && variable.Rows == 1);
|
||||
|
||||
if (variable.Columns == 3)
|
||||
{
|
||||
@@ -515,7 +515,7 @@ class MaterialAssetLoader : IAssetLoader, IAssetSaver //, IReloadingAssetLoader
|
||||
variableValue = .ColorRGBA(value);
|
||||
}
|
||||
}
|
||||
else if (variable.Type == .Float && variable.Rows == 1)
|
||||
else if (variable.ElementType == .Float && variable.Rows == 1)
|
||||
{
|
||||
switch (variable.Columns)
|
||||
{
|
||||
|
||||
@@ -4,26 +4,42 @@ using GlitchyEditor.Assets.Importers;
|
||||
using GlitchyEngine.Renderer;
|
||||
using GlitchyEngine;
|
||||
using GlitchyEngine.Content;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace GlitchyEditor.Assets.Processors;
|
||||
|
||||
class ProcessedMaterial : ProcessedResource
|
||||
{
|
||||
public AssetHandle EffectHandle;
|
||||
|
||||
private Dictionary<String, uint8[]> _bufferData = new .() ~ DeleteDictionaryAndKeysAndValues!(_);
|
||||
private Dictionary<String, AssetHandle> _textures = new .() ~ DeleteDictionaryAndKeys!(_);
|
||||
|
||||
public override AssetType AssetType => .Material;
|
||||
|
||||
public Dictionary<String, uint8[]> Buffers => _bufferData;
|
||||
public Dictionary<String, AssetHandle> Textures => _textures;
|
||||
|
||||
public this(AssetIdentifier ownAssetIdentifier, AssetHandle assetHandle) : base(ownAssetIdentifier, assetHandle)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public uint8[] CloneBuffer(ConstantBuffer cBuffer)
|
||||
public Span<uint8> CloneBuffer(String name, ConstantBuffer cBuffer)
|
||||
{
|
||||
String name = new String(cBuffer.Name);
|
||||
//uint8[] data = cBuffer.
|
||||
String copyName = new String(name);
|
||||
uint8[] data = new uint8[cBuffer.RawData.Length];
|
||||
cBuffer.RawData.CopyTo(data);
|
||||
|
||||
return null;
|
||||
_bufferData.Add(copyName, data);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public void AddTexture(StringView name, AssetHandle textureHandle)
|
||||
{
|
||||
String copyName = new String(name);
|
||||
_textures.Add(copyName, textureHandle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,22 +63,67 @@ class MaterialProcessor : IAssetProcessor
|
||||
|
||||
Effect effect = Content.GetAsset<Effect>(importedMaterial.Effect, blocking: true);
|
||||
|
||||
if (effect == null)
|
||||
// TODO: Don't error out, use the error-effect
|
||||
return .Err;
|
||||
|
||||
ProcessedMaterial processedMaterial = new .(new AssetIdentifier(importedMaterial.AssetIdentifier), config.AssetHandle);
|
||||
|
||||
processedMaterial.EffectHandle = importedMaterial.Effect;
|
||||
|
||||
for (let buffer in effect.Buffers)
|
||||
{
|
||||
// TODO: Skip engine buffers
|
||||
|
||||
if (buffer.Buffer == null)
|
||||
continue;
|
||||
|
||||
ConstantBuffer cBuffer = buffer.Buffer as ConstantBuffer;
|
||||
|
||||
if (cBuffer == null)
|
||||
{
|
||||
|
||||
Log.EngineLogger.Error("The buffers of a material must be ConstantBuffers.");
|
||||
continue;
|
||||
// TODO: Why even allow any kind of Buffer for Materials? Will this make sense later if we can create and bind Buffers from C#?
|
||||
}
|
||||
|
||||
processedMaterial.CloneBuffer(cBuffer);
|
||||
Span<uint8> data = processedMaterial.CloneBuffer(buffer.Name, cBuffer);
|
||||
|
||||
for (BufferVariable effectVariable in cBuffer.Variables)
|
||||
{
|
||||
if (importedMaterial.Constants.TryGetValue(effectVariable.Name, let materialValue))
|
||||
{
|
||||
if (effectVariable.ElementType != materialValue.ElementType)
|
||||
{
|
||||
Log.EngineLogger.Error("Element type doesn't match between material and effect.");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create buffers
|
||||
int effectVariableSize = effectVariable.Rows * effectVariable.Columns * Math.Max(1, effectVariable.ArrayElements) * effectVariable.ElementType.ElementSizeInBytes();
|
||||
|
||||
return default;
|
||||
if (effectVariableSize != materialValue.RawData.Count)
|
||||
{
|
||||
Log.EngineLogger.Warning("Warning, matrix size in matrix and effect doesn't match. Truncating value.");
|
||||
}
|
||||
|
||||
int bytesToCopy = Math.Min(effectVariableSize, materialValue.RawData.Count);
|
||||
Debug.Assert(effectVariable.Offset + bytesToCopy <= data.Length, "Material value goes out of bounds ");
|
||||
|
||||
Internal.MemCpy(data.Ptr + effectVariable.Offset, materialValue.RawData.Ptr, bytesToCopy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let (textureName, textureBinding) in effect.Textures)
|
||||
{
|
||||
if (importedMaterial.Textures.TryGetValue(textureName, let textureHandle))
|
||||
{
|
||||
processedMaterial.AddTexture(textureName, textureHandle);
|
||||
}
|
||||
}
|
||||
|
||||
outProcessedResources.Add(processedMaterial);
|
||||
|
||||
return .Ok;
|
||||
}
|
||||
}
|
||||
@@ -29,10 +29,6 @@ namespace GlitchyEditor
|
||||
_contentManager.SetAsDefaultAssetLoader<ModelAssetLoader>(".glb", ".gltf");
|
||||
_contentManager.SetAssetPropertiesEditor<ModelAssetLoader>(=> ModelAssetPropertiesEditor.Factory);
|
||||
|
||||
_contentManager.RegisterAssetLoader<MaterialAssetLoader>();
|
||||
_contentManager.SetAsDefaultAssetLoader<MaterialAssetLoader>(".mat");
|
||||
_contentManager.SetAssetPropertiesEditor<MaterialAssetLoader>(=> MaterialAssetPropertiesEditor.Factory);
|
||||
|
||||
_contentManager.RegisterAssetImporter<TextureImporter>();
|
||||
_contentManager.RegisterAssetProcessor<TextureProcessor>();
|
||||
_contentManager.RegisterAssetExporter<TextureExporter>();
|
||||
@@ -43,6 +39,10 @@ namespace GlitchyEditor
|
||||
_contentManager.RegisterAssetProcessor<ShaderProcessor>();
|
||||
_contentManager.RegisterAssetExporter<ShaderExporter>();
|
||||
|
||||
_contentManager.RegisterAssetImporter<MaterialImporter>();
|
||||
_contentManager.RegisterAssetProcessor<MaterialProcessor>();
|
||||
_contentManager.RegisterAssetExporter<MaterialExporter>();
|
||||
|
||||
_contentManager.SetGlobalAssetCacheDirectory(".cache");
|
||||
_contentManager.SetResourcesDirectory("Resources");
|
||||
|
||||
|
||||
@@ -946,6 +946,7 @@ class EditorContentManager : IContentManager
|
||||
TextureLoader textureLoader = new .() ~ delete _;
|
||||
SpriteLoader spriteLoader = new .() ~ delete _;
|
||||
ShaderLoader shaderLoader = new .() ~ delete _;
|
||||
MaterialLoader materialLoader = new .() ~ delete _;
|
||||
|
||||
private IProcessedAssetLoader GetLoader(AssetType assetType)
|
||||
{
|
||||
@@ -957,6 +958,8 @@ class EditorContentManager : IContentManager
|
||||
return spriteLoader;
|
||||
case .Shader:
|
||||
return shaderLoader;
|
||||
case .Material:
|
||||
return materialLoader;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using GlitchyEngine.Renderer;
|
||||
|
||||
namespace GlitchyEngine.Content.Loaders;
|
||||
|
||||
class MaterialLoader : IProcessedAssetLoader
|
||||
{
|
||||
public Result<Asset> Load(Stream stream)
|
||||
{
|
||||
Compiler.Assert(sizeof(AssetHandle) == 8);
|
||||
|
||||
AssetHandle<Effect> effectHandle = Try!(stream.Read<AssetHandle>());
|
||||
|
||||
Effect effect = Content.GetAsset<Effect>(effectHandle, blocking: true);
|
||||
|
||||
Material material = new Material(effect);
|
||||
|
||||
uint16 textureCount = Try!(stream.Read<uint16>());
|
||||
|
||||
for (int i < textureCount)
|
||||
{
|
||||
AssetHandle<Texture> textureHandle = Try!(stream.Read<AssetHandle>());
|
||||
|
||||
int16 textureNameLength = Try!(stream.Read<int16>());
|
||||
String textureName = scope String(textureNameLength);
|
||||
stream.ReadStrSized32(textureNameLength, textureName);
|
||||
|
||||
material.SetTexture(textureName, textureHandle);
|
||||
}
|
||||
|
||||
uint16 bufferCount = Try!(stream.Read<uint16>());
|
||||
|
||||
for (int i < bufferCount)
|
||||
{
|
||||
int64 bufferDataSize = Try!(stream.Read<int64>());
|
||||
int16 textureNameLength = Try!(stream.Read<int16>());
|
||||
String textureName = scope String(textureNameLength);
|
||||
stream.ReadStrSized32(textureNameLength, textureName);
|
||||
|
||||
uint8[] data = new:ScopedAlloc! uint8[bufferDataSize];
|
||||
|
||||
Try!(stream.TryRead(data));
|
||||
|
||||
// TODO: Somehow get buffer data into material
|
||||
}
|
||||
|
||||
material.SetVariable("AlbedoColor", GlitchyEngine.Math.float4(1.0f, 0, 0, 1.0f));
|
||||
|
||||
return material;
|
||||
}
|
||||
}
|
||||
@@ -10,20 +10,20 @@ namespace GlitchyEngine.Renderer
|
||||
|
||||
private String _name ~ delete _;
|
||||
|
||||
private ShaderVariableType _type;
|
||||
private ShaderVariableType _elementType;
|
||||
|
||||
internal uint32 _columns;
|
||||
internal uint32 _rows;
|
||||
private uint32 _offset;
|
||||
internal uint32 _sizeInBytes;
|
||||
// Number of elements in the array
|
||||
internal uint32 _elements;
|
||||
internal uint32 _arrayElements;
|
||||
|
||||
private bool _isUsed;
|
||||
|
||||
public ConstantBuffer ConstantBuffer => _constantBuffer;
|
||||
|
||||
public ShaderVariableType Type => _type;
|
||||
public ShaderVariableType ElementType => _elementType;
|
||||
|
||||
public String Name => _name;
|
||||
|
||||
@@ -31,6 +31,9 @@ namespace GlitchyEngine.Renderer
|
||||
|
||||
public uint32 Columns => _columns;
|
||||
public uint32 Rows => _rows;
|
||||
public uint32 ArrayElements => _arrayElements;
|
||||
|
||||
public uint32 Offset => _offset;
|
||||
|
||||
/**
|
||||
* Gets a pointer to the start of the variable in the constant buffers backing data.
|
||||
@@ -38,16 +41,16 @@ namespace GlitchyEngine.Renderer
|
||||
[Inline]
|
||||
internal uint8* firstByte => _constantBuffer.rawData.CArray() + _offset;
|
||||
|
||||
public this(StringView name, ConstantBuffer constantBuffer, ShaderVariableType type, uint32 columns, uint32 rows, uint32 offset, uint32 sizeInBytes, uint32 elements, bool isUsed)
|
||||
public this(StringView name, ConstantBuffer constantBuffer, ShaderVariableType type, uint32 columns, uint32 rows, uint32 offset, uint32 sizeInBytes, uint32 arrayElements, bool isUsed)
|
||||
{
|
||||
_name = new String(name);
|
||||
_constantBuffer = constantBuffer; // Only hold a weak reference. This variable has to die with the buffer
|
||||
_type = type;
|
||||
_elementType = type;
|
||||
_columns = columns;
|
||||
_rows = rows;
|
||||
_offset = offset;
|
||||
_sizeInBytes = sizeInBytes;
|
||||
_elements = elements;
|
||||
_arrayElements = arrayElements;
|
||||
_isUsed = isUsed;
|
||||
}
|
||||
|
||||
@@ -64,8 +67,8 @@ namespace GlitchyEngine.Renderer
|
||||
#endif
|
||||
|
||||
#if GE_SHADER_VAR_TYPE_MISMATCH_IS_ERROR
|
||||
if (type != _type)
|
||||
Log.EngineLogger.Assert(false, scope $"The types do not match: Expected \"{_type}\" but Received \"{type}\" instead. Variable: \"{_name}\" of buffer: \"{_constantBuffer.Name}\"");
|
||||
if (type != _elementType)
|
||||
Log.EngineLogger.Assert(false, scope $"The types do not match: Expected \"{_elementType}\" but Received \"{type}\" instead. Variable: \"{_name}\" of buffer: \"{_constantBuffer.Name}\"");
|
||||
#elif GE_SHADER_VAR_TYPE_MISMATCH_IS_WARNING
|
||||
if (type != _type)
|
||||
Log.EngineLogger.Warning($"The types do not match: Expected \"{_type}\" but Received \"{type}\" instead. Variable: \"{_name}\" of buffer: \"{_constantBuffer.Name}\"");
|
||||
@@ -174,7 +177,7 @@ namespace GlitchyEngine.Renderer
|
||||
|
||||
// TODO: assert length
|
||||
|
||||
Internal.MemCpy(firstByte, value.Ptr, sizeof(Matrix4x3) * Math.Min(value.Count, _elements));
|
||||
Internal.MemCpy(firstByte, value.Ptr, sizeof(Matrix4x3) * Math.Min(value.Count, _arrayElements));
|
||||
}
|
||||
|
||||
public void SetData(Matrix3x3 value)
|
||||
@@ -192,7 +195,7 @@ namespace GlitchyEngine.Renderer
|
||||
|
||||
// TODO: assert length
|
||||
|
||||
for(int i < Math.Min(value.Count, _elements))
|
||||
for(int i < Math.Min(value.Count, _arrayElements))
|
||||
{
|
||||
((Matrix4x3*)firstByte)[i] = Matrix4x3(value[i]);
|
||||
}
|
||||
@@ -206,7 +209,7 @@ namespace GlitchyEngine.Renderer
|
||||
|
||||
// TODO: assert length
|
||||
|
||||
Internal.MemCpy(firstByte, value.Ptr, sizeof(Matrix) * Math.Min(value.Count, _elements));
|
||||
Internal.MemCpy(firstByte, value.Ptr, sizeof(Matrix) * Math.Min(value.Count, _arrayElements));
|
||||
}
|
||||
|
||||
// Todo: add all the other SetData-Methods
|
||||
|
||||
@@ -78,6 +78,7 @@ namespace GlitchyEngine.Renderer
|
||||
switch (this)
|
||||
{
|
||||
case .Bool:
|
||||
// TODO: I'm pretty sure this is wrong and should be 4 as well!
|
||||
return 1;
|
||||
case .Float:
|
||||
return 4;
|
||||
|
||||
@@ -93,9 +93,9 @@ public class Material : Asset
|
||||
{
|
||||
if (_variables.TryGetValue(newKey, let oldEntry))
|
||||
{
|
||||
if (oldEntry.Variable.Type == newValue.Variable.Type)
|
||||
if (oldEntry.Variable.ElementType == newValue.Variable.ElementType)
|
||||
{
|
||||
int elementSize = newValue.Variable.Type.ElementSizeInBytes();
|
||||
int elementSize = newValue.Variable.ElementType.ElementSizeInBytes();
|
||||
|
||||
for (int r = 0; r < Math.Min(oldEntry.Variable.Rows, newValue.Variable.Rows); r++)
|
||||
for (int c = 0; c < Math.Min(oldEntry.Variable.Columns, newValue.Variable.Columns); c++)
|
||||
@@ -259,7 +259,7 @@ public class Material : Asset
|
||||
{
|
||||
entry.Variable.EnsureTypeMatch<Matrix3x3>();
|
||||
|
||||
int count = Math.Min(values.Count, entry.Variable._elements);
|
||||
int count = Math.Min(values.Count, entry.Variable._arrayElements);
|
||||
|
||||
for(int i < count)
|
||||
{
|
||||
@@ -281,7 +281,7 @@ public class Material : Asset
|
||||
{
|
||||
entry.Variable.EnsureTypeMatch<Matrix>();
|
||||
|
||||
Internal.MemCpy(RawPointer!<Matrix>(entry.Offset), values.Ptr, sizeof(Matrix) * Math.Min(values.Count, entry.Variable._elements));
|
||||
Internal.MemCpy(RawPointer!<Matrix>(entry.Offset), values.Ptr, sizeof(Matrix) * Math.Min(values.Count, entry.Variable._arrayElements));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user