using System.Drawing; using System.Numerics; using Dashboard.Drawing; using Dashboard.Pal; using OpenTK.Graphics.OpenGL; namespace Dashboard.OpenGL.Drawing { public class DirectRendering : IDirectRendering { public DeviceContext Context { get; private set; } = null!; public string DriverName { get; } = "Dashboard OpenGL"; public string DriverVendor { get; } = "Dashboard"; public Version DriverVersion { get; } = new Version(0, 1); IContextBase IContextExtensionBase.Context => Context; private int _vao = -1; public void Dispose() { GC.SuppressFinalize(this); } public void Require(DeviceContext context) => Context = context; public void Require(IContextBase context) => Require((DeviceContext)context); public void Begin() { if (_vao == -1) { GL.CreateVertexArray(out _vao); } } public void End() { } public IShader CreatePipeline(T createInfo) where T : IShaderCreateInfo { int program = createInfo switch { GlslShaderCreateInfo glsl => glsl.CreateProgram(), GlslComputeShaderCreateInfo compute => compute.CreateProgram(), SpirvShaderCreateInfo spirv => spirv.CreateProgram(), _ => throw new Exception($"Unsupported shader pipeline type {createInfo.GetType()}."), }; return new GLShader((GLDeviceContext)Context, program); } public IBuffer CreateBuffer(BufferAccessPattern pattern, long size) { return GLBuffer.Create((GLDeviceContext)Context, pattern, size); } public void Draw(DrawCall drawCall) { Vector2 size = Context.FramebufferSize; drawCall.SetAll(size, _vao, false); if (drawCall.ElementBuffer is null) { GL.DrawArrays(drawCall.Primitive.OpenGL, drawCall.First, drawCall.Count); } else if (drawCall.BaseVertex == 0) { GL.DrawElements(drawCall.Primitive.OpenGL, drawCall.Count, drawCall.IndexType.OpenGL, (nint)drawCall.Offset); } else { GL.DrawElementsBaseVertex(drawCall.Primitive.OpenGL, drawCall.Count, drawCall.IndexType.OpenGL, (nint)drawCall.Offset, drawCall.BaseVertex); } } } }