From e8a5594540c280dbef258ba6b93416766978b415 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Tue, 1 Aug 2023 13:28:04 +0200 Subject: [PATCH] Allow changing Effect of Materials + TextureDimension Property for Texture --- GlitchyEditor/SandboxProject/project_user.bon | 1 + .../src/Assets/MaterialAssetLoader.bf | 29 +++++ GlitchyEditor/src/ProjectUserSettings.bf | 1 - GlitchyEngine/src/Renderer/ConstantBuffer.bf | 25 ++++- GlitchyEngine/src/Renderer/Material.bf | 103 ++++++++++++++---- GlitchyEngine/src/Renderer/RenderTarget.bf | 4 +- GlitchyEngine/src/Renderer/Texture.bf | 6 + 7 files changed, 142 insertions(+), 27 deletions(-) create mode 100644 GlitchyEditor/SandboxProject/project_user.bon diff --git a/GlitchyEditor/SandboxProject/project_user.bon b/GlitchyEditor/SandboxProject/project_user.bon new file mode 100644 index 0000000..2204afa --- /dev/null +++ b/GlitchyEditor/SandboxProject/project_user.bon @@ -0,0 +1 @@ +{_recentScenes=["Assets\\Scenes\\physics2D.scene"]} \ No newline at end of file diff --git a/GlitchyEditor/src/Assets/MaterialAssetLoader.bf b/GlitchyEditor/src/Assets/MaterialAssetLoader.bf index 77d410c..45b3b23 100644 --- a/GlitchyEditor/src/Assets/MaterialAssetLoader.bf +++ b/GlitchyEditor/src/Assets/MaterialAssetLoader.bf @@ -59,9 +59,38 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor if (material == null) return; + + ImGui.TextUnformatted("Effect: "); + ImGui.SameLine(); Effect effect = material?.Effect; + StringView effectName = (effect?.Identifier ?? "(None)"); + + ImGui.Button(effectName.ToScopeCStr!()); + + ImGui.AttachTooltip(effectName); + + // Effect drop target + if (ImGui.BeginDragDropTarget()) + { + ImGui.Payload* payload = ImGui.AcceptDragDropPayload(.ContentBrowserItem); + + if (payload != null) + { + StringView path = .((char8*)payload.Data, (int)payload.DataSize); + + AssetHandle newEffect = Content.LoadAsset(path); + + material.Effect = newEffect; + + //newTexture.Get().SamplerState = SamplerStateManager.AnisotropicWrap; + //material.SetTexture(texture.key, newTexture.Cast()); + } + + ImGui.EndDragDropTarget(); + } + if (effect == null) return; diff --git a/GlitchyEditor/src/ProjectUserSettings.bf b/GlitchyEditor/src/ProjectUserSettings.bf index 6934e43..936ea9d 100644 --- a/GlitchyEditor/src/ProjectUserSettings.bf +++ b/GlitchyEditor/src/ProjectUserSettings.bf @@ -70,7 +70,6 @@ class ProjectUserSettings public void RestoreDefaults() { - //_lastOpenedScene?.Clear(); if (_recentScenes != null) ClearAndDeleteItems!(_recentScenes); diff --git a/GlitchyEngine/src/Renderer/ConstantBuffer.bf b/GlitchyEngine/src/Renderer/ConstantBuffer.bf index 2434f98..9efa9a1 100644 --- a/GlitchyEngine/src/Renderer/ConstantBuffer.bf +++ b/GlitchyEngine/src/Renderer/ConstantBuffer.bf @@ -104,10 +104,27 @@ namespace GlitchyEngine.Renderer public enum ShaderVariableType { - Bool, - Float, - Int, - UInt + case Bool; + case Float; + case Int; + case UInt; // todo + + public int ElementSizeInBytes() + { + switch (this) + { + case .Bool: + return 1; + case .Float: + return 4; + case .Int: + return 4; + case .UInt: + return 4; + default: + return 0; + } + } } } diff --git a/GlitchyEngine/src/Renderer/Material.bf b/GlitchyEngine/src/Renderer/Material.bf index 2bb3010..e074f22 100644 --- a/GlitchyEngine/src/Renderer/Material.bf +++ b/GlitchyEngine/src/Renderer/Material.bf @@ -14,30 +14,61 @@ public class Material : Asset private uint8[] _rawVariables ~ delete _; - private Dictionary Handle, TextureDimension Dimension)> _textures = new .() ~ delete _; + private Dictionary Handle, TextureDimension Dimension)> _textures = new .() ~ DeleteDictionaryAndKeys!(_); - private Dictionary _variables = new .() ~ delete _; + private Dictionary _variables = new .() ~ DeleteDictionaryAndKeys!(_); - public Effect Effect => _effect; + public Effect Effect + { + get => _effect; + set + { + SetReference!(_effect, value); + + if (_effect == null) + return; + + // TODO: get variables from effect + decltype(_textures) newTextures = new .(); + + // Get texture slots from effect + for(let (name, effectTexture) in _effect.Textures) + { + // TODO: We need to be able to define default textures in the shader. + // At least things like "Black", "White", "Normal" + // At best whole paths. Shouldn't be that hard to do... + + AssetHandle textureHandle = .Invalid; + + if (_textures.TryGetValue(name, let oldMaterialTexture)) + { + textureHandle = oldMaterialTexture.Handle; + } + + if (textureHandle.IsValid) + { + if (textureHandle.Dimension != effectTexture.TextureDimension) + textureHandle = .Invalid; + } + + _textures[new String(name)] = (textureHandle, effectTexture.TextureDimension); + } + + DeleteDictionaryAndKeys!(_textures); + _textures = newTextures; + + InitRawData(); + } + } + + public this() + { + + } public this(Effect effect) { - _effect = effect..AddRef(); - - // TODO: get variables from effect - - // Get texture slots from effect - for(let (name, entry) in _effect.Textures) - { - // TODO: We need to be able to define default textures in the shader. - // At least things like "Black", "White", "Normal" - // At best whole paths. Shouldn't be that hard to do... - /*var texture = entry.BoundTexture;*/ - - _textures.Add(name, (AssetHandle.Invalid, entry.TextureDimension)); - } - - InitRawData(); + Effect = effect; } @@ -47,14 +78,44 @@ public class Material : Asset { uint32 bufferSize = 0; + decltype(_variables) newVariables = new Dictionary(); + for(let variable in _effect.Variables) { - _variables.Add(variable.Name, (bufferSize, variable)); + newVariables.Add(new .(variable.Name), (bufferSize, variable)); bufferSize += variable._sizeInBytes; } - _rawVariables = new uint8[bufferSize]; + uint8[] newData = new uint8[bufferSize]; + + for (let (newKey, newValue) in newVariables) + { + if (_variables.TryGetValue(newKey, let oldEntry)) + { + if (oldEntry.Variable.Type == newValue.Variable.Type) + { + int elementSize = newValue.Variable.Type.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++) + { + int oldElementIndex = r * oldEntry.Variable.Columns + c; + int newElementIndex = r * newValue.Variable.Columns + c; + + Internal.MemCpy(newData.Ptr + (newValue.Offset + elementSize * oldElementIndex), + _rawVariables.Ptr + (oldEntry.Offset + elementSize * newElementIndex), elementSize); + } + } + // TODO: we could try to convert e.g. Int <-> Float + } + } + + delete _rawVariables; + _rawVariables = newData; + + DeleteDictionaryAndKeys!(_variables); + _variables = newVariables; } /** diff --git a/GlitchyEngine/src/Renderer/RenderTarget.bf b/GlitchyEngine/src/Renderer/RenderTarget.bf index 8d063f9..af11062 100644 --- a/GlitchyEngine/src/Renderer/RenderTarget.bf +++ b/GlitchyEngine/src/Renderer/RenderTarget.bf @@ -49,7 +49,9 @@ namespace GlitchyEngine.Renderer public override uint32 ArraySize => _description.ArraySize; public override uint32 MipLevels => _description.MipLevels; public override Format Format => _description.PixelFormat; - + + public override TextureDimension Dimension => .Texture2D; + protected internal DepthStencilTarget _depthStenilTarget ~ _?.ReleaseRef(); // TODO: DepthStencilTarget is just a renderTarget diff --git a/GlitchyEngine/src/Renderer/Texture.bf b/GlitchyEngine/src/Renderer/Texture.bf index ada746d..ef7d056 100644 --- a/GlitchyEngine/src/Renderer/Texture.bf +++ b/GlitchyEngine/src/Renderer/Texture.bf @@ -31,6 +31,8 @@ namespace GlitchyEngine.Renderer public abstract Format Format {get;} + public abstract TextureDimension Dimension {get;} + public abstract TextureViewBinding GetViewBinding(); } @@ -82,6 +84,8 @@ namespace GlitchyEngine.Renderer //public override extern uint32 ArraySize {get;} //public override extern uint32 MipLevels {get;} + public override TextureDimension Dimension => .Texture2D; + public this(Texture2DDesc desc) { PrepareTexturePlatform(desc, false); @@ -163,6 +167,8 @@ namespace GlitchyEngine.Renderer // public override extern uint32 ArraySize {get;} // public override extern uint32 MipLevels {get;} + public override TextureDimension Dimension => .TextureCube; + public this(Texture2DDesc desc) { PrepareTexturePlatform(desc, false);