Start of inheriting Materials, create material instance for getMaterial from scripts

This commit is contained in:
Simon Lübeß
2025-02-14 12:39:35 +01:00
parent aaed4199d3
commit 24295731f3
6 changed files with 66 additions and 17 deletions
+24 -17
View File
@@ -10,6 +10,15 @@ namespace GlitchyEngine.Renderer;
public class Material : Asset public class Material : Asset
{ {
/**
* If true, this material is a runtime instance and can be changed by scripts.
* If false, it is the actual material from the harddrive and should not be modified by scripts.
* If a script tries to modify it, a runtime instance will be created.
*/
private bool _isRuntimeInstance = false;
private Material _parent ~ _?.ReleaseRef();
private Effect _effect ~ _?.ReleaseRef(); private Effect _effect ~ _?.ReleaseRef();
private Dictionary<String, (AssetHandle<Texture> Handle, TextureDimension Dimension, int32? groupTarget)> _textures = new .() ~ DeleteDictionaryAndKeys!(_); private Dictionary<String, (AssetHandle<Texture> Handle, TextureDimension Dimension, int32? groupTarget)> _textures = new .() ~ DeleteDictionaryAndKeys!(_);
@@ -32,6 +41,11 @@ public class Material : Asset
} }
} }
// TODO: allow changing
public Material Parent => _parent;
public bool IsRuntimeInstance => _isRuntimeInstance;
public this() public this()
{ {
@@ -42,6 +56,13 @@ public class Material : Asset
Effect = effect; Effect = effect;
} }
public this(Material parentMaterial, bool isRuntimeInstance)
{
_parent = parentMaterial..AddRef();
Effect = _parent.Effect;
_isRuntimeInstance = isRuntimeInstance;
}
private void Init() private void Init()
{ {
decltype(_textures) newTextures = new .(); decltype(_textures) newTextures = new .();
@@ -99,7 +120,9 @@ public class Material : Asset
} }
} }
for (let (bufferName, buffer) in _effect.Buffers) BufferCollection parentBuffers = _parent?._bufferCollection ?? _effect.Buffers;
for (let (bufferName, buffer) in parentBuffers)
{ {
if (buffer == null) if (buffer == null)
continue; continue;
@@ -171,28 +194,12 @@ public class Material : Asset
{ {
if(_textures.TryGetValue(name, var entry)) if(_textures.TryGetValue(name, var entry))
{ {
/*switch (texture.Get().GetType())
{
//case .Texture1D:
// _textures[name].Dimension = .Texture1D;
case typeof(Texture2D):
_textures[name].Dimension = .Texture2D;
case typeof(TextureCube):
_textures[name].Dimension = .TextureCube;
//case .Texture3D:
// _textures[name].Dimension = .Texture3D;
default:
_textures[name].Dimension = .Unknown;
}*/
//entry?.ReleaseRef();
_textures[name].Handle = texture; _textures[name].Handle = texture;
_textures[name].groupTarget = groupTargetIndex; _textures[name].groupTarget = groupTargetIndex;
//texture?.AddRef();
} }
else else
{ {
Log.EngineLogger.Error($"Material doesn't have the texture slot \"{name}\""); Log.EngineLogger.Error($"Material doesn't have the texture slot \"{name}\"");
//Log.EngineLogger.Assert(false);
} }
} }
+22
View File
@@ -1054,6 +1054,17 @@ static class ScriptGlue
static void SpriteRenderer_GetMaterial(UUID entityId, out AssetHandle assetId) static void SpriteRenderer_GetMaterial(UUID entityId, out AssetHandle assetId)
{ {
SpriteRendererComponent* spriteRenderer = GetComponentSafe<SpriteRendererComponent>(entityId); SpriteRendererComponent* spriteRenderer = GetComponentSafe<SpriteRendererComponent>(entityId);
Material material = GetAssetOrThrow!<Material>((AssetHandle)spriteRenderer.Material);
if (!material.IsRuntimeInstance)
{
material = new Material(material, true);
material.Identifier = scope $"(Instance) {material.Identifier}";
Content.ManageAsset(material);
spriteRenderer.Material = material.Handle;
}
assetId = spriteRenderer.Material; assetId = spriteRenderer.Material;
} }
@@ -1162,6 +1173,17 @@ static class ScriptGlue
static void MeshRenderer_GetMaterial(UUID entityId, out AssetHandle assetId) static void MeshRenderer_GetMaterial(UUID entityId, out AssetHandle assetId)
{ {
MeshRendererComponent* meshRenderer = GetComponentSafe<MeshRendererComponent>(entityId); MeshRendererComponent* meshRenderer = GetComponentSafe<MeshRendererComponent>(entityId);
Material material = GetAssetOrThrow!<Material>((AssetHandle)meshRenderer.Material);
if (!material.IsRuntimeInstance)
{
material = new Material(material, true);
material.Identifier = scope $"(Instance) {material.Identifier}";
Content.ManageAsset(material);
meshRenderer.Material = material.Handle;
}
assetId = meshRenderer.Material; assetId = meshRenderer.Material;
} }
+9
View File
@@ -25,4 +25,13 @@ public abstract class EngineObject
{ {
_uuid = uuid; _uuid = uuid;
} }
/// <summary>Determines whether the specified <see cref="EngineObject"/> is equal to the current <see cref="EngineObject"/>.</summary>
/// <param name="other">The object to compare with the current object.</param>
/// <returns>true if the specified object is equal to the current object; otherwise, false.</returns>
public bool Equals(EngineObject other)
{
// TODO: Are we really only interested in what equates to reference equality on the engine side?
return _uuid == other._uuid;
}
} }
+3
View File
@@ -3,6 +3,9 @@ using GlitchyEngine.Math;
namespace GlitchyEngine.Graphics; namespace GlitchyEngine.Graphics;
/// <summary>
/// An <see cref="Asset"/> that represents how a surface should be rendered.
/// </summary>
public class Material : Asset public class Material : Asset
{ {
public void SetVariable(string name, float4 value) public void SetVariable(string name, float4 value)
+4
View File
@@ -10,6 +10,10 @@ public class MeshRenderer : Component
/// <summary> /// <summary>
/// Gets or sets the Material of this <see cref="MeshRenderer"/>. /// Gets or sets the Material of this <see cref="MeshRenderer"/>.
/// </summary> /// </summary>
/// <remarks>
/// If you get the <see cref="Material"/> and it is not yet a runtime-instance,
/// a new runtime-instance will be created and returned in its place.
/// </remarks>
public Material Material public Material Material
{ {
get get
+4
View File
@@ -39,6 +39,10 @@ public class SpriteRenderer : Component
/// <summary> /// <summary>
/// Gets or sets the Material of this SpriteRenderer. /// Gets or sets the Material of this SpriteRenderer.
/// </summary> /// </summary>
/// <remarks>
/// If you get the <see cref="Material"/> and it is not yet a runtime-instance,
/// a new runtime-instance will be created and returned in its place.
/// </remarks>
public Material Material public Material Material
{ {
get get