improved ECS and added new render component
This commit is contained in:
@ -0,0 +1,8 @@
|
||||
using Silk.NET.OpenGL;
|
||||
|
||||
namespace EngineSharp.Core.ECS;
|
||||
|
||||
public abstract class RenderComponent : IComponent
|
||||
{
|
||||
internal abstract void Render(GL gl);
|
||||
}
|
||||
@ -1,13 +1,15 @@
|
||||
using System.Linq;
|
||||
using Silk.NET.OpenGL;
|
||||
|
||||
namespace EngineSharp.Core.ECS;
|
||||
|
||||
public class Scene
|
||||
{
|
||||
private Dictionary<long, LogicComponent> _logicComponents = new();
|
||||
private Dictionary<long, DataComponent> _dataComponents = new();
|
||||
private readonly Dictionary<long, List<LogicComponent>> _logicComponents = new();
|
||||
private readonly Dictionary<long, List<DataComponent>> _dataComponents = new();
|
||||
private readonly Dictionary<long, List<RenderComponent>> _renderComponents = new();
|
||||
|
||||
private long _nextSceneId; // ugly solution but it works
|
||||
private long _nextSceneId; // not the prettiest solution but it works
|
||||
|
||||
public Entity CreateEntity(string name)
|
||||
{
|
||||
@ -16,63 +18,80 @@ public class Scene
|
||||
|
||||
internal void StartComponents()
|
||||
{
|
||||
foreach (var component in _logicComponents.Values)
|
||||
foreach (var components in _logicComponents.Values)
|
||||
{
|
||||
component.Start();
|
||||
components.ForEach(c => c.Start());
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateComponents(double deltaTime)
|
||||
{
|
||||
foreach (var component in _logicComponents.Values)
|
||||
foreach (var components in _logicComponents.Values)
|
||||
{
|
||||
component.OnUpdate(deltaTime);
|
||||
components.ForEach(c => c.OnUpdate(deltaTime));
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddComponent(Entity entity, IComponent component)
|
||||
internal void RenderComponents(GL gl)
|
||||
{
|
||||
foreach (var components in _renderComponents.Values)
|
||||
{
|
||||
components.ForEach(c => c.Render(gl));
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddComponent<T>(Entity entity, T component)
|
||||
where T : class, IComponent
|
||||
{
|
||||
switch (component)
|
||||
{
|
||||
case LogicComponent logic:
|
||||
_logicComponents.TryAdd(entity.Id, logic);
|
||||
AddComponent(entity.Id, logic, _logicComponents);
|
||||
break;
|
||||
case DataComponent data:
|
||||
_dataComponents.TryAdd(entity.Id, data);
|
||||
AddComponent(entity.Id, data, _dataComponents);
|
||||
break;
|
||||
case RenderComponent render:
|
||||
AddComponent(entity.Id, render, _renderComponents);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
internal IComponent? GetComponent(Entity entity, IComponent component)
|
||||
internal T? GetComponent<T>(Entity entity, T component)
|
||||
where T : class, IComponent
|
||||
{
|
||||
switch (component)
|
||||
return component switch
|
||||
{
|
||||
case LogicComponent logic:
|
||||
return GetComponent(entity.Id, logic);
|
||||
case DataComponent data:
|
||||
return GetComponent(entity.Id, data);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
LogicComponent => GetComponent<T, LogicComponent>(entity.Id, _logicComponents),
|
||||
DataComponent => GetComponent<T, DataComponent>(entity.Id, _dataComponents),
|
||||
RenderComponent => GetComponent<T, RenderComponent>(entity.Id, _renderComponents),
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
|
||||
private LogicComponent? GetComponent(long id, LogicComponent component)
|
||||
private static TComponent? GetComponent<TComponent, TArchetype>(long id, Dictionary<long, List<TArchetype>> componentStore)
|
||||
where TComponent : class, IComponent
|
||||
{
|
||||
if (_logicComponents.TryGetValue(id, out var logic))
|
||||
// ReSharper disable once ConvertIfStatementToReturnStatement
|
||||
if (componentStore.TryGetValue(id, out var components))
|
||||
{
|
||||
return logic;
|
||||
return components.OfType<TComponent>().SingleOrDefault();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private DataComponent? GetComponent(long id, DataComponent component)
|
||||
private static void AddComponent<TComponent, TArchetype>(long id, TComponent component, Dictionary<long, List<TArchetype>> componentStore)
|
||||
where TArchetype : class, IComponent
|
||||
where TComponent : TArchetype
|
||||
{
|
||||
if (_dataComponents.TryGetValue(id, out var data))
|
||||
if (componentStore.TryGetValue(id, out var components))
|
||||
{
|
||||
return data;
|
||||
components.Add(component);
|
||||
}
|
||||
else
|
||||
{
|
||||
componentStore.Add(id, [component]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -80,8 +80,12 @@ internal class OpenGLEngine : IEngine
|
||||
var viewMatrix = _camera.ViewMatrix;
|
||||
|
||||
// TODO: Here render all meshes etc.
|
||||
// On constructing a MeshRenderer, register it somewhere so it can be rendered here (MeshRenderer would then be a component while Mesh would be a normal C# object in the context of an ECS)
|
||||
// MeshRenderer contains a mesh; Mesh contains a material; Material contains a shader and the values for all uniforms of the shader (apart from the matrices; I am not sure how to best handle the model matrix with this approach)
|
||||
|
||||
if (_currentScene is not null)
|
||||
{
|
||||
_currentScene.RenderComponents(_gl);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnResize(Vector2D<int> newDimensions)
|
||||
|
||||
@ -1,14 +1,15 @@
|
||||
using Silk.NET.OpenGL;
|
||||
using EngineSharp.Core.ECS;
|
||||
using Silk.NET.OpenGL;
|
||||
|
||||
namespace EngineSharp.Core.Rendering;
|
||||
|
||||
public class MeshRenderer
|
||||
public class MeshRenderer : RenderComponent
|
||||
{
|
||||
public Mesh Mesh { get; set; }
|
||||
|
||||
private uint vao, vbo, ebo;
|
||||
|
||||
internal void Render(GL gl)
|
||||
internal override void Render(GL gl)
|
||||
{
|
||||
GenerateRenderableMesh(gl);
|
||||
gl.BindVertexArray(vao);
|
||||
|
||||
Reference in New Issue
Block a user