Files
doom-dm/Engine/Renderer/Renderer.cs
2024-12-04 22:35:04 +03:00

107 lines
3.3 KiB
C#

using System.Runtime.InteropServices;
using Engine.Renderer.Pixel;
using OpenTK.Graphics.OpenGL;
using Serilog;
using Serilog.Events;
namespace Engine.Renderer;
public class Renderer
{
internal Texture.Texture<Rgb8> TextureInternal => _framebuffer.TextureInternal;
private readonly Framebuffer.Framebuffer _framebuffer;
private readonly Queue<Action<Renderer>> _renderActions = new();
public Renderer(int width, int height)
{
InitializeOpenGl();
_framebuffer = new Framebuffer.Framebuffer(width, height);
}
private void InitializeOpenGl()
{
GL.Enable(EnableCap.DebugOutput);
GL.DebugMessageCallback(DebugCallback, IntPtr.Zero);
GL.Enable(EnableCap.DepthTest);
GL.Enable(EnableCap.FramebufferSrgb);
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
GL.Enable(EnableCap.Blend);
}
private static void DebugCallback(DebugSource source, DebugType type, int id, DebugSeverity severity, int length,
IntPtr message, IntPtr userParam)
{
var logger = Log.ForContext<Engine>();
var messageText = Marshal.PtrToStringAnsi(message, length) ?? "Unknown OpenGL Error";
var typePrefix = type switch
{
DebugType.DebugTypeError => "Error",
DebugType.DebugTypeDeprecatedBehavior => "Deprecated",
DebugType.DebugTypeUndefinedBehavior => "Undefined",
DebugType.DebugTypePortability => "Portability",
DebugType.DebugTypePerformance => "Performance",
DebugType.DebugTypeMarker => "Marker",
DebugType.DebugTypePushGroup => "PushGroup",
DebugType.DebugTypePopGroup => "PopGroup",
DebugType.DebugTypeOther => "Info",
_ => "Unknown"
};
var sourcePrefix = source switch
{
DebugSource.DebugSourceApi => "API",
DebugSource.DebugSourceWindowSystem => "Window",
DebugSource.DebugSourceShaderCompiler => "Shader",
DebugSource.DebugSourceThirdParty => "ThirdParty",
DebugSource.DebugSourceApplication => "Application",
DebugSource.DebugSourceOther => "Other",
_ => "Unknown"
};
logger.Write(
GetLogLevel(severity),
"[OpenGL {TypePrefix}] [{Source}] {Message} (ID: 0x{Id:X8})",
typePrefix,
sourcePrefix,
messageText,
id
);
}
private static LogEventLevel GetLogLevel(DebugSeverity severity)
{
return severity switch
{
DebugSeverity.DebugSeverityNotification => LogEventLevel.Information,
DebugSeverity.DebugSeverityHigh => LogEventLevel.Error,
DebugSeverity.DebugSeverityMedium => LogEventLevel.Warning,
DebugSeverity.DebugSeverityLow => LogEventLevel.Debug,
_ => LogEventLevel.Debug
};
}
internal void Commit(Action<Renderer> renderAction)
{
_renderActions.Enqueue(renderAction);
}
internal void Render()
{
_framebuffer.Bind();
while (_renderActions.TryDequeue(out var renderAction))
renderAction(this);
_framebuffer.Unbind();
}
internal void Resize(int width, int height)
{
_framebuffer.Resize(width, height);
}
}