Fix null warnings in StandardRenderSystem, remove SceneGraph module, temporarily disable nullables in TestGame.
This commit is contained in:
@@ -1,12 +0,0 @@
|
|||||||
using Voile.Rendering;
|
|
||||||
using Voile.SceneGraph;
|
|
||||||
|
|
||||||
namespace Voile;
|
|
||||||
|
|
||||||
public class Circle2d : Drawable2d
|
|
||||||
{
|
|
||||||
public override void OnDraw(RenderSystem renderer)
|
|
||||||
{
|
|
||||||
renderer.DrawCircle(32f, Color.AliceBlue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,6 +4,7 @@ using Voile.Utils;
|
|||||||
using Voile.Input;
|
using Voile.Input;
|
||||||
using Voile.Systems.Particles;
|
using Voile.Systems.Particles;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
public class TestGame : Game
|
public class TestGame : Game
|
||||||
{
|
{
|
||||||
@@ -12,6 +13,7 @@ public class TestGame : Game
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
InitializeDefault();
|
InitializeDefault();
|
||||||
|
|
||||||
_particleSystem = new ParticleSystem();
|
_particleSystem = new ParticleSystem();
|
||||||
|
|
||||||
ResourceManager.AddResourceLoaderAssociation(new ParticleEmitterSettingsResourceLoader());
|
ResourceManager.AddResourceLoaderAssociation(new ParticleEmitterSettingsResourceLoader());
|
||||||
@@ -33,13 +35,13 @@ public class TestGame : Game
|
|||||||
|
|
||||||
if (!ResourceManager.TryLoad("test_emitter.toml", out _emitterSettings))
|
if (!ResourceManager.TryLoad("test_emitter.toml", out _emitterSettings))
|
||||||
{
|
{
|
||||||
|
throw new Exception("Failed to load emitter settings!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Ready()
|
protected override void Ready()
|
||||||
{
|
{
|
||||||
_emitterId = _particleSystem!.CreateEmitter(Renderer.WindowSize / 2, _emitterSettings);
|
_emitterId = _particleSystem.CreateEmitter(Renderer.WindowSize / 2, _emitterSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Run()
|
protected override void Run()
|
||||||
@@ -87,8 +89,8 @@ public class TestGame : Game
|
|||||||
Renderer.EndBlended();
|
Renderer.EndBlended();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ParticleSystem? _particleSystem;
|
[NotNull] private ParticleSystem _particleSystem;
|
||||||
private int _emitterId;
|
private int _emitterId;
|
||||||
private ResourceRef<ParticleEmitterSettingsResource>? _emitterSettings;
|
private ResourceRef<ParticleEmitterSettingsResource> _emitterSettings;
|
||||||
private Logger _logger = new(nameof(TestGame));
|
private Logger _logger = new(nameof(TestGame));
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>disable</Nullable>
|
||||||
<PublishAot>true</PublishAot>
|
<PublishAot>true</PublishAot>
|
||||||
<RuntimeIdentifiers>win-x64;linux-x64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x64;linux-x64</RuntimeIdentifiers>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
using Voile;
|
|
||||||
using Voile.Extensions;
|
|
||||||
using Voile.SceneGraph;
|
|
||||||
using Voile.Utils;
|
|
||||||
|
|
||||||
public class TestPlayer : RectangleShape2d
|
|
||||||
{
|
|
||||||
public float SprintSpeed { get; set; } = 400f;
|
|
||||||
protected override void OnStart()
|
|
||||||
{
|
|
||||||
base.OnStart();
|
|
||||||
Color = Color.Cyan;
|
|
||||||
|
|
||||||
_camera = new Camera2d()
|
|
||||||
{
|
|
||||||
Current = true,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (Layer is not null)
|
|
||||||
{
|
|
||||||
Layer.AddEntity(_camera);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnUpdate(double dt)
|
|
||||||
{
|
|
||||||
base.OnUpdate(dt);
|
|
||||||
|
|
||||||
var sprinting = Input.IsActionDown("sprint");
|
|
||||||
_speed = sprinting ? SprintSpeed : 200f;
|
|
||||||
|
|
||||||
var velocity = Input.GetInputDirection("left", "right", "up", "down") * _speed;
|
|
||||||
Position += velocity * (float)dt;
|
|
||||||
|
|
||||||
if (_camera is not null)
|
|
||||||
{
|
|
||||||
_camera.Position = _camera.Position.Lerp(Position, dt * 5f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Logger _logger = new(nameof(TestPlayer));
|
|
||||||
private float _speed = 200f;
|
|
||||||
private Camera2d? _camera;
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
using System.Numerics;
|
|
||||||
using Voile;
|
|
||||||
using Voile.Rendering;
|
|
||||||
using Voile.SceneGraph;
|
|
||||||
using Voile.UI;
|
|
||||||
using Voile.Utils;
|
|
||||||
|
|
||||||
public class UiLayer : Layer
|
|
||||||
{
|
|
||||||
protected override void OnStart()
|
|
||||||
{
|
|
||||||
base.OnStart();
|
|
||||||
|
|
||||||
GetResources();
|
|
||||||
CreateUiElements();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnUpdate(double dt)
|
|
||||||
{
|
|
||||||
base.OnUpdate(dt);
|
|
||||||
if (Scene is null) return;
|
|
||||||
_screenContainer.UpdateRect(Vector2.Zero, Scene.Renderer.WindowSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnBeginDraw(RenderSystem renderer)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnDraw(RenderSystem renderer)
|
|
||||||
{
|
|
||||||
_screenContainer.Render(renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnEndDraw(RenderSystem renderer)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CreateUiElements()
|
|
||||||
{
|
|
||||||
if (Scene is null) return;
|
|
||||||
|
|
||||||
_screenContainer.UpdateRect(Vector2.Zero, Scene.Renderer.WindowSize);
|
|
||||||
|
|
||||||
var style = new PanelStyle()
|
|
||||||
{
|
|
||||||
BackgroundColor = new Color(0.2f, 0.2f, 0.2f, 1.0f)
|
|
||||||
};
|
|
||||||
|
|
||||||
_panel = new MarginPanel(style)
|
|
||||||
{
|
|
||||||
ExpandRatio = new Vector2(0.5f, 1f),
|
|
||||||
AbsoluteMargin = Vector2.One * 16f
|
|
||||||
};
|
|
||||||
_screenContainer.AddChild(_panel);
|
|
||||||
|
|
||||||
var exampleText = new TextLabel()
|
|
||||||
{
|
|
||||||
Font = _defaultFont!,
|
|
||||||
FontSize = 20,
|
|
||||||
Text = "This Panel will occupy 50% of the screen.\nThis text in particular is inside a panel with an absolute margin of 16px.\nHow cool is that?"
|
|
||||||
};
|
|
||||||
|
|
||||||
var contentPanel = new MarginPanel(new PanelStyle()
|
|
||||||
{
|
|
||||||
BackgroundColor = new Color(0.25f, 0.25f, 0.25f, 1.0f)
|
|
||||||
})
|
|
||||||
{
|
|
||||||
AbsoluteMargin = Vector2.One * 32f
|
|
||||||
};
|
|
||||||
|
|
||||||
_panel.AddChild(contentPanel);
|
|
||||||
|
|
||||||
var verticalPanel = new MarginPanel(new PanelStyle()
|
|
||||||
{
|
|
||||||
BackgroundColor = new Color(0.1f, 0.1f, 0.1f, 1.0f),
|
|
||||||
})
|
|
||||||
{
|
|
||||||
AbsoluteMargin = Vector2.One * 8f,
|
|
||||||
};
|
|
||||||
|
|
||||||
contentPanel.AddChild(verticalPanel);
|
|
||||||
verticalPanel.AddChild(exampleText);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GetResources()
|
|
||||||
{
|
|
||||||
ResourceManager.TryGetResource("inter_regular", out _defaultFont);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private Font? _defaultFont;
|
|
||||||
private Container _screenContainer = new();
|
|
||||||
private Panel? _panel;
|
|
||||||
|
|
||||||
private Logger _logger = new(nameof(UiLayer));
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using System.Numerics;
|
|
||||||
using Voile;
|
|
||||||
using Voile.Rendering;
|
|
||||||
using Voile.SceneGraph;
|
|
||||||
|
|
||||||
public class World : Drawable2d
|
|
||||||
{
|
|
||||||
protected override void OnStart()
|
|
||||||
{
|
|
||||||
base.OnStart();
|
|
||||||
|
|
||||||
_randomPositions = new Vector2[_rectangleAmount];
|
|
||||||
for (int i = 0; i < _rectangleAmount - 1; i++)
|
|
||||||
{
|
|
||||||
_randomPositions[i] = MathUtils.RandomVector2(Position, Vector2.One * 2048f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public override void OnDraw(RenderSystem renderer)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < _rectangleAmount; i++)
|
|
||||||
{
|
|
||||||
renderer.SetTransform(_randomPositions[i], PivotOffset, 0);
|
|
||||||
renderer.DrawRectangle(Vector2.One * 16f, _rectangleColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Color _rectangleColor = new Color(0.25f, 0.25f, 0.25f, 1.0f);
|
|
||||||
private int _rectangleAmount = 6000;
|
|
||||||
private Vector2[] _randomPositions;
|
|
||||||
}
|
|
||||||
@@ -67,6 +67,21 @@ namespace Voile
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
|
if (Renderer is null)
|
||||||
|
{
|
||||||
|
throw new NullReferenceException("No renderer provided.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Input is null)
|
||||||
|
{
|
||||||
|
throw new NullReferenceException("No input system provided.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ResourceManager is null)
|
||||||
|
{
|
||||||
|
throw new NullReferenceException("No ResourceManager provided.");
|
||||||
|
}
|
||||||
|
|
||||||
Initialize();
|
Initialize();
|
||||||
LoadResources();
|
LoadResources();
|
||||||
Ready();
|
Ready();
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Voile.Rendering
|
|||||||
public class StandardRenderSystem : RenderSystem
|
public class StandardRenderSystem : RenderSystem
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override Vector2 WindowSize { get; set; }
|
public override Vector2 WindowSize { get => _windowSize; set { _windowSize = value; } }
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool ShouldRun => !_window?.IsClosing ?? false;
|
public override bool ShouldRun => !_window?.IsClosing ?? false;
|
||||||
|
|
||||||
@@ -189,7 +189,7 @@ namespace Voile.Rendering
|
|||||||
|
|
||||||
private unsafe void CreateApi()
|
private unsafe void CreateApi()
|
||||||
{
|
{
|
||||||
_wgpu = WebGPU.GetApi();
|
_wgpu = WebGPU.GetApi() ?? throw new Exception("Failed to initialize WebGPU API.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void CreateInstance()
|
private unsafe void CreateInstance()
|
||||||
@@ -205,6 +205,11 @@ namespace Voile.Rendering
|
|||||||
|
|
||||||
private unsafe void CreateAdapter()
|
private unsafe void CreateAdapter()
|
||||||
{
|
{
|
||||||
|
if (_wgpu is null)
|
||||||
|
{
|
||||||
|
throw new Exception("WebGPU API is not initialized!");
|
||||||
|
}
|
||||||
|
|
||||||
RequestAdapterOptions adapterOptions = new()
|
RequestAdapterOptions adapterOptions = new()
|
||||||
{
|
{
|
||||||
CompatibleSurface = _surface,
|
CompatibleSurface = _surface,
|
||||||
@@ -224,13 +229,13 @@ namespace Voile.Rendering
|
|||||||
|
|
||||||
_wgpu.AdapterGetProperties(_adapter, &adapterProperties);
|
_wgpu.AdapterGetProperties(_adapter, &adapterProperties);
|
||||||
|
|
||||||
string deviceName = Marshal.PtrToStringAnsi((IntPtr)adapterProperties.Name);
|
string deviceName = Marshal.PtrToStringAnsi((IntPtr)adapterProperties.Name) ?? string.Empty;
|
||||||
|
|
||||||
_logger.Info($"Retrieved WebGPU Adapter ({deviceName})");
|
_logger.Info($"Retrieved WebGPU Adapter ({deviceName})");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string msg = Marshal.PtrToStringAnsi((IntPtr)msgPtr);
|
string msg = Marshal.PtrToStringAnsi((IntPtr)msgPtr) ?? string.Empty;
|
||||||
_logger.Error($"Error while retrieving WebGPU Adapter: {msg}");
|
_logger.Error($"Error while retrieving WebGPU Adapter: {msg}");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -240,6 +245,11 @@ namespace Voile.Rendering
|
|||||||
|
|
||||||
private unsafe void CreateDevice()
|
private unsafe void CreateDevice()
|
||||||
{
|
{
|
||||||
|
if (_wgpu is null)
|
||||||
|
{
|
||||||
|
throw new Exception("WebGPU API is not initialized!");
|
||||||
|
}
|
||||||
|
|
||||||
DeviceDescriptor deviceDescriptor = new();
|
DeviceDescriptor deviceDescriptor = new();
|
||||||
|
|
||||||
PfnRequestDeviceCallback callback = PfnRequestDeviceCallback.From(
|
PfnRequestDeviceCallback callback = PfnRequestDeviceCallback.From(
|
||||||
@@ -252,7 +262,7 @@ namespace Voile.Rendering
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string msg = Marshal.PtrToStringAnsi((IntPtr)msgPtr);
|
string msg = Marshal.PtrToStringAnsi((IntPtr)msgPtr) ?? string.Empty;
|
||||||
_logger.Error($"Error while retrieving WebGPU Device: {msg}");
|
_logger.Error($"Error while retrieving WebGPU Device: {msg}");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -262,6 +272,11 @@ namespace Voile.Rendering
|
|||||||
|
|
||||||
private unsafe void ConfigureSurface()
|
private unsafe void ConfigureSurface()
|
||||||
{
|
{
|
||||||
|
if (_wgpu is null)
|
||||||
|
{
|
||||||
|
throw new Exception("WebGPU API is not initialized!");
|
||||||
|
}
|
||||||
|
|
||||||
SurfaceConfiguration configuration = new SurfaceConfiguration
|
SurfaceConfiguration configuration = new SurfaceConfiguration
|
||||||
{
|
{
|
||||||
Device = _device,
|
Device = _device,
|
||||||
@@ -272,14 +287,19 @@ namespace Voile.Rendering
|
|||||||
Usage = TextureUsage.RenderAttachment
|
Usage = TextureUsage.RenderAttachment
|
||||||
};
|
};
|
||||||
|
|
||||||
_wgpu!.SurfaceConfigure(_surface, configuration);
|
_wgpu.SurfaceConfigure(_surface, configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void ConfigureDebugCallback()
|
private unsafe void ConfigureDebugCallback()
|
||||||
{
|
{
|
||||||
|
if (_wgpu is null)
|
||||||
|
{
|
||||||
|
throw new Exception("WebGPU API is not initialized!");
|
||||||
|
}
|
||||||
|
|
||||||
PfnErrorCallback callback = PfnErrorCallback.From((type, msgPtr, userDataPtr) =>
|
PfnErrorCallback callback = PfnErrorCallback.From((type, msgPtr, userDataPtr) =>
|
||||||
{
|
{
|
||||||
string msg = Marshal.PtrToStringAnsi((IntPtr)msgPtr);
|
string msg = Marshal.PtrToStringAnsi((IntPtr)msgPtr) ?? string.Empty;
|
||||||
_logger.Error($"WebGPU Error: {msg}");
|
_logger.Error($"WebGPU Error: {msg}");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -289,6 +309,11 @@ namespace Voile.Rendering
|
|||||||
|
|
||||||
private unsafe void WgpuBeginFrame()
|
private unsafe void WgpuBeginFrame()
|
||||||
{
|
{
|
||||||
|
if (_wgpu is null)
|
||||||
|
{
|
||||||
|
throw new Exception("WebGPU API is not initialized!");
|
||||||
|
}
|
||||||
|
|
||||||
_queue = _wgpu.DeviceGetQueue(_device);
|
_queue = _wgpu.DeviceGetQueue(_device);
|
||||||
|
|
||||||
_commandEncoder = _wgpu.DeviceCreateCommandEncoder(_device, null);
|
_commandEncoder = _wgpu.DeviceCreateCommandEncoder(_device, null);
|
||||||
@@ -309,6 +334,11 @@ namespace Voile.Rendering
|
|||||||
|
|
||||||
private unsafe void WgpuEndFrame()
|
private unsafe void WgpuEndFrame()
|
||||||
{
|
{
|
||||||
|
if (_wgpu is null)
|
||||||
|
{
|
||||||
|
throw new Exception("WebGPU API is not initialized!");
|
||||||
|
}
|
||||||
|
|
||||||
_wgpu.RenderPassEncoderEnd(_renderPassEncoder);
|
_wgpu.RenderPassEncoderEnd(_renderPassEncoder);
|
||||||
var commandBuffer = _wgpu.CommandEncoderFinish(_commandEncoder, null);
|
var commandBuffer = _wgpu.CommandEncoderFinish(_commandEncoder, null);
|
||||||
_wgpu.CommandEncoderRelease(_commandEncoder);
|
_wgpu.CommandEncoderRelease(_commandEncoder);
|
||||||
@@ -325,7 +355,7 @@ namespace Voile.Rendering
|
|||||||
|
|
||||||
private unsafe void ShutdownUnsafe()
|
private unsafe void ShutdownUnsafe()
|
||||||
{
|
{
|
||||||
_wgpu.DeviceDestroy(_device);
|
_wgpu!.DeviceDestroy(_device);
|
||||||
_wgpu.InstanceRelease(_instance);
|
_wgpu.InstanceRelease(_instance);
|
||||||
_wgpu.SurfaceRelease(_surface);
|
_wgpu.SurfaceRelease(_surface);
|
||||||
_wgpu.AdapterRelease(_adapter);
|
_wgpu.AdapterRelease(_adapter);
|
||||||
@@ -365,7 +395,7 @@ namespace Voile.Rendering
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Vector2 _windowSize;
|
private Vector2 _windowSize = Vector2.Zero;
|
||||||
private IWindow? _window;
|
private IWindow? _window;
|
||||||
|
|
||||||
private Color _clearColor = Color.Black;
|
private Color _clearColor = Color.Black;
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
using System.Numerics;
|
|
||||||
|
|
||||||
namespace Voile.SceneGraph;
|
|
||||||
|
|
||||||
public class Camera2d : Entity2d
|
|
||||||
{
|
|
||||||
public Vector2 Offset { get; set; }
|
|
||||||
public float Zoom { get; set; } = 1f;
|
|
||||||
public bool Current
|
|
||||||
{
|
|
||||||
get => _current; set
|
|
||||||
{
|
|
||||||
_current = value;
|
|
||||||
Layer?.UpdateCurrentCamera();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnStart()
|
|
||||||
{
|
|
||||||
base.OnStart();
|
|
||||||
Offset = Renderer.WindowSize / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool _current;
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
using Voile.Rendering;
|
|
||||||
|
|
||||||
namespace Voile.SceneGraph
|
|
||||||
{
|
|
||||||
public class CircleShape2d : Drawable2d
|
|
||||||
{
|
|
||||||
public float Radius { get => _radius; set => _radius = value; }
|
|
||||||
public Color Color { get => _color; set => _color = value; }
|
|
||||||
|
|
||||||
public override void OnDraw(RenderSystem renderer)
|
|
||||||
{
|
|
||||||
renderer.DrawCircle(_radius, _color);
|
|
||||||
}
|
|
||||||
|
|
||||||
private float _radius = 16;
|
|
||||||
private Color _color = Color.White;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
using System.Numerics;
|
|
||||||
using Voile.Rendering;
|
|
||||||
|
|
||||||
namespace Voile.SceneGraph
|
|
||||||
{
|
|
||||||
public abstract class Drawable2d : Entity2d, IDrawable
|
|
||||||
{
|
|
||||||
public Vector2 PivotOffset { get; set; }
|
|
||||||
public void Draw(RenderSystem renderer)
|
|
||||||
{
|
|
||||||
renderer.SetTransform(Position, PivotOffset, Rotation);
|
|
||||||
OnDraw(renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void OnDraw(RenderSystem renderer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
using System.Text.Json.Serialization;
|
|
||||||
using Voile.Audio;
|
|
||||||
using Voile.Input;
|
|
||||||
using Voile.Rendering;
|
|
||||||
|
|
||||||
namespace Voile.SceneGraph
|
|
||||||
{
|
|
||||||
public class Entity
|
|
||||||
{
|
|
||||||
[JsonIgnore] public EntityLayer? Layer { get; set; }
|
|
||||||
[JsonIgnore] public InputSystem Input => Layer!.Scene.Input;
|
|
||||||
[JsonIgnore] public AudioSystem Audio => Layer!.Scene.Audio;
|
|
||||||
[JsonIgnore] public RenderSystem Renderer => Layer!.Scene.Renderer;
|
|
||||||
public int Id { get; set; }
|
|
||||||
|
|
||||||
public void Start() => OnStart();
|
|
||||||
public void Update(double dt) => OnUpdate(dt);
|
|
||||||
public void ReceiveInput(InputSystem input) => OnInput(input);
|
|
||||||
|
|
||||||
protected virtual void OnStart() { }
|
|
||||||
protected virtual void OnDestroy() { }
|
|
||||||
protected virtual void OnUpdate(double dt) { }
|
|
||||||
protected virtual void OnInput(InputSystem input) { }
|
|
||||||
|
|
||||||
public void Destroy()
|
|
||||||
{
|
|
||||||
OnDestroy();
|
|
||||||
Layer?.DestroyEntity(Id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
|
||||||
[JsonSerializable(typeof(Entity))]
|
|
||||||
internal partial class EntitySourceGenerationContext : JsonSerializerContext
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
using System.Numerics;
|
|
||||||
|
|
||||||
namespace Voile.SceneGraph
|
|
||||||
{
|
|
||||||
public class Entity2d : Entity
|
|
||||||
{
|
|
||||||
public Vector2 Position { get; set; }
|
|
||||||
public float Rotation { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
using Voile.Rendering;
|
|
||||||
|
|
||||||
namespace Voile.SceneGraph
|
|
||||||
{
|
|
||||||
public interface IDrawable
|
|
||||||
{
|
|
||||||
public void Draw(RenderSystem renderer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
using System.Numerics;
|
|
||||||
using Voile.Rendering;
|
|
||||||
|
|
||||||
namespace Voile.SceneGraph;
|
|
||||||
|
|
||||||
public class RectangleShape2d : Drawable2d
|
|
||||||
{
|
|
||||||
public Vector2 Size { get; set; } = Vector2.One * 32;
|
|
||||||
public Color Color { get; set; } = Color.White;
|
|
||||||
public override void OnDraw(RenderSystem renderer)
|
|
||||||
{
|
|
||||||
PivotOffset = Size / 2;
|
|
||||||
renderer.DrawRectangle(Size, Color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
using System.Drawing;
|
|
||||||
|
|
||||||
using Voile.Rendering;
|
|
||||||
|
|
||||||
namespace Voile.SceneGraph
|
|
||||||
{
|
|
||||||
public class Sprite2d : Drawable2d
|
|
||||||
{
|
|
||||||
public Texture2d Texture { get => _texture ?? Texture2d.Empty; set => _texture = value; }
|
|
||||||
|
|
||||||
protected override void OnStart()
|
|
||||||
{
|
|
||||||
var renderer = Layer.Scene.Renderer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnDraw(RenderSystem renderer)
|
|
||||||
{
|
|
||||||
renderer.DrawTexture(_texture!, Color.White);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Texture2d? _texture;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
using Voile.Rendering;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
namespace Voile.SceneGraph
|
|
||||||
{
|
|
||||||
public class Text2d : Drawable2d
|
|
||||||
{
|
|
||||||
public string Text { get => _text; set => _text = value; }
|
|
||||||
public Color FontColor { get => _fontColor; set => _fontColor = value; }
|
|
||||||
public Font Font
|
|
||||||
{
|
|
||||||
get => _font; set
|
|
||||||
{
|
|
||||||
_isDirty = true;
|
|
||||||
_font = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Text2d(Font font)
|
|
||||||
{
|
|
||||||
_font = font;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnDraw(RenderSystem renderer)
|
|
||||||
{
|
|
||||||
if (_font == null)
|
|
||||||
{
|
|
||||||
renderer.DrawDebugText(_text, 20, _fontColor);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
renderer.DrawText(_font, _text, _fontColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string _text = string.Empty;
|
|
||||||
private Color _fontColor = Color.White;
|
|
||||||
private Font _font;
|
|
||||||
private int _fontHandle;
|
|
||||||
private bool _isDirty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
using System.Text.Json.Serialization;
|
|
||||||
using Voile.Rendering;
|
|
||||||
using Voile.Utils;
|
|
||||||
|
|
||||||
namespace Voile.SceneGraph
|
|
||||||
{
|
|
||||||
public class EntityLayer : Layer
|
|
||||||
{
|
|
||||||
public List<Entity> Entities { get; set; }
|
|
||||||
public Camera2d? CurrentCamera { get; set; }
|
|
||||||
|
|
||||||
public EntityLayer(List<Entity> entities)
|
|
||||||
{
|
|
||||||
Entities = entities;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntityLayer()
|
|
||||||
{
|
|
||||||
Entities = new List<Entity>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateCurrentCamera()
|
|
||||||
{
|
|
||||||
if (_cameraEntities.Count == 1)
|
|
||||||
{
|
|
||||||
CurrentCamera = _cameraEntities[0];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (var camera in _cameraEntities)
|
|
||||||
{
|
|
||||||
if (camera.Current) CurrentCamera = camera;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddEntity(Entity entity)
|
|
||||||
{
|
|
||||||
entity.Id = Entities.Count;
|
|
||||||
entity.Layer = this;
|
|
||||||
|
|
||||||
if (entity is Camera2d camera2d)
|
|
||||||
{
|
|
||||||
_cameraEntities.Add(camera2d);
|
|
||||||
UpdateCurrentCamera();
|
|
||||||
}
|
|
||||||
|
|
||||||
Entities.Add(entity);
|
|
||||||
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DestroyEntity(int at)
|
|
||||||
{
|
|
||||||
Entities.RemoveAt(at);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnStart()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < Entities.Count; i++)
|
|
||||||
{
|
|
||||||
var entity = Entities[i];
|
|
||||||
entity.Layer = this;
|
|
||||||
entity.Start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnUpdate(double dt)
|
|
||||||
{
|
|
||||||
foreach (var entity in Entities)
|
|
||||||
{
|
|
||||||
entity.Update(dt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnBeginDraw(RenderSystem renderer)
|
|
||||||
{
|
|
||||||
if (CurrentCamera is not null)
|
|
||||||
{
|
|
||||||
renderer.BeginCamera2d(CurrentCamera.Offset, CurrentCamera.Position, 0f, CurrentCamera.Zoom);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnEndDraw(RenderSystem renderer)
|
|
||||||
{
|
|
||||||
if (CurrentCamera is not null)
|
|
||||||
{
|
|
||||||
renderer.EndCamera2d();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected override void OnDraw(RenderSystem renderer)
|
|
||||||
{
|
|
||||||
// TODO: can be done more efficiently, needs rendering redesign.
|
|
||||||
foreach (var entity in Entities)
|
|
||||||
{
|
|
||||||
if (entity is IDrawable drawable)
|
|
||||||
{
|
|
||||||
drawable.Draw(renderer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private List<Camera2d> _cameraEntities = new();
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
|
||||||
[JsonSerializable(typeof(EntityLayer))]
|
|
||||||
[JsonSerializable(typeof(Entity))]
|
|
||||||
[JsonSerializable(typeof(List<Entity>))]
|
|
||||||
internal partial class EntityLayerContext : JsonSerializerContext
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
namespace Voile.SceneGraph
|
|
||||||
{
|
|
||||||
public interface IMainLoop
|
|
||||||
{
|
|
||||||
void Init();
|
|
||||||
void Start();
|
|
||||||
void Update();
|
|
||||||
double DeltaTime { get; }
|
|
||||||
bool ShouldRun { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
using Voile.Resources;
|
|
||||||
using Voile.Rendering;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
using Voile.Input;
|
|
||||||
|
|
||||||
namespace Voile.SceneGraph
|
|
||||||
{
|
|
||||||
public abstract class Layer : IDrawable
|
|
||||||
{
|
|
||||||
[JsonIgnore] public Scene? Scene { get; set; }
|
|
||||||
[JsonIgnore] public InputSystem? Input { get; set; }
|
|
||||||
[JsonIgnore] public ResourceManager ResourceManager => Scene!.ResourceManager;
|
|
||||||
|
|
||||||
public void BeginDraw(RenderSystem renderer) => OnBeginDraw(renderer);
|
|
||||||
public void Draw(RenderSystem renderer) => OnDraw(renderer);
|
|
||||||
public void EndDraw(RenderSystem renderer) => OnEndDraw(renderer);
|
|
||||||
|
|
||||||
public void Start() => OnStart();
|
|
||||||
public void Update(double dt) => OnUpdate(dt);
|
|
||||||
public void ReceiveInput(InputSystem input) => OnInput(input);
|
|
||||||
|
|
||||||
protected virtual void OnStart() { }
|
|
||||||
protected virtual void OnUpdate(double dt) { }
|
|
||||||
protected virtual void OnInput(InputSystem input) { }
|
|
||||||
protected abstract void OnBeginDraw(RenderSystem renderer);
|
|
||||||
protected abstract void OnDraw(RenderSystem renderer);
|
|
||||||
protected abstract void OnEndDraw(RenderSystem renderer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace Voile.SceneGraph
|
|
||||||
{
|
|
||||||
public class SerializedScene : Resource
|
|
||||||
{
|
|
||||||
public Dictionary<string, Layer> Layers { get; set; }
|
|
||||||
|
|
||||||
public byte[]? Buffer { get; set; }
|
|
||||||
public long BufferSize { get; set; }
|
|
||||||
|
|
||||||
public SerializedScene(string path, byte[] buffer) : base(path)
|
|
||||||
{
|
|
||||||
Buffer = buffer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
|
||||||
[JsonSerializable(typeof(SerializedScene))]
|
|
||||||
[JsonSerializable(typeof(Dictionary<string, Layer>))]
|
|
||||||
[JsonSerializable(typeof(Entity2d))]
|
|
||||||
[JsonSerializable(typeof(Layer))]
|
|
||||||
[JsonSerializable(typeof(EntityLayer))]
|
|
||||||
internal partial class SerializedSceneContext : JsonSerializerContext
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
using Voile.Resources;
|
|
||||||
using Voile.Utils;
|
|
||||||
|
|
||||||
namespace Voile.SceneGraph
|
|
||||||
{
|
|
||||||
public class SerializedSceneSaver : IResourceSaver<SerializedScene>
|
|
||||||
{
|
|
||||||
public bool TrySave(string path, in SerializedScene resource)
|
|
||||||
{
|
|
||||||
if (resource.Buffer is null)
|
|
||||||
{
|
|
||||||
_logger.Error($"Tried to save a resource at \"{path}\" with a null buffer!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
File.WriteAllBytes(path, resource.Buffer);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Logger _logger = new(nameof(SerializedSceneSaver));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
using System.Text.Json;
|
|
||||||
using Voile.Audio;
|
|
||||||
using Voile.Input;
|
|
||||||
using Voile.Rendering;
|
|
||||||
using Voile.Resources;
|
|
||||||
|
|
||||||
|
|
||||||
namespace Voile.SceneGraph
|
|
||||||
{
|
|
||||||
public class Scene : IMainLoop
|
|
||||||
{
|
|
||||||
public RenderSystem Renderer { get => _renderer; set => _renderer = value; }
|
|
||||||
public InputSystem? Input { get => _input; set => _input = value; }
|
|
||||||
public AudioSystem? Audio => _audioBackend;
|
|
||||||
public ResourceManager ResourceManager => _resourceManager;
|
|
||||||
|
|
||||||
public double DeltaTime => _renderer.FrameTime;
|
|
||||||
public bool ShouldRun => Renderer.ShouldRun;
|
|
||||||
|
|
||||||
public Scene(SceneSettings settings)
|
|
||||||
{
|
|
||||||
_renderer = settings.Renderer;
|
|
||||||
_input = settings.InputHandler;
|
|
||||||
_audioBackend = settings.AudioBackend;
|
|
||||||
_resourceManager = settings.ResourceManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Scene FromSerialized(SerializedScene serializedScene, SceneSettings settings)
|
|
||||||
{
|
|
||||||
var scene = new Scene(settings);
|
|
||||||
scene.WithLayers(serializedScene.Layers);
|
|
||||||
|
|
||||||
return scene;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TrySerialize(out SerializedScene serializedScene)
|
|
||||||
{
|
|
||||||
serializedScene = new SerializedScene(string.Empty, new byte[] { })
|
|
||||||
{
|
|
||||||
Layers = _layers
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
serializedScene.Buffer = JsonSerializer.SerializeToUtf8Bytes(serializedScene, new JsonSerializerOptions
|
|
||||||
{
|
|
||||||
TypeInfoResolver = SerializedSceneContext.Default
|
|
||||||
});
|
|
||||||
serializedScene.BufferSize = serializedScene.Buffer.LongLength;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void WithLayers(Dictionary<string, Layer> layers)
|
|
||||||
{
|
|
||||||
_layers = layers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Init() => SetupRenderer();
|
|
||||||
public void Start()
|
|
||||||
{
|
|
||||||
foreach (var layer in _layers.Values)
|
|
||||||
{
|
|
||||||
if (_input is not null)
|
|
||||||
{
|
|
||||||
layer.Input = _input;
|
|
||||||
}
|
|
||||||
|
|
||||||
layer.Start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Update()
|
|
||||||
{
|
|
||||||
foreach (var layer in _layers)
|
|
||||||
{
|
|
||||||
layer.Value.Update(DeltaTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
Audio?.Update(DeltaTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddLayer(string name, Layer layer)
|
|
||||||
{
|
|
||||||
layer.Scene = this;
|
|
||||||
_layers.Add(name, layer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void BeginDraw()
|
|
||||||
{
|
|
||||||
Renderer.BeginFrame();
|
|
||||||
Renderer.ClearBackground(Color.Black);
|
|
||||||
|
|
||||||
foreach (var layer in _layers.Values)
|
|
||||||
{
|
|
||||||
layer.BeginDraw(_renderer);
|
|
||||||
layer.Draw(_renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
Renderer.ResetTransform();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void EndDraw()
|
|
||||||
{
|
|
||||||
foreach (var layer in _layers.Values)
|
|
||||||
{
|
|
||||||
layer.EndDraw(_renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
Renderer.EndFrame();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetupRenderer()
|
|
||||||
{
|
|
||||||
Renderer.Initialize(new RendererSettings { Msaa = Msaa.Msaa4x, UseVSync = true });
|
|
||||||
}
|
|
||||||
|
|
||||||
private Dictionary<string, Layer> _layers = new();
|
|
||||||
private RenderSystem _renderer;
|
|
||||||
private AudioSystem? _audioBackend;
|
|
||||||
private InputSystem? _input;
|
|
||||||
private ResourceManager _resourceManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct SceneSettings
|
|
||||||
{
|
|
||||||
public RenderSystem Renderer { get; set; }
|
|
||||||
public AudioSystem AudioBackend { get; set; }
|
|
||||||
public InputSystem InputHandler { get; set; }
|
|
||||||
public ResourceManager ResourceManager { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,332 +0,0 @@
|
|||||||
using System.Numerics;
|
|
||||||
using ImGuiNET;
|
|
||||||
using Raylib_cs;
|
|
||||||
using Voile.Input;
|
|
||||||
using Voile.Rendering;
|
|
||||||
using KeyboardKey = Voile.Input.KeyboardKey;
|
|
||||||
using MouseButton = Voile.Input.MouseButton;
|
|
||||||
|
|
||||||
namespace Voile.SceneGraph
|
|
||||||
{
|
|
||||||
public class ImGuiRenderLayer : Layer
|
|
||||||
{
|
|
||||||
protected override void OnDraw(RenderSystem renderer)
|
|
||||||
{
|
|
||||||
Layout();
|
|
||||||
_controller.Draw(renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void Layout() { }
|
|
||||||
|
|
||||||
protected override void OnStart()
|
|
||||||
{
|
|
||||||
_controller = new ImGuiController();
|
|
||||||
_controller.Load(Scene.Renderer.WindowSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnUpdate(double dt)
|
|
||||||
{
|
|
||||||
// _controller.Update(dt, Input);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnBeginDraw(RenderSystem renderer)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnEndDraw(RenderSystem renderer)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ImGuiController _controller;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ImGuiController : IDisposable, IDrawable
|
|
||||||
{
|
|
||||||
public ImGuiController()
|
|
||||||
{
|
|
||||||
_context = ImGui.CreateContext();
|
|
||||||
ImGui.SetCurrentContext(_context);
|
|
||||||
}
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
ImGui.DestroyContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Load(Vector2 size)
|
|
||||||
{
|
|
||||||
ImGuiIOPtr io = ImGui.GetIO();
|
|
||||||
io.Fonts.AddFontDefault();
|
|
||||||
|
|
||||||
Resize(size);
|
|
||||||
LoadFontTexture();
|
|
||||||
SetupInput();
|
|
||||||
ImGui.NewFrame();
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe void LoadFontTexture()
|
|
||||||
{
|
|
||||||
ImGuiIOPtr io = ImGui.GetIO();
|
|
||||||
io.Fonts.GetTexDataAsRGBA32(out byte* pixels, out int width, out int height);
|
|
||||||
|
|
||||||
// TODO: use engine API instead of Raylib.
|
|
||||||
Image image = new Image
|
|
||||||
{
|
|
||||||
data = pixels,
|
|
||||||
width = width,
|
|
||||||
height = height,
|
|
||||||
mipmaps = 1,
|
|
||||||
format = PixelFormat.PIXELFORMAT_UNCOMPRESSED_R8G8B8A8,
|
|
||||||
};
|
|
||||||
_fontTexture = Raylib.LoadTextureFromImage(image);
|
|
||||||
|
|
||||||
io.Fonts.SetTexID(new IntPtr(_fontTexture.id));
|
|
||||||
io.Fonts.ClearTexData();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetupInput()
|
|
||||||
{
|
|
||||||
ImGuiIOPtr io = ImGui.GetIO();
|
|
||||||
|
|
||||||
// Setup config flags
|
|
||||||
io.ConfigFlags |= ImGuiConfigFlags.NavEnableKeyboard;
|
|
||||||
|
|
||||||
// Setup back-end capabilities flags
|
|
||||||
io.BackendFlags |= ImGuiBackendFlags.HasMouseCursors;
|
|
||||||
io.BackendFlags |= ImGuiBackendFlags.HasSetMousePos;
|
|
||||||
|
|
||||||
// Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array.
|
|
||||||
io.KeyMap[(int)ImGuiKey.Tab] = (int)KeyboardKey.Tab;
|
|
||||||
io.KeyMap[(int)ImGuiKey.LeftArrow] = (int)KeyboardKey.Left;
|
|
||||||
io.KeyMap[(int)ImGuiKey.RightArrow] = (int)KeyboardKey.Right;
|
|
||||||
io.KeyMap[(int)ImGuiKey.UpArrow] = (int)KeyboardKey.Up;
|
|
||||||
io.KeyMap[(int)ImGuiKey.DownArrow] = (int)KeyboardKey.Down;
|
|
||||||
io.KeyMap[(int)ImGuiKey.PageUp] = (int)KeyboardKey.PageUp;
|
|
||||||
io.KeyMap[(int)ImGuiKey.PageDown] = (int)KeyboardKey.PageDown;
|
|
||||||
io.KeyMap[(int)ImGuiKey.Home] = (int)KeyboardKey.Home;
|
|
||||||
io.KeyMap[(int)ImGuiKey.End] = (int)KeyboardKey.End;
|
|
||||||
io.KeyMap[(int)ImGuiKey.Insert] = (int)KeyboardKey.Insert;
|
|
||||||
io.KeyMap[(int)ImGuiKey.Delete] = (int)KeyboardKey.Delete;
|
|
||||||
io.KeyMap[(int)ImGuiKey.Backspace] = (int)KeyboardKey.Backspace;
|
|
||||||
io.KeyMap[(int)ImGuiKey.Space] = (int)KeyboardKey.Spacebar;
|
|
||||||
io.KeyMap[(int)ImGuiKey.Enter] = (int)KeyboardKey.Enter;
|
|
||||||
io.KeyMap[(int)ImGuiKey.Escape] = (int)KeyboardKey.Escape;
|
|
||||||
io.KeyMap[(int)ImGuiKey.A] = (int)KeyboardKey.A;
|
|
||||||
io.KeyMap[(int)ImGuiKey.C] = (int)KeyboardKey.C;
|
|
||||||
io.KeyMap[(int)ImGuiKey.V] = (int)KeyboardKey.V;
|
|
||||||
io.KeyMap[(int)ImGuiKey.X] = (int)KeyboardKey.X;
|
|
||||||
io.KeyMap[(int)ImGuiKey.Y] = (int)KeyboardKey.Y;
|
|
||||||
io.KeyMap[(int)ImGuiKey.Z] = (int)KeyboardKey.Z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Resize(Vector2 size)
|
|
||||||
{
|
|
||||||
ImGuiIOPtr io = ImGui.GetIO();
|
|
||||||
io.DisplaySize = size / _scaleFactor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Update(double dt, InputSystem input)
|
|
||||||
{
|
|
||||||
ImGuiIOPtr io = ImGui.GetIO();
|
|
||||||
|
|
||||||
io.DisplayFramebufferScale = Vector2.One;
|
|
||||||
io.DeltaTime = (float)dt;
|
|
||||||
|
|
||||||
UpdateKeyboard(input);
|
|
||||||
UpdateMouse(input);
|
|
||||||
|
|
||||||
ImGui.NewFrame();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateKeyboard(InputSystem input)
|
|
||||||
{
|
|
||||||
ImGuiIOPtr io = ImGui.GetIO();
|
|
||||||
|
|
||||||
// Modifiers are not reliable across systems
|
|
||||||
io.KeyCtrl = io.KeysDown[(int)KeyboardKey.LeftControl] || io.KeysDown[(int)KeyboardKey.RightControl];
|
|
||||||
io.KeyShift = io.KeysDown[(int)KeyboardKey.LeftShift] || io.KeysDown[(int)KeyboardKey.RightShift];
|
|
||||||
io.KeyAlt = io.KeysDown[(int)KeyboardKey.LeftAlt] || io.KeysDown[(int)KeyboardKey.RightAlt];
|
|
||||||
io.KeySuper = io.KeysDown[(int)KeyboardKey.LeftSuper] || io.KeysDown[(int)KeyboardKey.RightSuper];
|
|
||||||
|
|
||||||
// Key states
|
|
||||||
for (int i = (int)KeyboardKey.Spacebar; i < (int)KeyboardKey.KBMenu + 1; i++)
|
|
||||||
{
|
|
||||||
io.KeysDown[i] = input.IsKeyboardKeyDown((KeyboardKey)i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Key input
|
|
||||||
int keyPressed = input.GetCharPressed();
|
|
||||||
if (keyPressed != 0)
|
|
||||||
{
|
|
||||||
io.AddInputCharacter((uint)keyPressed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateMouse(InputSystem input)
|
|
||||||
{
|
|
||||||
ImGuiIOPtr io = ImGui.GetIO();
|
|
||||||
|
|
||||||
// Store button states
|
|
||||||
for (int i = 0; i < io.MouseDown.Count; i++)
|
|
||||||
{
|
|
||||||
io.MouseDown[i] = input.IsMouseButtonDown((MouseButton)i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mouse scroll
|
|
||||||
io.MouseWheel += input.GetMouseWheelMovement();
|
|
||||||
|
|
||||||
// Mouse position
|
|
||||||
Vector2 mousePosition = io.MousePos;
|
|
||||||
// TODO:
|
|
||||||
// bool focused = Raylib.IsWindowFocused();
|
|
||||||
|
|
||||||
if (io.WantSetMousePos)
|
|
||||||
{
|
|
||||||
input.SetMousePosition(mousePosition);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
io.MousePos = input.GetMousePosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mouse cursor state
|
|
||||||
if ((io.ConfigFlags & ImGuiConfigFlags.NoMouseCursorChange) == 0 || input.IsCursorHidden())
|
|
||||||
{
|
|
||||||
ImGuiMouseCursor cursor = ImGui.GetMouseCursor();
|
|
||||||
if (cursor == ImGuiMouseCursor.None || io.MouseDrawCursor)
|
|
||||||
{
|
|
||||||
input.HideCursor();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
input.ShowCursor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Render()
|
|
||||||
{
|
|
||||||
ImGui.Render();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RenderCommandLists(ImDrawDataPtr data)
|
|
||||||
{
|
|
||||||
// Scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
|
||||||
int fbWidth = (int)(data.DisplaySize.X * data.FramebufferScale.X);
|
|
||||||
int fbHeight = (int)(data.DisplaySize.Y * data.FramebufferScale.Y);
|
|
||||||
|
|
||||||
// Avoid rendering if display is minimized or if the command list is empty
|
|
||||||
if (fbWidth <= 0 || fbHeight <= 0 || data.CmdListsCount == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Rlgl.rlDrawRenderBatchActive();
|
|
||||||
Rlgl.rlDisableBackfaceCulling();
|
|
||||||
Rlgl.rlEnableScissorTest();
|
|
||||||
|
|
||||||
data.ScaleClipRects(ImGui.GetIO().DisplayFramebufferScale);
|
|
||||||
|
|
||||||
for (int n = 0; n < data.CmdListsCount; n++)
|
|
||||||
{
|
|
||||||
int idxOffset = 0;
|
|
||||||
ImDrawListPtr cmdList = data.CmdListsRange[n];
|
|
||||||
|
|
||||||
// Vertex buffer and index buffer generated by DearImGui
|
|
||||||
ImPtrVector<ImDrawVertPtr> vtxBuffer = cmdList.VtxBuffer;
|
|
||||||
ImVector<ushort> idxBuffer = cmdList.IdxBuffer;
|
|
||||||
|
|
||||||
for (int cmdi = 0; cmdi < cmdList.CmdBuffer.Size; cmdi++)
|
|
||||||
{
|
|
||||||
ImDrawCmdPtr pcmd = cmdList.CmdBuffer[cmdi];
|
|
||||||
|
|
||||||
// Scissor rect
|
|
||||||
Vector2 pos = data.DisplayPos;
|
|
||||||
int rectX = (int)((pcmd.ClipRect.X - pos.X) * data.FramebufferScale.X);
|
|
||||||
int rectY = (int)((pcmd.ClipRect.Y - pos.Y) * data.FramebufferScale.Y);
|
|
||||||
int rectW = (int)((pcmd.ClipRect.Z - rectX) * data.FramebufferScale.Y);
|
|
||||||
int rectH = (int)((pcmd.ClipRect.W - rectY) * data.FramebufferScale.Y);
|
|
||||||
Rlgl.rlScissor(rectX, Raylib.GetScreenHeight() - (rectY + rectH), rectW, rectH);
|
|
||||||
|
|
||||||
if (pcmd.UserCallback != IntPtr.Zero)
|
|
||||||
{
|
|
||||||
// pcmd.UserCallback(cmdList, pcmd);
|
|
||||||
idxOffset += (int)pcmd.ElemCount;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DrawTriangles(pcmd.ElemCount, idxOffset, (int)pcmd.VtxOffset, idxBuffer, vtxBuffer, pcmd.TextureId);
|
|
||||||
idxOffset += (int)pcmd.ElemCount;
|
|
||||||
Rlgl.rlDrawRenderBatchActive();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rlgl.rlSetTexture(0);
|
|
||||||
Rlgl.rlDisableScissorTest();
|
|
||||||
Rlgl.rlEnableBackfaceCulling();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Color GetColor(uint hexValue)
|
|
||||||
{
|
|
||||||
Color color = new Color();
|
|
||||||
|
|
||||||
color.R = (byte)(hexValue & 0xFF) / 255f;
|
|
||||||
color.G = (byte)((hexValue >> 8) & 0xFF) / 255f;
|
|
||||||
color.B = (byte)((hexValue >> 16) & 0xFF) / 255f;
|
|
||||||
color.A = (byte)((hexValue >> 24) & 0xFF) / 255f;
|
|
||||||
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawTriangleVertex(ImDrawVertPtr idxVert)
|
|
||||||
{
|
|
||||||
Color c = GetColor(idxVert.col);
|
|
||||||
Rlgl.rlColor4ub((byte)Math.Round(c.R * 255f), (byte)Math.Round(c.G * 255f), (byte)Math.Round(c.B * 255f), (byte)Math.Round(c.A * 255f));
|
|
||||||
Rlgl.rlTexCoord2f(idxVert.uv.X, idxVert.uv.Y);
|
|
||||||
Rlgl.rlVertex2f(idxVert.pos.X, idxVert.pos.Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw the imgui triangle data
|
|
||||||
private void DrawTriangles(uint count, int idxOffset, int vtxOffset, ImVector<ushort> idxBuffer, ImPtrVector<ImDrawVertPtr> idxVert, IntPtr textureId)
|
|
||||||
{
|
|
||||||
ushort index = 0;
|
|
||||||
ImDrawVertPtr vertex;
|
|
||||||
|
|
||||||
if (Rlgl.rlCheckRenderBatchLimit((int)count * 3))
|
|
||||||
{
|
|
||||||
Rlgl.rlDrawRenderBatchActive();
|
|
||||||
}
|
|
||||||
|
|
||||||
Rlgl.rlBegin(DrawMode.TRIANGLES);
|
|
||||||
Rlgl.rlSetTexture((uint)textureId);
|
|
||||||
|
|
||||||
for (int i = 0; i <= (count - 3); i += 3)
|
|
||||||
{
|
|
||||||
index = idxBuffer[idxOffset + i];
|
|
||||||
vertex = idxVert[vtxOffset + index];
|
|
||||||
DrawTriangleVertex(vertex);
|
|
||||||
|
|
||||||
index = idxBuffer[idxOffset + i + 1];
|
|
||||||
vertex = idxVert[vtxOffset + index];
|
|
||||||
DrawTriangleVertex(vertex);
|
|
||||||
|
|
||||||
index = idxBuffer[idxOffset + i + 2];
|
|
||||||
vertex = idxVert[vtxOffset + index];
|
|
||||||
DrawTriangleVertex(vertex);
|
|
||||||
}
|
|
||||||
Rlgl.rlEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Draw(RenderSystem renderer)
|
|
||||||
{
|
|
||||||
ImGui.Render();
|
|
||||||
RenderCommandLists(ImGui.GetDrawData());
|
|
||||||
}
|
|
||||||
|
|
||||||
private IntPtr _context;
|
|
||||||
private Texture2D _fontTexture;
|
|
||||||
private Vector2 _scaleFactor = Vector2.One;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user