107 lines
3.3 KiB
C#
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);
|
|
}
|
|
} |