.
This commit is contained in:
@@ -194,6 +194,10 @@ dotnet_naming_rule.constant_should_be_constant_style.severity = suggestion
|
|||||||
dotnet_naming_rule.constant_should_be_constant_style.symbols = constant
|
dotnet_naming_rule.constant_should_be_constant_style.symbols = constant
|
||||||
dotnet_naming_rule.constant_should_be_constant_style.style = constant_style
|
dotnet_naming_rule.constant_should_be_constant_style.style = constant_style
|
||||||
|
|
||||||
|
dotnet_naming_rule.static_readonly_should_be_pascal_case.severity = suggestion
|
||||||
|
dotnet_naming_rule.static_readonly_should_be_pascal_case.symbols = static_readonly
|
||||||
|
dotnet_naming_rule.static_readonly_should_be_pascal_case.style = constant_style
|
||||||
|
|
||||||
dotnet_naming_rule.all_fields_should_be_fields_style.severity = suggestion
|
dotnet_naming_rule.all_fields_should_be_fields_style.severity = suggestion
|
||||||
dotnet_naming_rule.all_fields_should_be_fields_style.symbols = all_fields
|
dotnet_naming_rule.all_fields_should_be_fields_style.symbols = all_fields
|
||||||
dotnet_naming_rule.all_fields_should_be_fields_style.style = fields_style
|
dotnet_naming_rule.all_fields_should_be_fields_style.style = fields_style
|
||||||
@@ -240,6 +244,10 @@ dotnet_naming_symbols.constant.applicable_kinds = field
|
|||||||
dotnet_naming_symbols.constant.applicable_accessibilities = *
|
dotnet_naming_symbols.constant.applicable_accessibilities = *
|
||||||
dotnet_naming_symbols.constant.required_modifiers = const
|
dotnet_naming_symbols.constant.required_modifiers = const
|
||||||
|
|
||||||
|
dotnet_naming_symbols.static_readonly.applicable_kinds = field
|
||||||
|
dotnet_naming_symbols.static_readonly.applicable_accessibilities = *
|
||||||
|
dotnet_naming_symbols.static_readonly.required_modifiers = static, readonly
|
||||||
|
|
||||||
dotnet_naming_symbols.local.applicable_kinds = local
|
dotnet_naming_symbols.local.applicable_kinds = local
|
||||||
dotnet_naming_symbols.local.applicable_accessibilities = *
|
dotnet_naming_symbols.local.applicable_accessibilities = *
|
||||||
dotnet_naming_symbols.local.required_modifiers =
|
dotnet_naming_symbols.local.required_modifiers =
|
||||||
|
|||||||
@@ -22,15 +22,20 @@ public static class DoomDeathmatch
|
|||||||
cameraObject.AddComponent<ControllerComponent>();
|
cameraObject.AddComponent<ControllerComponent>();
|
||||||
|
|
||||||
using var reader = new StreamReader("../DoomDeathmatch/asset/model/test2.obj");
|
using var reader = new StreamReader("../DoomDeathmatch/asset/model/test2.obj");
|
||||||
|
var mesh = ObjMeshLoader.Load(reader);
|
||||||
|
|
||||||
var box2dRenderer = new GameObject();
|
var box2dRenderer = new GameObject();
|
||||||
box2dRenderer.AddComponent(new MeshRenderer { Mesh = ObjMeshLoader.Load(reader) });
|
box2dRenderer.AddComponent(new MeshRenderer { Mesh = mesh });
|
||||||
box2dRenderer.AddComponent<Box2DRenderer>();
|
|
||||||
box2dRenderer.AddComponent<RotateComponent>();
|
box2dRenderer.AddComponent<RotateComponent>();
|
||||||
|
|
||||||
|
var testChild = new GameObject();
|
||||||
|
testChild.Transform.Scale /= 4;
|
||||||
|
testChild.AddComponent(new MeshRenderer { Mesh = mesh });
|
||||||
|
|
||||||
var scene = new Scene();
|
var scene = new Scene();
|
||||||
scene.Add(cameraObject);
|
scene.Add(cameraObject);
|
||||||
scene.Add(box2dRenderer);
|
scene.Add(box2dRenderer);
|
||||||
|
scene.AddChild(box2dRenderer, testChild);
|
||||||
|
|
||||||
return scene;
|
return scene;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
<InternalsVisibleTo Include="PresenterConsole"/>
|
<InternalsVisibleTo Include="PresenterConsole"/>
|
||||||
<InternalsVisibleTo Include="PresenterWpf"/>
|
<InternalsVisibleTo Include="PresenterWpf"/>
|
||||||
<InternalsVisibleTo Include="PresenterNative"/>
|
<InternalsVisibleTo Include="PresenterNative"/>
|
||||||
|
<PackageReference Include="Evergine.Bindings.RenderDoc" Version="2024.10.7.18" />
|
||||||
|
|
||||||
<PackageReference Include="OpenTK" Version="4.8.2"/>
|
<PackageReference Include="OpenTK" Version="4.8.2"/>
|
||||||
<PackageReference Include="Serilog" Version="4.1.0"/>
|
<PackageReference Include="Serilog" Version="4.1.0"/>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using OpenTK.Mathematics;
|
|||||||
using OpenTK.Windowing.Common;
|
using OpenTK.Windowing.Common;
|
||||||
using OpenTK.Windowing.Desktop;
|
using OpenTK.Windowing.Desktop;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
using Debug = Engine.Graphics.Debug;
|
||||||
|
|
||||||
namespace Engine;
|
namespace Engine;
|
||||||
|
|
||||||
@@ -69,8 +70,8 @@ public sealed class Engine
|
|||||||
Profile = ContextProfile.Core
|
Profile = ContextProfile.Core
|
||||||
};
|
};
|
||||||
|
|
||||||
Window = new Window(this, new NativeWindow(settings), parHeadless);
|
Renderer = new Renderer(parWidth, parHeight, settings);
|
||||||
Renderer = new Renderer(parWidth, parHeight);
|
Window = new Window(this, Renderer.NativeWindow, parHeadless);
|
||||||
|
|
||||||
Log.Logger = parLogger;
|
Log.Logger = parLogger;
|
||||||
_logger = Log.ForContext<Engine>();
|
_logger = Log.ForContext<Engine>();
|
||||||
@@ -92,18 +93,22 @@ public sealed class Engine
|
|||||||
{
|
{
|
||||||
while (!Presenter?.IsExiting ?? false)
|
while (!Presenter?.IsExiting ?? false)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
Debug.RenderDocStartFrame();
|
||||||
|
#endif
|
||||||
|
|
||||||
Renderer.StartFrame();
|
Renderer.StartFrame();
|
||||||
|
|
||||||
var view = Matrix4.Identity;
|
|
||||||
var projection = Matrix4.Identity;
|
var projection = Matrix4.Identity;
|
||||||
|
var view = Matrix4.Identity;
|
||||||
lock (_sceneLock)
|
lock (_sceneLock)
|
||||||
{
|
{
|
||||||
var camera = SceneManager.CurrentScene?.MainCamera;
|
var camera = SceneManager.CurrentScene?.MainCamera;
|
||||||
if (camera != null)
|
if (camera != null)
|
||||||
{
|
{
|
||||||
camera.ScreenSize = new Vector2i(Renderer.ViewportWidth, Renderer.ViewportHeight);
|
camera.ScreenSize = new Vector2i(Renderer.ViewportWidth, Renderer.ViewportHeight);
|
||||||
view = camera.View;
|
|
||||||
projection = camera.Projection;
|
projection = camera.Projection;
|
||||||
|
view = camera.View;
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneManager.Render();
|
SceneManager.Render();
|
||||||
@@ -115,10 +120,15 @@ public sealed class Engine
|
|||||||
Renderer.GlobalMeshRenderer.Render(projection, view);
|
Renderer.GlobalMeshRenderer.Render(projection, view);
|
||||||
Renderer.GlobalMeshRenderer.Reset();
|
Renderer.GlobalMeshRenderer.Reset();
|
||||||
|
|
||||||
Renderer.EndFrame();
|
Renderer.EndFrame(projection, view);
|
||||||
|
|
||||||
Presenter!.Present(Renderer.RenderTexture);
|
Presenter!.Present(Renderer.RenderTexture);
|
||||||
Presenter!.Render();
|
Presenter!.Render();
|
||||||
|
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
Debug.RenderDocEndFrame();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,12 +52,12 @@ public class IndexBuffer : OpenGlObject
|
|||||||
GL.NamedBufferSubData(Handle, parOffset, parData.Length * sizeof(uint), parData);
|
GL.NamedBufferSubData(Handle, parOffset, parData.Length * sizeof(uint), parData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Bind()
|
internal override void Bind()
|
||||||
{
|
{
|
||||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, Handle);
|
GL.BindBuffer(BufferTarget.ElementArrayBuffer, Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Unbind()
|
internal override void Unbind()
|
||||||
{
|
{
|
||||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
|
GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class VertexArray : OpenGlObject
|
|||||||
{
|
{
|
||||||
GL.VertexArrayElementBuffer(Handle, parBuffer.Handle);
|
GL.VertexArrayElementBuffer(Handle, parBuffer.Handle);
|
||||||
|
|
||||||
Log.Debug("Vertex array {Handle} bound to index buffer {Buffer}", Handle, parBuffer.Handle);
|
Log.Debug("Index buffer {Buffer} bound to vertex array {Handle}", parBuffer.Handle, Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BindVertexBuffer<T>(VertexBuffer<T> parBuffer, int parBindingIndex = 0, int parDivisor = 0)
|
public void BindVertexBuffer<T>(VertexBuffer<T> parBuffer, int parBindingIndex = 0, int parDivisor = 0)
|
||||||
@@ -48,9 +48,8 @@ public class VertexArray : OpenGlObject
|
|||||||
|
|
||||||
GL.VertexArrayBindingDivisor(Handle, parBindingIndex, parDivisor);
|
GL.VertexArrayBindingDivisor(Handle, parBindingIndex, parDivisor);
|
||||||
|
|
||||||
Log.Debug(
|
Log.Debug("Vertex buffer {Buffer} bound to vertex array {Handle} at {BindingIndex} binding with {Divisor} divisor",
|
||||||
"Vertex array {Handle} bound to vertex buffer {Buffer} at {BindingIndex} binding with {Divisor} divisor",
|
parBuffer.Handle, Handle, parBindingIndex, parDivisor);
|
||||||
Handle, parBuffer.Handle, parBindingIndex, parDivisor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetupAttribute(VertexAttribute parAttribute, int parBaseLocation, int parBaseOffset, int parBindingIndex)
|
private void SetupAttribute(VertexAttribute parAttribute, int parBaseLocation, int parBaseOffset, int parBindingIndex)
|
||||||
@@ -70,12 +69,12 @@ public class VertexArray : OpenGlObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Bind()
|
internal override void Bind()
|
||||||
{
|
{
|
||||||
GL.BindVertexArray(Handle);
|
GL.BindVertexArray(Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Unbind()
|
internal override void Unbind()
|
||||||
{
|
{
|
||||||
GL.BindVertexArray(0);
|
GL.BindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,12 +91,12 @@ public class VertexBuffer<T> : OpenGlObject
|
|||||||
GL.NamedBufferSubData(Handle, parOffset * _stride, parCount * _stride, parData);
|
GL.NamedBufferSubData(Handle, parOffset * _stride, parCount * _stride, parData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Bind()
|
internal override void Bind()
|
||||||
{
|
{
|
||||||
GL.BindBuffer(BufferTarget.ArrayBuffer, Handle);
|
GL.BindBuffer(BufferTarget.ArrayBuffer, Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Unbind()
|
internal override void Unbind()
|
||||||
{
|
{
|
||||||
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
|
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ namespace Engine.Graphics.Camera;
|
|||||||
|
|
||||||
public interface ICamera
|
public interface ICamera
|
||||||
{
|
{
|
||||||
public Matrix4 View { get; }
|
Matrix4 View { get; }
|
||||||
public Matrix4 Projection { get; }
|
Matrix4 Projection { get; }
|
||||||
public Vector2i ScreenSize { get; internal set; }
|
Vector2i ScreenSize { get; internal set; }
|
||||||
}
|
}
|
||||||
@@ -2,17 +2,35 @@
|
|||||||
using OpenTK.Graphics.OpenGL;
|
using OpenTK.Graphics.OpenGL;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
|
using Evergine.Bindings.RenderDoc;
|
||||||
|
|
||||||
namespace Engine.Graphics;
|
namespace Engine.Graphics;
|
||||||
|
|
||||||
internal static class Debug
|
internal static class Debug
|
||||||
{
|
{
|
||||||
|
private static RenderDoc _renderDocApi;
|
||||||
|
|
||||||
public static void Setup()
|
public static void Setup()
|
||||||
{
|
{
|
||||||
GL.Enable(EnableCap.DebugOutput);
|
GL.Enable(EnableCap.DebugOutput);
|
||||||
GL.DebugMessageCallback(DebugCallback, IntPtr.Zero);
|
GL.DebugMessageCallback(DebugCallback, IntPtr.Zero);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void InitializeRenderDoc()
|
||||||
|
{
|
||||||
|
RenderDoc.Load(out _renderDocApi);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RenderDocStartFrame()
|
||||||
|
{
|
||||||
|
// _renderDocApi.API.StartFrameCapture(IntPtr.Zero, IntPtr.Zero);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RenderDocEndFrame()
|
||||||
|
{
|
||||||
|
// _renderDocApi.API.EndFrameCapture(IntPtr.Zero, IntPtr.Zero);
|
||||||
|
}
|
||||||
|
|
||||||
private static void DebugCallback(DebugSource parSource, DebugType parType, int parId, DebugSeverity parSeverity,
|
private static void DebugCallback(DebugSource parSource, DebugType parType, int parId, DebugSeverity parSeverity,
|
||||||
int parLength,
|
int parLength,
|
||||||
IntPtr parMessage, IntPtr parUserParam)
|
IntPtr parMessage, IntPtr parUserParam)
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class Framebuffer : OpenGlObject
|
|||||||
private int _width;
|
private int _width;
|
||||||
private int _height;
|
private int _height;
|
||||||
|
|
||||||
public Framebuffer(int parWidth, int parHeight,
|
internal Framebuffer(int parWidth, int parHeight,
|
||||||
IDictionary<FramebufferAttachment, IFramebufferAttachment> parAttachments)
|
IDictionary<FramebufferAttachment, IFramebufferAttachment> parAttachments)
|
||||||
{
|
{
|
||||||
Width = parWidth;
|
Width = parWidth;
|
||||||
@@ -62,7 +62,7 @@ public class Framebuffer : OpenGlObject
|
|||||||
return new FramebufferBuilder(parWidth, parHeight);
|
return new FramebufferBuilder(parWidth, parHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
public T? GetAttachment<T>(FramebufferAttachment parAttachment) where T : IFramebufferAttachment
|
internal T? GetAttachment<T>(FramebufferAttachment parAttachment) where T : IFramebufferAttachment
|
||||||
{
|
{
|
||||||
if (!_attachments.TryGetValue(parAttachment, out var attachmentValue))
|
if (!_attachments.TryGetValue(parAttachment, out var attachmentValue))
|
||||||
{
|
{
|
||||||
@@ -95,12 +95,12 @@ public class Framebuffer : OpenGlObject
|
|||||||
Log.Debug("Framebuffer {Handle} resized to {Width}x{Height}", Handle, parWidth, parHeight);
|
Log.Debug("Framebuffer {Handle} resized to {Width}x{Height}", Handle, parWidth, parHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Bind()
|
internal override void Bind()
|
||||||
{
|
{
|
||||||
GL.BindFramebuffer(FramebufferTarget.Framebuffer, Handle);
|
GL.BindFramebuffer(FramebufferTarget.Framebuffer, Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Unbind()
|
internal override void Unbind()
|
||||||
{
|
{
|
||||||
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
|
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
namespace Engine.Graphics.Framebuffer;
|
namespace Engine.Graphics.Framebuffer;
|
||||||
|
|
||||||
public interface IFramebufferAttachment
|
internal interface IFramebufferAttachment
|
||||||
{
|
{
|
||||||
internal int Handle { get; }
|
int Handle { get; }
|
||||||
|
|
||||||
public void Resize(int parWidth, int parHeight);
|
void Resize(int parWidth, int parHeight);
|
||||||
|
|
||||||
internal void Attach(Framebuffer parFramebuffer, FramebufferAttachment parAttachment);
|
void Attach(Framebuffer parFramebuffer, FramebufferAttachment parAttachment);
|
||||||
}
|
}
|
||||||
@@ -39,12 +39,12 @@ public class Renderbuffer : OpenGlObject, IFramebufferAttachment
|
|||||||
GL.NamedFramebufferRenderbuffer(parFramebuffer.Handle, parAttachment, RenderbufferTarget.Renderbuffer, Handle);
|
GL.NamedFramebufferRenderbuffer(parFramebuffer.Handle, parAttachment, RenderbufferTarget.Renderbuffer, Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Bind()
|
internal override void Bind()
|
||||||
{
|
{
|
||||||
GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, Handle);
|
GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Unbind()
|
internal override void Unbind()
|
||||||
{
|
{
|
||||||
GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, 0);
|
GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
59
Engine/src/Graphics/GenericRenderer.cs
Normal file
59
Engine/src/Graphics/GenericRenderer.cs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
using Engine.Graphics.Pixel;
|
||||||
|
using Engine.Graphics.Render.Mesh;
|
||||||
|
using Engine.Graphics.Render.Quad;
|
||||||
|
using OpenTK.Graphics.OpenGL;
|
||||||
|
using OpenTK.Mathematics;
|
||||||
|
|
||||||
|
namespace Engine.Graphics;
|
||||||
|
|
||||||
|
public class GenericRenderer : IRenderer
|
||||||
|
{
|
||||||
|
public QuadRenderer QuadRenderer => _quadRenderer ??= new QuadRenderer(1024 * 8);
|
||||||
|
public GlobalMeshRenderer GlobalMeshRenderer => _globalMeshRenderer ??= new GlobalMeshRenderer(1024);
|
||||||
|
|
||||||
|
private QuadRenderer? _quadRenderer;
|
||||||
|
private GlobalMeshRenderer? _globalMeshRenderer;
|
||||||
|
|
||||||
|
internal readonly Framebuffer.Framebuffer _framebuffer;
|
||||||
|
|
||||||
|
private bool _frameStarted;
|
||||||
|
|
||||||
|
public GenericRenderer(int parWidth, int parHeight)
|
||||||
|
{
|
||||||
|
_framebuffer = Framebuffer.Framebuffer.Builder(parWidth, parHeight)
|
||||||
|
.AddColorAttachment<Rgba8>()
|
||||||
|
.AddDepthAttachment()
|
||||||
|
.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartFrame()
|
||||||
|
{
|
||||||
|
_frameStarted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EndFrame(in Matrix4 parProjectionMatrix, in Matrix4 parViewMatrix)
|
||||||
|
{
|
||||||
|
if (!_frameStarted)
|
||||||
|
throw new InvalidOperationException("Frame not started");
|
||||||
|
|
||||||
|
_framebuffer.Bind();
|
||||||
|
|
||||||
|
GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
||||||
|
|
||||||
|
QuadRenderer.Render(parProjectionMatrix, parViewMatrix);
|
||||||
|
QuadRenderer.Reset();
|
||||||
|
|
||||||
|
GlobalMeshRenderer.Render(parProjectionMatrix, parViewMatrix);
|
||||||
|
GlobalMeshRenderer.Reset();
|
||||||
|
|
||||||
|
_framebuffer.Unbind();
|
||||||
|
|
||||||
|
_frameStarted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Resize(int parWidth, int parHeight)
|
||||||
|
{
|
||||||
|
_framebuffer.Resize(parWidth, parHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,11 +6,11 @@ namespace Engine.Graphics;
|
|||||||
|
|
||||||
public interface IPresenter : IUpdate, IRender
|
public interface IPresenter : IUpdate, IRender
|
||||||
{
|
{
|
||||||
public bool IsExiting { get; }
|
bool IsExiting { get; }
|
||||||
public int Width { get; }
|
int Width { get; }
|
||||||
public int Height { get; }
|
int Height { get; }
|
||||||
|
|
||||||
public event Action<ResizeEventArgs> Resize;
|
event Action<ResizeEventArgs> Resize;
|
||||||
|
|
||||||
public void Present(IConstTexture parTexture);
|
void Present(IConstTexture parTexture);
|
||||||
}
|
}
|
||||||
11
Engine/src/Graphics/IRenderer.cs
Normal file
11
Engine/src/Graphics/IRenderer.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using OpenTK.Mathematics;
|
||||||
|
|
||||||
|
namespace Engine.Graphics;
|
||||||
|
|
||||||
|
internal interface IRenderer
|
||||||
|
{
|
||||||
|
public void StartFrame();
|
||||||
|
public void EndFrame(in Matrix4 parProjectionMatrix, in Matrix4 parViewMatrix);
|
||||||
|
|
||||||
|
public void Resize(int parWidth, int parHeight);
|
||||||
|
}
|
||||||
@@ -6,8 +6,8 @@ public abstract class OpenGlObject
|
|||||||
{
|
{
|
||||||
public int Handle { get; protected set; } = -1;
|
public int Handle { get; protected set; } = -1;
|
||||||
|
|
||||||
public abstract void Bind();
|
internal abstract void Bind();
|
||||||
public abstract void Unbind();
|
internal abstract void Unbind();
|
||||||
|
|
||||||
protected abstract void Destroy();
|
protected abstract void Destroy();
|
||||||
|
|
||||||
|
|||||||
27
Engine/src/Graphics/Pipeline/RenderLayer.cs
Normal file
27
Engine/src/Graphics/Pipeline/RenderLayer.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
namespace Engine.Graphics.Pipeline;
|
||||||
|
|
||||||
|
public class RenderLayer
|
||||||
|
{
|
||||||
|
public static readonly RenderLayer DEFAULT = new("default");
|
||||||
|
public static readonly RenderLayer HUD = new("hud");
|
||||||
|
public static readonly RenderLayer OVERLAY = new("overlay");
|
||||||
|
|
||||||
|
public static readonly IReadOnlyList<RenderLayer> ALL = new List<RenderLayer> { DEFAULT, HUD, OVERLAY }.AsReadOnly();
|
||||||
|
|
||||||
|
public string Name { get; }
|
||||||
|
|
||||||
|
private RenderLayer(string parName)
|
||||||
|
{
|
||||||
|
Name = parName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return Name.GetHashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
6
Engine/src/Graphics/Pipeline/RenderPipeline.cs
Normal file
6
Engine/src/Graphics/Pipeline/RenderPipeline.cs
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Engine.Graphics.Pipeline;
|
||||||
|
|
||||||
|
public class RenderPipeline
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,9 +4,9 @@ namespace Engine.Graphics.Pixel;
|
|||||||
|
|
||||||
public interface IPixel
|
public interface IPixel
|
||||||
{
|
{
|
||||||
public PixelFormat Format { get; }
|
PixelFormat Format { get; }
|
||||||
public PixelType Type { get; }
|
PixelType Type { get; }
|
||||||
|
|
||||||
public PixelInternalFormat InternalFormat { get; }
|
PixelInternalFormat InternalFormat { get; }
|
||||||
public SizedInternalFormat SizedInternalFormat { get; }
|
SizedInternalFormat SizedInternalFormat { get; }
|
||||||
}
|
}
|
||||||
21
Engine/src/Graphics/Pixel/Rgba8.cs
Normal file
21
Engine/src/Graphics/Pixel/Rgba8.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using OpenTK.Graphics.OpenGL;
|
||||||
|
|
||||||
|
namespace Engine.Graphics.Pixel;
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct Rgba8 : IPixel
|
||||||
|
{
|
||||||
|
public PixelFormat Format => PixelFormat.Rgba;
|
||||||
|
public PixelType Type => PixelType.UnsignedByte;
|
||||||
|
|
||||||
|
public PixelInternalFormat InternalFormat => PixelInternalFormat.Rgba8;
|
||||||
|
public SizedInternalFormat SizedInternalFormat => SizedInternalFormat.Rgba8;
|
||||||
|
|
||||||
|
public byte R;
|
||||||
|
public byte G;
|
||||||
|
public byte B;
|
||||||
|
public byte A;
|
||||||
|
|
||||||
|
public override string ToString() => $"{R}, {G}, {B}, {A}";
|
||||||
|
}
|
||||||
@@ -10,8 +10,6 @@ public abstract class InstancedRenderer<C, I>
|
|||||||
where C : struct, IVertex
|
where C : struct, IVertex
|
||||||
where I : struct, IVertex
|
where I : struct, IVertex
|
||||||
{
|
{
|
||||||
protected readonly Renderer _renderer;
|
|
||||||
|
|
||||||
private readonly IndexBuffer _indexBuffer;
|
private readonly IndexBuffer _indexBuffer;
|
||||||
private readonly VertexBuffer<C> _commonVertexBuffer;
|
private readonly VertexBuffer<C> _commonVertexBuffer;
|
||||||
private readonly VertexBuffer<I> _instanceVertexBuffer;
|
private readonly VertexBuffer<I> _instanceVertexBuffer;
|
||||||
@@ -24,12 +22,11 @@ public abstract class InstancedRenderer<C, I>
|
|||||||
private readonly PrimitiveType _primitiveType;
|
private readonly PrimitiveType _primitiveType;
|
||||||
private readonly Program _program;
|
private readonly Program _program;
|
||||||
|
|
||||||
protected InstancedRenderer(Renderer parRenderer, PrimitiveType parPrimitiveType, int parInstanceCount,
|
protected InstancedRenderer(PrimitiveType parPrimitiveType, int parInstanceCount,
|
||||||
uint[] parIndexBuffer, C[] parInstanceBuffer,
|
uint[] parIndexBuffer, C[] parInstanceBuffer,
|
||||||
Program parProgram)
|
Program parProgram)
|
||||||
{
|
{
|
||||||
_program = parProgram;
|
_program = parProgram;
|
||||||
_renderer = parRenderer;
|
|
||||||
_instanceCount = parInstanceCount;
|
_instanceCount = parInstanceCount;
|
||||||
_queuedInstanceCount = 0;
|
_queuedInstanceCount = 0;
|
||||||
_instanceVertices = new I[parInstanceCount];
|
_instanceVertices = new I[parInstanceCount];
|
||||||
@@ -53,8 +50,6 @@ public abstract class InstancedRenderer<C, I>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderer.EnsureRenderThread();
|
|
||||||
|
|
||||||
_instanceVertexBuffer.UploadData(_instanceVertices, _queuedInstanceCount);
|
_instanceVertexBuffer.UploadData(_instanceVertices, _queuedInstanceCount);
|
||||||
_vertexArray.Bind();
|
_vertexArray.Bind();
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using OpenTK.Mathematics;
|
|||||||
|
|
||||||
namespace Engine.Graphics.Render.Mesh;
|
namespace Engine.Graphics.Render.Mesh;
|
||||||
|
|
||||||
public class GlobalMeshRenderer(Renderer parRenderer, int parMaxInstanceCount)
|
public class GlobalMeshRenderer(int parMaxInstanceCount)
|
||||||
{
|
{
|
||||||
private readonly Dictionary<Asset.Mesh.Mesh, MeshRenderer> _meshRenderers = new();
|
private readonly Dictionary<Asset.Mesh.Mesh, MeshRenderer> _meshRenderers = new();
|
||||||
private readonly HashSet<Asset.Mesh.Mesh> _frameMeshes = [];
|
private readonly HashSet<Asset.Mesh.Mesh> _frameMeshes = [];
|
||||||
@@ -18,7 +18,7 @@ public class GlobalMeshRenderer(Renderer parRenderer, int parMaxInstanceCount)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var newMeshRenderer = new MeshRenderer(parRenderer, parMesh, parMaxInstanceCount, _program);
|
var newMeshRenderer = new MeshRenderer(parMesh, parMaxInstanceCount, _program);
|
||||||
newMeshRenderer.Commit(parModelMatrix);
|
newMeshRenderer.Commit(parModelMatrix);
|
||||||
|
|
||||||
_meshRenderers.Add(parMesh, newMeshRenderer);
|
_meshRenderers.Add(parMesh, newMeshRenderer);
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ using OpenTK.Mathematics;
|
|||||||
|
|
||||||
namespace Engine.Graphics.Render.Mesh;
|
namespace Engine.Graphics.Render.Mesh;
|
||||||
|
|
||||||
public class MeshRenderer(Renderer parRenderer, Asset.Mesh.Mesh parMesh, int parInstanceCount, Program parProgram)
|
public class MeshRenderer(Asset.Mesh.Mesh parMesh, int parInstanceCount, Program parProgram)
|
||||||
: InstancedRenderer<Asset.Mesh.Mesh.Vertex, MeshInstanceVertex>(
|
: InstancedRenderer<Asset.Mesh.Mesh.Vertex, MeshInstanceVertex>(
|
||||||
parRenderer, PrimitiveType.Triangles,
|
PrimitiveType.Triangles,
|
||||||
parInstanceCount,
|
parInstanceCount,
|
||||||
parMesh.Indices.ToArray(),
|
parMesh.Indices.ToArray(),
|
||||||
parMesh.Vertices.ToArray(),
|
parMesh.Vertices.ToArray(),
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ public class QuadRenderer : InstancedRenderer<QuadCommonVertex, QuadInstanceVert
|
|||||||
private readonly TextureUnitMap _textureUnitMap = new(16);
|
private readonly TextureUnitMap _textureUnitMap = new(16);
|
||||||
private readonly int[] _textureUnitIndices = new int[16];
|
private readonly int[] _textureUnitIndices = new int[16];
|
||||||
|
|
||||||
public QuadRenderer(Renderer parRenderer, int parInstanceCount)
|
public QuadRenderer(int parInstanceCount)
|
||||||
: base(parRenderer, PrimitiveType.Triangles, parInstanceCount, [0, 1, 2, 2, 3, 0], [
|
: base(PrimitiveType.Triangles, parInstanceCount, [0, 1, 2, 2, 3, 0], [
|
||||||
new QuadCommonVertex { _position = new Vector3(-0.5f, -0.5f, 0), _uv = new Vector2(0, 1) },
|
new QuadCommonVertex { _position = new Vector3(-0.5f, -0.5f, 0), _uv = new Vector2(0, 1) },
|
||||||
new QuadCommonVertex { _position = new Vector3(0.5f, -0.5f, 0), _uv = new Vector2(1, 1) },
|
new QuadCommonVertex { _position = new Vector3(0.5f, -0.5f, 0), _uv = new Vector2(1, 1) },
|
||||||
new QuadCommonVertex { _position = new Vector3(0.5f, 0.5f, 0), _uv = new Vector2(1, 0) },
|
new QuadCommonVertex { _position = new Vector3(0.5f, 0.5f, 0), _uv = new Vector2(1, 0) },
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
using Engine.Graphics.Pixel;
|
using Engine.Graphics.Pipeline;
|
||||||
|
using Engine.Graphics.Pixel;
|
||||||
using Engine.Graphics.Render.Mesh;
|
using Engine.Graphics.Render.Mesh;
|
||||||
using Engine.Graphics.Render.Quad;
|
using Engine.Graphics.Render.Quad;
|
||||||
using OpenTK.Graphics.OpenGL;
|
using OpenTK.Graphics.OpenGL;
|
||||||
|
using OpenTK.Mathematics;
|
||||||
|
using OpenTK.Windowing.Desktop;
|
||||||
|
|
||||||
namespace Engine.Graphics;
|
namespace Engine.Graphics;
|
||||||
|
|
||||||
@@ -15,15 +18,25 @@ public class Renderer
|
|||||||
public int ViewportWidth => _framebuffer.Width;
|
public int ViewportWidth => _framebuffer.Width;
|
||||||
public int ViewportHeight => _framebuffer.Height;
|
public int ViewportHeight => _framebuffer.Height;
|
||||||
|
|
||||||
|
private readonly Dictionary<RenderLayer, GenericRenderer> _renderers = new();
|
||||||
|
|
||||||
|
internal NativeWindow NativeWindow { get; }
|
||||||
|
|
||||||
private readonly Framebuffer.Framebuffer _framebuffer;
|
private readonly Framebuffer.Framebuffer _framebuffer;
|
||||||
private readonly Thread _renderThread;
|
private readonly Thread _renderThread;
|
||||||
|
|
||||||
private readonly Queue<Action> _scheduleActions = new();
|
private readonly Queue<Action> _scheduleActions = new();
|
||||||
|
|
||||||
public Renderer(int parWidth, int parHeight)
|
public Renderer(int parWidth, int parHeight, NativeWindowSettings parSettings)
|
||||||
{
|
{
|
||||||
Thread.CurrentThread.Name = "RendererThread";
|
Thread.CurrentThread.Name = "RendererThread";
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
Debug.InitializeRenderDoc();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NativeWindow = new NativeWindow(parSettings);
|
||||||
|
|
||||||
InitializeOpenGl(parWidth, parHeight);
|
InitializeOpenGl(parWidth, parHeight);
|
||||||
|
|
||||||
_renderThread = Thread.CurrentThread;
|
_renderThread = Thread.CurrentThread;
|
||||||
@@ -33,8 +46,8 @@ public class Renderer
|
|||||||
.AddDepthAttachment()
|
.AddDepthAttachment()
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
QuadRenderer = new QuadRenderer(this, 1024 * 8);
|
QuadRenderer = new QuadRenderer(1024 * 8);
|
||||||
GlobalMeshRenderer = new GlobalMeshRenderer(this, 1024);
|
GlobalMeshRenderer = new GlobalMeshRenderer(1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeOpenGl(int parWidth, int parHeight)
|
private void InitializeOpenGl(int parWidth, int parHeight)
|
||||||
@@ -77,13 +90,31 @@ public class Renderer
|
|||||||
_framebuffer.Bind();
|
_framebuffer.Bind();
|
||||||
|
|
||||||
GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
GL.Clear(ClearBufferMask.ColorBufferBit);
|
||||||
|
|
||||||
|
// foreach (var renderer in _renderers.Values)
|
||||||
|
// {
|
||||||
|
// renderer.StartFrame();
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void EndFrame()
|
internal void EndFrame(in Matrix4 parViewMatrix, in Matrix4 parProjectionMatrix)
|
||||||
{
|
{
|
||||||
EnsureRenderThread();
|
EnsureRenderThread();
|
||||||
|
|
||||||
|
// foreach (var renderer in _renderers.Values)
|
||||||
|
// {
|
||||||
|
// renderer.EndFrame(in parViewMatrix, in parProjectionMatrix);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// foreach (var renderer in _renderers.Values)
|
||||||
|
// {
|
||||||
|
// QuadRenderer.Commit(Matrix4.CreateScale(2f), Vector4.One, renderer._framebuffer.TextureInternal);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// QuadRenderer.Render(in parProjectionMatrix, in parViewMatrix);
|
||||||
|
// QuadRenderer.Reset();
|
||||||
|
|
||||||
_framebuffer.Unbind();
|
_framebuffer.Unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,12 +62,12 @@ public class Program : OpenGlObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Bind()
|
internal override void Bind()
|
||||||
{
|
{
|
||||||
GL.UseProgram(Handle);
|
GL.UseProgram(Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Unbind()
|
internal override void Unbind()
|
||||||
{
|
{
|
||||||
GL.UseProgram(0);
|
GL.UseProgram(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,12 +127,12 @@ public abstract class Texture : OpenGlObject, ITexture
|
|||||||
GL.BindTextureUnit(parUnit, Handle);
|
GL.BindTextureUnit(parUnit, Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Bind()
|
internal override void Bind()
|
||||||
{
|
{
|
||||||
GL.BindTexture(TextureTarget.Texture2D, Handle);
|
GL.BindTexture(TextureTarget.Texture2D, Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Unbind()
|
internal override void Unbind()
|
||||||
{
|
{
|
||||||
GL.BindTexture(TextureTarget.Texture2D, 0);
|
GL.BindTexture(TextureTarget.Texture2D, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user