Implement new immediate mode.
This commit is contained in:
parent
6e8888df48
commit
2932b3b85e
15
Dashboard.Common/Drawing/IImmediateMode.cs
Normal file
15
Dashboard.Common/Drawing/IImmediateMode.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System.Drawing;
|
||||
using System.Numerics;
|
||||
using Dashboard.Pal;
|
||||
|
||||
namespace Dashboard.Drawing
|
||||
{
|
||||
public interface IImmediateMode : IDeviceContextExtension
|
||||
{
|
||||
void ClearColor(Color color);
|
||||
|
||||
void Line(Vector2 a, Vector2 b, float width, float depth, Vector4 color);
|
||||
void Rectangle(Box2d rectangle, float depth, Vector4 color);
|
||||
void Image(Box2d rectangle, Box2d uv, float depth, ITexture texture);
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
using System.Drawing;
|
||||
using Dashboard.Pal;
|
||||
|
||||
namespace Dashboard.Pal
|
||||
namespace Dashboard.Drawing
|
||||
{
|
||||
public interface ITextureExtension : IDeviceContextExtension
|
||||
{
|
||||
@ -1,5 +1,6 @@
|
||||
using Dashboard.Collections;
|
||||
using Dashboard.Windowing;
|
||||
using BindingFlags = System.Reflection.BindingFlags;
|
||||
|
||||
namespace Dashboard.Pal
|
||||
{
|
||||
@ -94,7 +95,7 @@ namespace Dashboard.Pal
|
||||
return _preloadedExtensions.Add<T>(() => new T());
|
||||
}
|
||||
|
||||
public T ExtensionRequire<T>() where T : IAppContextExtension, new()
|
||||
public T ExtensionRequire<T>() where T : IAppContextExtension
|
||||
{
|
||||
T? extension = default;
|
||||
|
||||
@ -112,7 +113,8 @@ namespace Dashboard.Pal
|
||||
}
|
||||
else
|
||||
{
|
||||
extension = new T();
|
||||
extension = (T?)typeof(T).GetConstructor(BindingFlags.Public, [])?.Invoke([]) ??
|
||||
throw new Exception("Constructor not found.");
|
||||
}
|
||||
|
||||
_extensions.Add(extension);
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Dashboard.Collections;
|
||||
using BindingFlags = System.Reflection.BindingFlags;
|
||||
|
||||
namespace Dashboard.Pal
|
||||
{
|
||||
@ -41,7 +42,7 @@ namespace Dashboard.Pal
|
||||
return _preloadedExtensions.Add<T>(() => new T());
|
||||
}
|
||||
|
||||
public T ExtensionRequire<T>() where T : IDeviceContextExtension, new()
|
||||
public T ExtensionRequire<T>() where T : IDeviceContextExtension
|
||||
{
|
||||
T? extension = default;
|
||||
|
||||
@ -59,7 +60,9 @@ namespace Dashboard.Pal
|
||||
}
|
||||
else
|
||||
{
|
||||
extension = new T();
|
||||
extension =(T)(
|
||||
typeof(T).GetConstructor(BindingFlags.Public, []) ?.Invoke([])
|
||||
?? throw new Exception("Could not find a suitable constructor for the given extension."));
|
||||
}
|
||||
|
||||
_extensions.Add(extension);
|
||||
|
||||
@ -63,7 +63,7 @@ namespace Dashboard.Pal
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The extension to require.</typeparam>
|
||||
/// <returns>The extension instance.</returns>
|
||||
T ExtensionRequire<T>() where T : TExtension, new();
|
||||
T ExtensionRequire<T>() where T : TExtension;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using System.Drawing;
|
||||
using Dashboard.Events;
|
||||
using Dashboard.Pal;
|
||||
|
||||
namespace Dashboard.Windowing
|
||||
{
|
||||
@ -59,7 +60,7 @@ namespace Dashboard.Windowing
|
||||
/// <summary>
|
||||
/// The device context for this window.
|
||||
/// </summary>
|
||||
IDeviceContext DeviceContext { get; }
|
||||
DeviceContext DeviceContext { get; }
|
||||
|
||||
/// <summary>
|
||||
/// True if the window is double buffered.
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BlurgText" Version="0.1.0-nightly-19" />
|
||||
<PackageReference Include="OpenTK.Graphics" Version="[5.0.0-pre.*,5.1)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
26
Dashboard.Drawing/DrawBuffer.cs
Normal file
26
Dashboard.Drawing/DrawBuffer.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using System.Numerics;
|
||||
|
||||
namespace Dashboard.Drawing
|
||||
{
|
||||
public enum DrawPrimitive
|
||||
{
|
||||
Point,
|
||||
Line,
|
||||
LineStrip,
|
||||
Triangle,
|
||||
TriangleFan,
|
||||
TriangleStrip
|
||||
}
|
||||
|
||||
public record struct DrawVertex(Vector3 Position, Vector3 TextureCoordinate, Vector4 Color);
|
||||
|
||||
public record DrawInfo(DrawPrimitive Primitive, int Count)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class DrawBuffer
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@ -4,10 +4,19 @@
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="OpenTK.Graphics" Version="[5.0.0-pre.*,5.1)" />
|
||||
<ProjectReference Include="..\Dashboard.Common\Dashboard.Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Drawing\immediate.frag" />
|
||||
<EmbeddedResource Include="Drawing\immediate.frag" />
|
||||
<None Remove="Drawing\immediate.vert" />
|
||||
<EmbeddedResource Include="Drawing\immediate.vert" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
229
Dashboard.OpenGL/Drawing/ImmediateMode.cs
Normal file
229
Dashboard.OpenGL/Drawing/ImmediateMode.cs
Normal file
@ -0,0 +1,229 @@
|
||||
using System.Drawing;
|
||||
using System.Numerics;
|
||||
using System.Runtime.InteropServices;
|
||||
using Dashboard.Drawing;
|
||||
using Dashboard.Drawing.OpenGL.Pal;
|
||||
using Dashboard.Pal;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
|
||||
namespace Dashboard.OpenGL.Drawing
|
||||
{
|
||||
public class ImmediateMode : IImmediateMode
|
||||
{
|
||||
public string DriverName => "Dashboard OpenGL Immediate Mode";
|
||||
public string DriverVendor => "Dashboard";
|
||||
public Version DriverVersion { get; } = new Version(1, 0);
|
||||
|
||||
public DeviceContext Context { get; private set; } = null!;
|
||||
|
||||
private int _program;
|
||||
private uint _program_apos;
|
||||
private uint _program_atexcoord;
|
||||
private uint _program_acolor;
|
||||
private int _program_transforms;
|
||||
private int _program_image;
|
||||
private int _vao;
|
||||
private int _white;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public void Require(DeviceContext context)
|
||||
{
|
||||
Context = context;
|
||||
|
||||
_program = GL.CreateProgram();
|
||||
|
||||
int vs = GL.CreateShader(ShaderType.VertexShader);
|
||||
|
||||
using (StreamReader reader = new StreamReader(GetType().Assembly
|
||||
.GetManifestResourceStream("Dashboard.OpenGL.Drawing.immediate.vert")!))
|
||||
{
|
||||
GL.ShaderSource(vs, reader.ReadToEnd());
|
||||
}
|
||||
GL.CompileShader(vs);
|
||||
GL.AttachShader(_program, vs);
|
||||
|
||||
int fs = GL.CreateShader(ShaderType.FragmentShader);
|
||||
|
||||
using (StreamReader reader = new StreamReader(GetType().Assembly
|
||||
.GetManifestResourceStream("Dashboard.OpenGL.Drawing.immediate.frag")!))
|
||||
{
|
||||
GL.ShaderSource(fs, reader.ReadToEnd());
|
||||
}
|
||||
|
||||
GL.CompileShader(fs);
|
||||
GL.AttachShader(_program, fs);
|
||||
|
||||
GL.LinkProgram(_program);
|
||||
GL.DeleteShader(vs); GL.DeleteShader(fs);
|
||||
|
||||
_program_apos = (uint)GL.GetAttribLocation(_program, "aPos");
|
||||
_program_atexcoord = (uint)GL.GetAttribLocation(_program, "aTexCoords");
|
||||
_program_acolor = (uint)GL.GetAttribLocation(_program, "aColor");
|
||||
|
||||
_program_transforms = GL.GetUniformLocation(_program, "transforms");
|
||||
_program_image = GL.GetUniformLocation(_program, "image");
|
||||
|
||||
GL.GenTexture(out _white);
|
||||
GL.BindTexture(TextureTarget.Texture2d, _white);
|
||||
GL.TexImage2D(TextureTarget.Texture2d, 0, InternalFormat.Rgb, 1, 1, 0, OpenTK.Graphics.OpenGL.PixelFormat.Rgb, PixelType.Byte, IntPtr.Zero);
|
||||
GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureSwizzleA, (int)All.One);
|
||||
GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureSwizzleR, (int)All.One);
|
||||
GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureSwizzleG, (int)All.One);
|
||||
GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureSwizzleB, (int)All.One);
|
||||
GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
|
||||
GL.TexParameteri(TextureTarget.Texture2d, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
|
||||
|
||||
GL.GenVertexArray(out _vao);
|
||||
}
|
||||
|
||||
public void ClearColor(Color color)
|
||||
{
|
||||
GL.ClearColor(color.R / 255f, color.G / 255f, color.B / 255f, color.A / 255f);
|
||||
GL.Clear(ClearBufferMask.ColorBufferBit);
|
||||
}
|
||||
|
||||
public void Line(Vector2 a, Vector2 b, float width, float depth, Vector4 color)
|
||||
{
|
||||
Vector2 normal = Vector2.Normalize(b - a);
|
||||
Vector2 tangent = new Vector2(-normal.Y, normal.X) * width;
|
||||
Span<ImmediateVertex> vertices =
|
||||
[
|
||||
new ImmediateVertex(new Vector3(a-tangent, depth), Vector2.Zero, color),
|
||||
new ImmediateVertex(new Vector3(b-tangent, depth), Vector2.Zero, color),
|
||||
new ImmediateVertex(new Vector3(b+tangent, depth), Vector2.Zero, color),
|
||||
new ImmediateVertex(new Vector3(a-tangent, depth), Vector2.Zero, color),
|
||||
new ImmediateVertex(new Vector3(b+tangent, depth), Vector2.Zero, color),
|
||||
new ImmediateVertex(new Vector3(a+tangent, depth), Vector2.Zero, color),
|
||||
];
|
||||
|
||||
int buffer = GL.GenBuffer();
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, buffer);
|
||||
GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * ImmediateVertex.Size, ref vertices[0], BufferUsage.StreamDraw);
|
||||
|
||||
GL.BindVertexArray(_vao);
|
||||
GL.VertexAttribPointer(_program_apos, 3, VertexAttribPointerType.Float, false, ImmediateVertex.Size, ImmediateVertex.PosOffset);
|
||||
GL.EnableVertexAttribArray(_program_apos);
|
||||
GL.VertexAttribPointer(_program_atexcoord, 2, VertexAttribPointerType.Float, false, ImmediateVertex.Size, ImmediateVertex.TexCoordsOffset);
|
||||
GL.EnableVertexAttribArray(_program_atexcoord);
|
||||
GL.VertexAttribPointer(_program_acolor, 4, VertexAttribPointerType.Float, false, ImmediateVertex.Size, ImmediateVertex.ColorOffset);
|
||||
GL.EnableVertexAttribArray(_program_acolor);
|
||||
|
||||
Size size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
|
||||
Matrix4x4 view = Matrix4x4.CreateOrthographicOffCenter(0, size.Width, 0, size.Height, 1, -1);
|
||||
|
||||
GL.UseProgram(_program);
|
||||
|
||||
GL.ActiveTexture(TextureUnit.Texture0);
|
||||
GL.BindTexture(TextureTarget.Texture2d, _white);
|
||||
|
||||
GL.UniformMatrix4f(_program_transforms, 1, true, ref view);
|
||||
GL.Uniform1i(_program_image, 0);
|
||||
|
||||
GL.DrawArrays(PrimitiveType.Triangles, 0, 6);
|
||||
|
||||
GL.DeleteBuffer(buffer);
|
||||
}
|
||||
|
||||
public void Rectangle(Box2d rectangle, float depth, Vector4 color)
|
||||
{
|
||||
Span<ImmediateVertex> vertices =
|
||||
[
|
||||
new ImmediateVertex(new Vector3(rectangle.Min.X, rectangle.Min.Y, depth), Vector2.Zero, color),
|
||||
new ImmediateVertex(new Vector3(rectangle.Max.X, rectangle.Min.Y, depth), Vector2.Zero, color),
|
||||
new ImmediateVertex(new Vector3(rectangle.Max.X, rectangle.Max.Y, depth), Vector2.Zero, color),
|
||||
new ImmediateVertex(new Vector3(rectangle.Min.X, rectangle.Min.Y, depth), Vector2.Zero, color),
|
||||
new ImmediateVertex(new Vector3(rectangle.Max.X, rectangle.Max.Y, depth), Vector2.Zero, color),
|
||||
new ImmediateVertex(new Vector3(rectangle.Min.X, rectangle.Max.Y, depth), Vector2.Zero, color),
|
||||
];
|
||||
|
||||
int buffer = GL.GenBuffer();
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, buffer);
|
||||
GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * ImmediateVertex.Size, ref vertices[0], BufferUsage.StreamDraw);
|
||||
|
||||
GL.BindVertexArray(_vao);
|
||||
GL.VertexAttribPointer(_program_apos, 3, VertexAttribPointerType.Float, false, ImmediateVertex.Size, ImmediateVertex.PosOffset);
|
||||
GL.EnableVertexAttribArray(_program_apos);
|
||||
GL.VertexAttribPointer(_program_atexcoord, 2, VertexAttribPointerType.Float, false, ImmediateVertex.Size, ImmediateVertex.TexCoordsOffset);
|
||||
GL.EnableVertexAttribArray(_program_atexcoord);
|
||||
GL.VertexAttribPointer(_program_acolor, 4, VertexAttribPointerType.Float, false, ImmediateVertex.Size, ImmediateVertex.ColorOffset);
|
||||
GL.EnableVertexAttribArray(_program_acolor);
|
||||
|
||||
Size size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
|
||||
Matrix4x4 view = Matrix4x4.CreateOrthographicOffCenter(0, size.Width, 0, size.Height, 1, -1);
|
||||
|
||||
GL.UseProgram(_program);
|
||||
|
||||
GL.ActiveTexture(TextureUnit.Texture0);
|
||||
GL.BindTexture(TextureTarget.Texture2d, _white);
|
||||
|
||||
GL.UniformMatrix4f(_program_transforms, 1, true, ref view);
|
||||
GL.Uniform1i(_program_image, 0);
|
||||
|
||||
GL.DrawArrays(PrimitiveType.Triangles, 0, 6);
|
||||
|
||||
GL.DeleteBuffer(buffer);
|
||||
}
|
||||
|
||||
public void Image(Box2d rectangle, Box2d uv, float depth, ITexture texture)
|
||||
{
|
||||
Span<ImmediateVertex> vertices =
|
||||
[
|
||||
new ImmediateVertex(new Vector3(rectangle.Min.X, rectangle.Min.Y, depth), new Vector2(uv.Min.X, uv.Min.Y), Vector4.One),
|
||||
new ImmediateVertex(new Vector3(rectangle.Max.X, rectangle.Min.Y, depth), new Vector2(uv.Max.X, uv.Min.Y), Vector4.One),
|
||||
new ImmediateVertex(new Vector3(rectangle.Max.X, rectangle.Max.Y, depth), new Vector2(uv.Max.X, uv.Max.Y), Vector4.One),
|
||||
new ImmediateVertex(new Vector3(rectangle.Min.X, rectangle.Min.Y, depth), new Vector2(uv.Min.X, uv.Min.Y), Vector4.One),
|
||||
new ImmediateVertex(new Vector3(rectangle.Max.X, rectangle.Max.Y, depth), new Vector2(uv.Max.X, uv.Max.Y), Vector4.One),
|
||||
new ImmediateVertex(new Vector3(rectangle.Min.X, rectangle.Max.Y, depth), new Vector2(uv.Min.X, uv.Max.Y), Vector4.One),
|
||||
];
|
||||
|
||||
int buffer = GL.GenBuffer();
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, buffer);
|
||||
GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * ImmediateVertex.Size, ref vertices[0], BufferUsage.StreamDraw);
|
||||
|
||||
GL.BindVertexArray(_vao);
|
||||
GL.VertexAttribPointer(_program_apos, 3, VertexAttribPointerType.Float, false, ImmediateVertex.Size, ImmediateVertex.PosOffset);
|
||||
GL.EnableVertexAttribArray(_program_apos);
|
||||
GL.VertexAttribPointer(_program_atexcoord, 2, VertexAttribPointerType.Float, false, ImmediateVertex.Size, ImmediateVertex.TexCoordsOffset);
|
||||
GL.EnableVertexAttribArray(_program_atexcoord);
|
||||
GL.VertexAttribPointer(_program_acolor, 4, VertexAttribPointerType.Float, false, ImmediateVertex.Size, ImmediateVertex.ColorOffset);
|
||||
GL.EnableVertexAttribArray(_program_acolor);
|
||||
Size size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
|
||||
Matrix4x4 view = Matrix4x4.CreateOrthographicOffCenter(0, size.Width, 0, size.Height, 1, -1);
|
||||
|
||||
GL.UseProgram(_program);
|
||||
|
||||
GL.ActiveTexture(TextureUnit.Texture0);
|
||||
GL.BindTexture(TextureTarget.Texture2d, ((GLTexture)texture).Handle);
|
||||
|
||||
GL.UniformMatrix4f(_program_transforms, 1, true, ref view);
|
||||
GL.Uniform1i(_program_image, 0);
|
||||
|
||||
GL.DrawArrays(PrimitiveType.Triangles, 0, 6);
|
||||
|
||||
GL.DeleteBuffer(buffer);
|
||||
}
|
||||
|
||||
IContextBase IContextExtensionBase.Context => Context;
|
||||
|
||||
void IContextExtensionBase.Require(IContextBase context)
|
||||
{
|
||||
Require((DeviceContext)context);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, Pack = sizeof(float) * 4, Size = Size)]
|
||||
private struct ImmediateVertex(Vector3 position, Vector2 texCoords, Vector4 color)
|
||||
{
|
||||
[FieldOffset(PosOffset)] public Vector3 Position = position;
|
||||
[FieldOffset(TexCoordsOffset)] public Vector2 TexCoords = texCoords;
|
||||
[FieldOffset(ColorOffset)] public Vector4 Color = color;
|
||||
|
||||
public const int Size = 16 * sizeof(float);
|
||||
public const int PosOffset = 0 * sizeof(float);
|
||||
public const int TexCoordsOffset = 4 * sizeof(float);
|
||||
public const int ColorOffset = 8 * sizeof(float);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Dashboard.OpenGL/Drawing/immediate.frag
Normal file
12
Dashboard.OpenGL/Drawing/immediate.frag
Normal file
@ -0,0 +1,12 @@
|
||||
#version 130
|
||||
|
||||
uniform sampler2D image;
|
||||
|
||||
in vec2 vTexCoords;
|
||||
in vec4 vColor;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
fragColor = vColor * texture(image, vTexCoords);
|
||||
}
|
||||
18
Dashboard.OpenGL/Drawing/immediate.vert
Normal file
18
Dashboard.OpenGL/Drawing/immediate.vert
Normal file
@ -0,0 +1,18 @@
|
||||
#version 130
|
||||
|
||||
uniform mat4 transforms;
|
||||
|
||||
in vec3 aPos;
|
||||
in vec2 aTexCoords;
|
||||
in vec4 aColor;
|
||||
|
||||
out vec2 vTexCoords;
|
||||
out vec4 vColor;
|
||||
|
||||
void main() {
|
||||
vec4 position = vec4(aPos, 1.0) * transforms;
|
||||
gl_Position = position;
|
||||
|
||||
vTexCoords = aTexCoords;
|
||||
vColor = aColor;
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Immutable;
|
||||
using Dashboard.OpenGL;
|
||||
using Dashboard.OpenGL.Drawing;
|
||||
using Dashboard.Pal;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
@ -62,6 +63,7 @@ namespace Dashboard.Drawing.OpenGL.Pal
|
||||
Extensions = extensions.ToImmutableHashSet();
|
||||
|
||||
ExtensionPreload<GLTextureExtension>();
|
||||
ExtensionPreload<ImmediateMode>();
|
||||
}
|
||||
|
||||
public bool IsGLExtensionAvailable(string name)
|
||||
@ -1,3 +1,4 @@
|
||||
using Dashboard.Drawing.OpenGL.Pal;
|
||||
using Dashboard.Windowing;
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Platform;
|
||||
@ -12,7 +13,6 @@ namespace Dashboard.OpenTK.PAL2
|
||||
public override string DriverVendor => "Dashboard";
|
||||
public override Version DriverVersion => new Version(0, 1);
|
||||
public GraphicsApiHints GraphicsApiHints { get; set; } = new OpenGLGraphicsApiHints();
|
||||
public bool OpenGLBindingsInitialized { get; private set; } = false;
|
||||
|
||||
private readonly List<PhysicalWindow> _windows = new List<PhysicalWindow>();
|
||||
|
||||
@ -21,14 +21,6 @@ namespace Dashboard.OpenTK.PAL2
|
||||
PhysicalWindow window = new PhysicalWindow(GraphicsApiHints);
|
||||
_windows.Add(window);
|
||||
|
||||
if (!OpenGLBindingsInitialized)
|
||||
{
|
||||
OpenGLBindingsInitialized = true;
|
||||
GLLoader.LoadBindings(
|
||||
new Pal2BindingsContext(TK.OpenGL,
|
||||
((OpenGLDeviceContext)window.DeviceContext).ContextHandle));
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Drawing;
|
||||
using Dashboard.OpenGL;
|
||||
using Dashboard.Pal;
|
||||
using Dashboard.Windowing;
|
||||
using OpenTK.Mathematics;
|
||||
using OpenTK.Platform;
|
||||
@ -8,7 +9,7 @@ using TK = OpenTK.Platform.Toolkit;
|
||||
|
||||
namespace Dashboard.OpenTK.PAL2
|
||||
{
|
||||
public class OpenGLDeviceContext : IGLContext, IGLDisposable
|
||||
public class Pal2GLContext : IGLContext, IDisposable
|
||||
{
|
||||
public OpenGLContextHandle ContextHandle { get; }
|
||||
public WindowHandle WindowHandle { get; }
|
||||
@ -27,12 +28,12 @@ namespace Dashboard.OpenTK.PAL2
|
||||
|
||||
public event Action? Disposed;
|
||||
|
||||
public OpenGLDeviceContext(WindowHandle window, OpenGLContextHandle context, ISwapGroup? group = null)
|
||||
public Pal2GLContext(WindowHandle window, OpenGLContextHandle context)
|
||||
{
|
||||
WindowHandle = window;
|
||||
ContextHandle = context;
|
||||
SwapGroup = group ?? new DummySwapGroup(context);
|
||||
ContextGroup = GetContextGroup(context);
|
||||
SwapGroup = new DummySwapGroup(context);
|
||||
ContextGroup = GetContextGroup(ContextHandle);
|
||||
}
|
||||
|
||||
public void MakeCurrent()
|
||||
@ -45,18 +46,13 @@ namespace Dashboard.OpenTK.PAL2
|
||||
return TK.OpenGL.GetProcedureAddress(ContextHandle, procName);
|
||||
}
|
||||
|
||||
private bool _isDisposed = false;
|
||||
|
||||
public void Dispose() => Dispose(true);
|
||||
|
||||
public void Dispose(bool safeExit)
|
||||
protected void Dispose(bool isDisposing)
|
||||
{
|
||||
if (_isDisposed) return;
|
||||
_isDisposed = true;
|
||||
|
||||
if (SwapGroup is IGLDisposable glDisposable)
|
||||
{
|
||||
glDisposable.Dispose(safeExit);
|
||||
glDisposable.Dispose(isDisposing);
|
||||
}
|
||||
else if (SwapGroup is IDisposable disposable)
|
||||
{
|
||||
@ -1,7 +1,9 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Drawing;
|
||||
using Dashboard.Drawing;
|
||||
using Dashboard.Drawing.OpenGL.Pal;
|
||||
using Dashboard.Events;
|
||||
using Dashboard.Pal;
|
||||
using Dashboard.Windowing;
|
||||
using OpenTK.Mathematics;
|
||||
using OpenTK.Platform;
|
||||
@ -14,7 +16,7 @@ namespace Dashboard.OpenTK.PAL2
|
||||
{
|
||||
public DrawQueue DrawQueue { get; } = new DrawQueue();
|
||||
public WindowHandle WindowHandle { get; }
|
||||
public IDeviceContext DeviceContext { get; }
|
||||
public DeviceContext DeviceContext { get; }
|
||||
public bool DoubleBuffered => true; // Always true for OpenTK windows.
|
||||
|
||||
public IWindowManager? WindowManager { get; set; }
|
||||
@ -52,17 +54,17 @@ namespace Dashboard.OpenTK.PAL2
|
||||
public event EventHandler<MouseButtonEventArgs>? MouseButtonUp;
|
||||
public event EventHandler<MouseScrollEventArgs>? MouseScroll;
|
||||
|
||||
public PhysicalWindow(WindowHandle window, IDeviceContext dc)
|
||||
public PhysicalWindow(WindowHandle window)
|
||||
{
|
||||
WindowHandle = window;
|
||||
DeviceContext = dc;
|
||||
DeviceContext = CreateDeviceContext(window, new OpenGLGraphicsApiHints());
|
||||
AddWindow(this);
|
||||
}
|
||||
|
||||
public PhysicalWindow(WindowHandle window, OpenGLContextHandle context, ISwapGroup? swapGroup = null)
|
||||
public PhysicalWindow(WindowHandle window, OpenGLContextHandle context)
|
||||
{
|
||||
WindowHandle = window;
|
||||
DeviceContext = new OpenGLDeviceContext(window, context, swapGroup);
|
||||
DeviceContext = new GLDeviceContext(new Pal2GLContext(window, context));
|
||||
AddWindow(this);
|
||||
}
|
||||
|
||||
@ -73,14 +75,13 @@ namespace Dashboard.OpenTK.PAL2
|
||||
AddWindow(this);
|
||||
}
|
||||
|
||||
private static IDeviceContext CreateDeviceContext(WindowHandle window, GraphicsApiHints hints)
|
||||
private static DeviceContext CreateDeviceContext(WindowHandle window, GraphicsApiHints hints)
|
||||
{
|
||||
switch (hints.Api)
|
||||
{
|
||||
case GraphicsApi.OpenGL:
|
||||
case GraphicsApi.OpenGLES:
|
||||
OpenGLContextHandle context = TK.OpenGL.CreateFromWindow(window);
|
||||
return new OpenGLDeviceContext(window, context);
|
||||
return new GLDeviceContext(new Pal2GLContext(window, TK.OpenGL.CreateFromWindow(window)));
|
||||
default:
|
||||
throw new Exception($"Unknown graphics API {hints.Api}.");
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ using Dashboard.Windowing;
|
||||
|
||||
namespace Dashboard.Controls
|
||||
{
|
||||
public class Control : IEventListener, IDrawQueuePaintable, IDisposable
|
||||
public class Control : IEventListener, IDisposable
|
||||
{
|
||||
public string? Id { get; set; }
|
||||
public ClassSet Classes { get; }
|
||||
|
||||
@ -6,7 +6,6 @@ namespace Dashboard.Controls
|
||||
public class Form : Control
|
||||
{
|
||||
public IWindow Window { get; }
|
||||
public override DrawQueue DrawQueue { get; }
|
||||
|
||||
public override Box2d ClientArea
|
||||
{
|
||||
@ -17,7 +16,6 @@ namespace Dashboard.Controls
|
||||
public Form(IWindow window)
|
||||
{
|
||||
Window = window;
|
||||
DrawQueue = (window as IDrawQueuePaintable)?.DrawQueue ?? new DrawQueue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,7 +27,6 @@ namespace Dashboard.Controls
|
||||
ClientArea = new Box2d(ClientArea.Min, ClientArea.Min + (Vector2)sz);
|
||||
}
|
||||
|
||||
|
||||
public override void OnPaint()
|
||||
{
|
||||
base.OnPaint();
|
||||
|
||||
@ -10,9 +10,11 @@ using OpenTK.Mathematics;
|
||||
using Box2d = Dashboard.Box2d;
|
||||
using TK = OpenTK.Platform.Toolkit;
|
||||
using Dashboard;
|
||||
using Dashboard.Drawing.OpenGL.Pal;
|
||||
using Dashboard.Windowing;
|
||||
using OpenTK.Windowing.GraphicsLibraryFramework;
|
||||
using AppContext = Dashboard.Pal.AppContext;
|
||||
using Vector4 = System.Numerics.Vector4;
|
||||
|
||||
TK.Init(new ToolkitOptions()
|
||||
{
|
||||
@ -51,13 +53,13 @@ PhysicalWindow window;
|
||||
SolidBrush fg = new SolidBrush(Color.FromArgb(0, 0, 0, 0));
|
||||
SolidBrush bg = new SolidBrush(Color.Black);
|
||||
CancellationTokenSource source = new CancellationTokenSource();
|
||||
GLEngine engine;
|
||||
ContextExecutor executor;
|
||||
DimUI dimUI;
|
||||
// GLEngine engine;
|
||||
// ContextExecutor executor;
|
||||
// DimUI dimUI;
|
||||
Vector2 mousePos = Vector2.Zero;
|
||||
Random r = new Random();
|
||||
List<Vector3> points = new List<Vector3>();
|
||||
IFont font;
|
||||
// IFont font;
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
app.Initialize();
|
||||
@ -70,20 +72,20 @@ TK.Window.SetClientSize(window.WindowHandle, new Vector2i(320, 240));
|
||||
TK.Window.SetBorderStyle(window.WindowHandle, WindowBorderStyle.ResizableBorder);
|
||||
// TK.Window.SetTransparencyMode(wnd, WindowTransparencyMode.TransparentFramebuffer, 0.1f);
|
||||
|
||||
OpenGLDeviceContext context = (OpenGLDeviceContext)window.DeviceContext;
|
||||
GLDeviceContext context = (GLDeviceContext)window.DeviceContext;
|
||||
|
||||
context.MakeCurrent();
|
||||
context.SwapGroup.SwapInterval = 1;
|
||||
context.GLContext.MakeCurrent();
|
||||
context.GLContext.SwapGroup.SwapInterval = 1;
|
||||
|
||||
engine = new GLEngine();
|
||||
engine.Initialize();
|
||||
|
||||
executor = engine.GetExecutor(context);
|
||||
|
||||
dimUI = new DimUI(new DimUIConfig()
|
||||
{
|
||||
Font = new NamedFont("Noto Sans", 9f),
|
||||
});
|
||||
// engine = new GLEngine();
|
||||
// engine.Initialize();
|
||||
//
|
||||
// executor = engine.GetExecutor(context);
|
||||
//
|
||||
// dimUI = new DimUI(new DimUIConfig()
|
||||
// {
|
||||
// Font = new NamedFont("Noto Sans", 9f),
|
||||
// });
|
||||
|
||||
EventQueue.EventRaised += (handle, type, eventArgs) =>
|
||||
{
|
||||
@ -102,66 +104,66 @@ EventQueue.EventRaised += (handle, type, eventArgs) =>
|
||||
};
|
||||
|
||||
TK.Window.SetMode(window.WindowHandle, WindowMode.Normal);
|
||||
font = Typesetter.LoadFont("Nimbus Mono", 12f);
|
||||
// font = Typesetter.LoadFont("Nimbus Mono", 12f);
|
||||
|
||||
window.Painting += (sender, ea) => {
|
||||
TK.Window.GetSize(context.WindowHandle, out Vector2i size);
|
||||
executor.BeginFrame();
|
||||
|
||||
dimUI.Begin(new Box2d(0, 0, size.X, size.Y), window.DrawQueue);
|
||||
dimUI.Text("Hello World!");
|
||||
dimUI.Button("Cancel"); dimUI.SameLine();
|
||||
dimUI.Button("OK");
|
||||
|
||||
dimUI.Input("type me!", builder);
|
||||
|
||||
dimUI.BeginMenu();
|
||||
|
||||
if (dimUI.MenuItem("File"))
|
||||
{
|
||||
dimUI.BeginMenu();
|
||||
dimUI.MenuItem("New Window");
|
||||
dimUI.MenuItem("Preferences");
|
||||
dimUI.MenuItem("Exit");
|
||||
dimUI.EndMenu();
|
||||
}
|
||||
|
||||
if (dimUI.MenuItem("Edit"))
|
||||
{
|
||||
dimUI.BeginMenu();
|
||||
dimUI.MenuItem("Cut");
|
||||
dimUI.MenuItem("Copy");
|
||||
dimUI.MenuItem("Paste");
|
||||
|
||||
if (dimUI.MenuItem("Send Char"))
|
||||
{
|
||||
dimUI.BeginMenu();
|
||||
dimUI.EndMenu();
|
||||
}
|
||||
|
||||
dimUI.EndMenu();
|
||||
}
|
||||
|
||||
if (dimUI.MenuItem("View"))
|
||||
{
|
||||
dimUI.BeginMenu();
|
||||
dimUI.MenuItem("Clear");
|
||||
|
||||
if (dimUI.MenuItem("Set Size"))
|
||||
{
|
||||
dimUI.BeginMenu();
|
||||
dimUI.MenuItem("24 x 40");
|
||||
dimUI.MenuItem("25 x 40");
|
||||
dimUI.MenuItem("24 x 80");
|
||||
dimUI.MenuItem("25 x 80");
|
||||
dimUI.MenuItem("25 x 120");
|
||||
dimUI.EndMenu();
|
||||
}
|
||||
|
||||
dimUI.EndMenu();
|
||||
}
|
||||
|
||||
dimUI.Finish();
|
||||
TK.Window.GetSize(window.WindowHandle, out Vector2i size);
|
||||
// executor.BeginFrame();
|
||||
//
|
||||
// dimUI.Begin(new Box2d(0, 0, size.X, size.Y), window.DrawQueue);
|
||||
// dimUI.Text("Hello World!");
|
||||
// dimUI.Button("Cancel"); dimUI.SameLine();
|
||||
// dimUI.Button("OK");
|
||||
//
|
||||
// dimUI.Input("type me!", builder);
|
||||
//
|
||||
// dimUI.BeginMenu();
|
||||
//
|
||||
// if (dimUI.MenuItem("File"))
|
||||
// {
|
||||
// dimUI.BeginMenu();
|
||||
// dimUI.MenuItem("New Window");
|
||||
// dimUI.MenuItem("Preferences");
|
||||
// dimUI.MenuItem("Exit");
|
||||
// dimUI.EndMenu();
|
||||
// }
|
||||
//
|
||||
// if (dimUI.MenuItem("Edit"))
|
||||
// {
|
||||
// dimUI.BeginMenu();
|
||||
// dimUI.MenuItem("Cut");
|
||||
// dimUI.MenuItem("Copy");
|
||||
// dimUI.MenuItem("Paste");
|
||||
//
|
||||
// if (dimUI.MenuItem("Send Char"))
|
||||
// {
|
||||
// dimUI.BeginMenu();
|
||||
// dimUI.EndMenu();
|
||||
// }
|
||||
//
|
||||
// dimUI.EndMenu();
|
||||
// }
|
||||
//
|
||||
// if (dimUI.MenuItem("View"))
|
||||
// {
|
||||
// dimUI.BeginMenu();
|
||||
// dimUI.MenuItem("Clear");
|
||||
//
|
||||
// if (dimUI.MenuItem("Set Size"))
|
||||
// {
|
||||
// dimUI.BeginMenu();
|
||||
// dimUI.MenuItem("24 x 40");
|
||||
// dimUI.MenuItem("25 x 40");
|
||||
// dimUI.MenuItem("24 x 80");
|
||||
// dimUI.MenuItem("25 x 80");
|
||||
// dimUI.MenuItem("25 x 120");
|
||||
// dimUI.EndMenu();
|
||||
// }
|
||||
//
|
||||
// dimUI.EndMenu();
|
||||
// }
|
||||
//
|
||||
// dimUI.Finish();
|
||||
|
||||
GL.Viewport(0, 0, size.X, size.Y);
|
||||
GL.ClearColor(0.3f, 0.3f, 0.3f, 1.0f);
|
||||
@ -171,10 +173,14 @@ window.Painting += (sender, ea) => {
|
||||
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
|
||||
GL.ColorMask(true, true, true, true);
|
||||
|
||||
executor.Draw(window.DrawQueue, new RectangleF(0, 0, size.X, size.Y), 1.5f /*(window as IDpiAwareWindow)?.Scale ?? 1*/);
|
||||
executor.EndFrame();
|
||||
// executor.Draw(window.DrawQueue, new RectangleF(0, 0, size.X, size.Y), 1.5f /*(window as IDpiAwareWindow)?.Scale ?? 1*/);
|
||||
// executor.EndFrame();
|
||||
|
||||
context.SwapGroup.Swap();
|
||||
IImmediateMode imm = context.ExtensionRequire<IImmediateMode>();
|
||||
imm.ClearColor(Color.Magenta);
|
||||
imm.Line(new System.Numerics.Vector2(10, 10), new System.Numerics.Vector2(50, 50), 3, 0, new Vector4(0.2f, 0.2f, 1.0f, 1.0f));
|
||||
|
||||
context.GLContext.SwapGroup.Swap();
|
||||
};
|
||||
|
||||
app.Run(true, source.Token);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user