18 Commits

Author SHA1 Message Date
dadd9f137a Add utility for custom commands into command lists. 2024-07-26 23:48:48 +03:00
23fc485b2a Create Dashboard.BlurgText 2024-07-26 22:20:44 +03:00
c6c76aa8be Update dependencies. 2024-07-18 21:54:44 +03:00
6670667ff6 Fix some broken dependencies. 2024-07-18 20:34:39 +03:00
d06264e424 Rename some classes to fit the new names. 2024-07-18 20:28:02 +03:00
a1f4e6a4dc Rename from QUIK to Dashboard
Due to unforseen naming conflicts, the project has been rebranded under the ReFuel
umbrealla and will now be referred to as Dashboard from now on. Other changes will
occur to suit the library more for the engine whilst keeping the freestanding
nature of the library.

Rename folder.

Rename to Dashboard.OpenTK

Rename to Dashboard.Media.Defaults.

Do the last renames and path fixes.
2024-07-17 23:26:58 +03:00
470475092a Rename namespace to Dashboard. 2024-07-17 23:18:20 +03:00
1ee492ccd4 Push WIP changes before rename. 2024-07-17 23:12:07 +03:00
3b52649ad2 Change over to the new nuget package and change namespaces. 2024-06-24 22:28:41 +03:00
f8a4c73367 Fix load order in FallbackFontDatabase. 2024-06-21 11:59:04 +03:00
88e060a92b Update Stbi to new rebranded package. 2024-06-21 09:52:29 +03:00
1ccab1c85a Converted project to ^nullable enable. 2024-06-09 22:54:33 +03:00
55e9d775cd Some changes to the UI elements. 2024-06-09 22:06:13 +03:00
8fd00257d3 Fix GL21 driver bug. 2024-06-09 19:55:13 +03:00
82d2027cf3 Add measure string function to Typesetter. 2024-06-09 19:20:35 +03:00
9b16e015f6 Fix depth test issue in demo. 2024-06-06 22:33:55 +03:00
ff4a158cdb Update stbi. 2024-06-01 14:33:20 +03:00
29829fd299 Made font rendering easier. 2024-05-27 21:49:25 +03:00
86 changed files with 1438 additions and 810 deletions

View File

@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BlurgText" Version="0.1.0-nightly-4" />
</ItemGroup>
</Project>

View File

@@ -8,12 +8,12 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Quik.FreeType" Version="1.1.0" /> <PackageReference Include="ReFuel.FreeType" Version="0.1.0-rc.5" />
<PackageReference Include="Quik.StbImage" Version="1.1.0" /> <PackageReference Include="ReFuel.StbImage" Version="2.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Quik\Quik.csproj" /> <ProjectReference Include="..\Dashboard\Dashboard.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -1,4 +1,4 @@
namespace Quik.Media.Defaults namespace Dashboard.Media.Defaults
{ {
internal static class EnvironmentVariables internal static class EnvironmentVariables
{ {

View File

@@ -1,7 +1,7 @@
using System; using System;
using Quik.FreeType; using ReFuel.FreeType;
namespace Quik.Media.Defaults namespace Dashboard.Media.Defaults
{ {
public static class FTProvider public static class FTProvider
{ {

View File

@@ -4,12 +4,12 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using System.Text.Json; using System.Text.Json;
using Quik.FreeType; using ReFuel.FreeType;
using Quik.Media.Font; using Dashboard.Media.Font;
using Quik.PAL; using Dashboard.PAL;
using Quik.Media.Defaults.Linux; using Dashboard.Media.Defaults.Linux;
namespace Quik.Media.Defaults.Fallback namespace Dashboard.Media.Defaults.Fallback
{ {
public class FallbackFontDatabase : IFontDataBase public class FallbackFontDatabase : IFontDataBase
{ {
@@ -41,6 +41,8 @@ namespace Quik.Media.Defaults.Fallback
VerifyDatabase(database); VerifyDatabase(database);
FlushDatabase(database); FlushDatabase(database);
database.ForEach(x => AddFont(x.Face, new FileInfo(x.FilePath)));
(FontFace, FileInfo) serif = FontDataBaseProvider.ResolveSystemFont(EnvironmentVariables.SerifFont, LinuxFonts.DefaultSerifFamilies, this); (FontFace, FileInfo) serif = FontDataBaseProvider.ResolveSystemFont(EnvironmentVariables.SerifFont, LinuxFonts.DefaultSerifFamilies, this);
SystemFonts[SystemFontFamily.Serif] = serif.Item1; SystemFonts[SystemFontFamily.Serif] = serif.Item1;
(FontFace, FileInfo) sans = FontDataBaseProvider.ResolveSystemFont(EnvironmentVariables.SansFont, LinuxFonts.DefaultSansFamilies, this); (FontFace, FileInfo) sans = FontDataBaseProvider.ResolveSystemFont(EnvironmentVariables.SansFont, LinuxFonts.DefaultSansFamilies, this);
@@ -51,14 +53,6 @@ namespace Quik.Media.Defaults.Fallback
SystemFonts[SystemFontFamily.Cursive] = cursive.Item1; SystemFonts[SystemFontFamily.Cursive] = cursive.Item1;
(FontFace, FileInfo) fantasy = FontDataBaseProvider.ResolveSystemFont(EnvironmentVariables.FantasyFont, LinuxFonts.DefaultFantasyFamilies, this); (FontFace, FileInfo) fantasy = FontDataBaseProvider.ResolveSystemFont(EnvironmentVariables.FantasyFont, LinuxFonts.DefaultFantasyFamilies, this);
SystemFonts[SystemFontFamily.Fantasy] = fantasy.Item1; SystemFonts[SystemFontFamily.Fantasy] = fantasy.Item1;
AddFont(serif.Item1, serif.Item2);
AddFont(sans.Item1, sans.Item2);
AddFont(mono.Item1, mono.Item2);
AddFont(cursive.Item1, cursive.Item2);
AddFont(fantasy.Item1, fantasy.Item2);
database.ForEach(x => AddFont(x.Face, new FileInfo(x.FilePath)));
} }
public FileInfo FontFileInfo(FontFace face) public FileInfo FontFileInfo(FontFace face)
@@ -241,7 +235,7 @@ namespace Quik.Media.Defaults.Fallback
{ {
FileInfo info = new FileInfo(DbPath); FileInfo info = new FileInfo(DbPath);
Directory.CreateDirectory(Path.GetDirectoryName(DbPath)); Directory.CreateDirectory(Path.GetDirectoryName(DbPath));
using Stream str = info.OpenWrite(); using Stream str = info.Open(FileMode.Create);
JsonSerializer.Serialize(str, db); JsonSerializer.Serialize(str, db);
} }

View File

@@ -3,13 +3,13 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Quik.FreeType; using ReFuel.FreeType;
using Quik.Media.Defaults.Fallback; using Dashboard.Media.Defaults.Fallback;
using Quik.Media.Defaults.Linux; using Dashboard.Media.Defaults.Linux;
using Quik.Media.Font; using Dashboard.Media.Font;
using Quik.PAL; using Dashboard.PAL;
namespace Quik.Media.Defaults namespace Dashboard.Media.Defaults
{ {
public static class FontDataBaseProvider public static class FontDataBaseProvider
{ {

View File

@@ -0,0 +1,24 @@
using System.Diagnostics.CodeAnalysis;
using System.IO;
using Dashboard.PAL;
namespace Dashboard.Media.Defaults
{
public class FreeTypeFontFactory : IFontFactory
{
public bool TryOpen(Stream stream, [NotNullWhen(true)] out QFont font)
{
try
{
font = new QFontFreeType(stream);
return true;
}
catch
{
font = null;
return false;
}
}
}
}

View File

@@ -2,9 +2,9 @@ using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using Quik; using Dashboard;
namespace Quik.Media.Defaults namespace Dashboard.Media.Defaults
{ {
public static unsafe class FontConfig public static unsafe class FontConfig
{ {

View File

@@ -5,11 +5,11 @@ using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using Quik.FreeType; using ReFuel.FreeType;
using Quik.Media.Font; using Dashboard.Media.Font;
using Quik.PAL; using Dashboard.PAL;
namespace Quik.Media.Defaults.Linux namespace Dashboard.Media.Defaults.Linux
{ {
/// <summary> /// <summary>
/// Font database for Linux libfontconfig systems. /// Font database for Linux libfontconfig systems.

View File

@@ -1,4 +1,4 @@
namespace Quik.Media.Defaults.Linux namespace Dashboard.Media.Defaults.Linux
{ {
internal static class LinuxFonts internal static class LinuxFonts
{ {

View File

@@ -1,11 +1,11 @@
using System; using System;
using System.Buffers; using System.Buffers;
using System.IO; using System.IO;
using Quik.FreeType; using ReFuel.FreeType;
using Quik.Media.Color; using Dashboard.Media.Color;
using Quik.Media.Font; using Dashboard.Media.Font;
namespace Quik.Media.Defaults namespace Dashboard.Media.Defaults
{ {
public class QFontFreeType : QFont public class QFontFreeType : QFont
{ {

View File

@@ -1,11 +1,9 @@
using System; using System;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using Dashboard.Media.Color;
using Quik.Media; using ReFuel.Stb;
using Quik.Media.Color;
using Quik.Stb;
namespace Quik.Media.Defaults namespace Dashboard.Media.Defaults
{ {
public unsafe class QImageStbi : QImage public unsafe class QImageStbi : QImage
{ {

View File

@@ -4,12 +4,12 @@ using System.Collections;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using Quik.Media.Font; using Dashboard.Media.Font;
// WebRequest is obsolete but runs on .NET framework. // WebRequest is obsolete but runs on .NET framework.
#pragma warning disable SYSLIB0014 #pragma warning disable SYSLIB0014
namespace Quik.Media.Defaults namespace Dashboard.Media.Defaults
{ {
public class StbMediaLoader : MediaLoader<string>, MediaLoader<Uri>, MediaLoader<FileInfo>, MediaLoader<FontFace> public class StbMediaLoader : MediaLoader<string>, MediaLoader<Uri>, MediaLoader<FileInfo>, MediaLoader<FontFace>
{ {

View File

@@ -1,18 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<Nullable>disable</Nullable> <Nullable>enable</Nullable>
<LangVersion>7.3</LangVersion> </PropertyGroup>
</PropertyGroup>
<ItemGroup>
<ItemGroup> <PackageReference Include="OpenTK" Version="4.8.0" />
<PackageReference Include="OpenTK" Version="4.8.0" /> </ItemGroup>
</ItemGroup>
<ItemGroup>
<ItemGroup> <ProjectReference Include="..\Dashboard\Dashboard.csproj" />
<ProjectReference Include="..\Quik\Quik.csproj" /> <EmbeddedResource Include="glsl\**"/>
<EmbeddedResource Include="glsl\**"/> </ItemGroup>
</ItemGroup>
</Project>
</Project>

View File

@@ -2,22 +2,22 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using OpenTK.Windowing.Desktop; using OpenTK.Windowing.Desktop;
using OpenTK.Windowing.GraphicsLibraryFramework; using OpenTK.Windowing.GraphicsLibraryFramework;
using Quik.CommandMachine; using Dashboard.CommandMachine;
using Quik.Media; using Dashboard.Media;
using Quik.OpenGL; using Dashboard.OpenGL;
using Quik.PAL; using Dashboard.PAL;
namespace Quik.OpenTK namespace Dashboard.OpenTK
{ {
public class OpenTKPlatform : IQuikPlatform public class OpenTKPlatform : IDashboardPlatform
{ {
private readonly List<OpenTKPort> _ports = new List<OpenTKPort>(); private readonly List<OpenTKPort> _ports = new List<OpenTKPort>();
// These shall remain a sad nop for now. // These shall remain a sad nop for now.
public string Title { get; set; } public string? Title { get; set; }
public QImage Icon { get; set; } public QImage? Icon { get; set; } = null;
public event EventHandler EventRaised; public event EventHandler? EventRaised;
public NativeWindowSettings DefaultSettings { get; set; } = NativeWindowSettings.Default; public NativeWindowSettings DefaultSettings { get; set; } = NativeWindowSettings.Default;
@@ -25,7 +25,7 @@ namespace Quik.OpenTK
private bool IsGLInitialized = false; private bool IsGLInitialized = false;
public IQuikPortHandle CreatePort() public IDashHandle CreatePort()
{ {
NativeWindow window = new NativeWindow(DefaultSettings); NativeWindow window = new NativeWindow(DefaultSettings);
OpenTKPort port = new OpenTKPort(window); OpenTKPort port = new OpenTKPort(window);
@@ -62,31 +62,31 @@ namespace Quik.OpenTK
NativeWindow.ProcessWindowEvents(block); NativeWindow.ProcessWindowEvents(block);
} }
public void DestroyPort(IQuikPortHandle port) => ((OpenTKPort)port).Dispose(); public void DestroyPort(IDashHandle port) => ((OpenTKPort)port).Dispose();
public string PortGetTitle(IQuikPortHandle port) => ((OpenTKPort)port).Title; public string PortGetTitle(IDashHandle port) => ((OpenTKPort)port).Title;
public void PortSetTitle(IQuikPortHandle port, string title) => ((OpenTKPort)port).Title = title; public void PortSetTitle(IDashHandle port, string title) => ((OpenTKPort)port).Title = title;
public QVec2 PortGetSize(IQuikPortHandle port) => ((OpenTKPort)port).Size; public QVec2 PortGetSize(IDashHandle port) => ((OpenTKPort)port).Size;
public void PortSetSize(IQuikPortHandle port, QVec2 size) => ((OpenTKPort)port).Size = size; public void PortSetSize(IDashHandle port, QVec2 size) => ((OpenTKPort)port).Size = size;
public QVec2 PortGetPosition(IQuikPortHandle port) => ((OpenTKPort)port).Position; public QVec2 PortGetPosition(IDashHandle port) => ((OpenTKPort)port).Position;
public void PortSetPosition(IQuikPortHandle port, QVec2 position) => ((OpenTKPort)port).Position = position; public void PortSetPosition(IDashHandle port, QVec2 position) => ((OpenTKPort)port).Position = position;
public bool PortIsValid(IQuikPortHandle port) => ((OpenTKPort)port).IsValid; public bool PortIsValid(IDashHandle port) => ((OpenTKPort)port).IsValid;
public void PortSubscribeEvent(IQuikPortHandle port, EventHandler handler) => ((OpenTKPort)port).EventRaised += handler; public void PortSubscribeEvent(IDashHandle port, EventHandler handler) => ((OpenTKPort)port).EventRaised += handler;
public void PortUnsubscribeEvent(IQuikPortHandle port, EventHandler handler) => ((OpenTKPort)port).EventRaised -= handler; public void PortUnsubscribeEvent(IDashHandle port, EventHandler handler) => ((OpenTKPort)port).EventRaised -= handler;
public void PortFocus(IQuikPortHandle port) => ((OpenTKPort)port).Focus(); public void PortFocus(IDashHandle port) => ((OpenTKPort)port).Focus();
public void PortShow(IQuikPortHandle port, bool shown = true) => ((OpenTKPort)port).Show(shown); public void PortShow(IDashHandle port, bool shown = true) => ((OpenTKPort)port).Show(shown);
public void PortPaint(IQuikPortHandle port, CommandList commands) => ((OpenTKPort)port).Paint(commands); public void PortPaint(IDashHandle port, CommandList commands) => ((OpenTKPort)port).Paint(commands);
public void GetMaximumImage(out int width, out int height) public void GetMaximumImage(out int width, out int height)
{ {

View File

@@ -1,14 +1,14 @@
using System; using System;
using OpenTK.Mathematics; using OpenTK.Mathematics;
using OpenTK.Windowing.Desktop; using OpenTK.Windowing.Desktop;
using Quik.OpenGL; using Dashboard.OpenGL;
using Quik.CommandMachine; using Dashboard.CommandMachine;
using Quik.PAL; using Dashboard.PAL;
using Quik.VertexGenerator; using Dashboard.VertexGenerator;
namespace Quik.OpenTK namespace Dashboard.OpenTK
{ {
public class OpenTKPort : IQuikPortHandle public class OpenTKPort : IDashHandle
{ {
private readonly NativeWindow _window; private readonly NativeWindow _window;
private readonly GL21Driver _glDriver; private readonly GL21Driver _glDriver;
@@ -51,7 +51,7 @@ namespace Quik.OpenTK
public bool IsValid => !isDisposed; public bool IsValid => !isDisposed;
public event EventHandler EventRaised; public event EventHandler? EventRaised;
public OpenTKPort(NativeWindow window) public OpenTKPort(NativeWindow window)
{ {
@@ -78,7 +78,7 @@ namespace Quik.OpenTK
if (!_glDriver.IsInit) if (!_glDriver.IsInit)
_glDriver.Init(); _glDriver.Init();
GL.Clear(GLEnum.GL_COLOR_BUFFER_BIT); GL.Clear(GLEnum.GL_COLOR_BUFFER_BIT | GLEnum.GL_DEPTH_BUFFER_BIT);
_glDriver.Draw(_vertexEngine.DrawQueue, view); _glDriver.Draw(_vertexEngine.DrawQueue, view);
_window.Context.SwapBuffers(); _window.Context.SwapBuffers();

51
Dashboard.sln Normal file
View File

@@ -0,0 +1,51 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dashboard", "Dashboard\Dashboard.csproj", "{4FE772DD-F424-4EAC-BF88-CB8F751B4926}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dashboard.Media.Defaults", "Dashboard.Media.Defaults\Dashboard.Media.Defaults.csproj", "{3798F6DD-8F84-4B7D-A810-B0D4B5ACB672}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dashboard.OpenTK", "Dashboard.OpenTK\Dashboard.OpenTK.csproj", "{2013470A-915C-46F2-BDD3-FCAA39C845EE}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{40F3B724-88A1-4D4F-93AB-FE0DC07A347E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dashboard.Demo", "tests\Dashboard.Demo\Dashboard.Demo.csproj", "{EAA5488E-ADF0-4D68-91F4-FAE98C8691FC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dashboard.BlurgText", "Dashboard.BlurgText\Dashboard.BlurgText.csproj", "{D05A9DEA-A5D1-43DC-AB41-36B07598B749}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4FE772DD-F424-4EAC-BF88-CB8F751B4926}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4FE772DD-F424-4EAC-BF88-CB8F751B4926}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4FE772DD-F424-4EAC-BF88-CB8F751B4926}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4FE772DD-F424-4EAC-BF88-CB8F751B4926}.Release|Any CPU.Build.0 = Release|Any CPU
{3798F6DD-8F84-4B7D-A810-B0D4B5ACB672}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3798F6DD-8F84-4B7D-A810-B0D4B5ACB672}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3798F6DD-8F84-4B7D-A810-B0D4B5ACB672}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3798F6DD-8F84-4B7D-A810-B0D4B5ACB672}.Release|Any CPU.Build.0 = Release|Any CPU
{2013470A-915C-46F2-BDD3-FCAA39C845EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2013470A-915C-46F2-BDD3-FCAA39C845EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2013470A-915C-46F2-BDD3-FCAA39C845EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2013470A-915C-46F2-BDD3-FCAA39C845EE}.Release|Any CPU.Build.0 = Release|Any CPU
{EAA5488E-ADF0-4D68-91F4-FAE98C8691FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EAA5488E-ADF0-4D68-91F4-FAE98C8691FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EAA5488E-ADF0-4D68-91F4-FAE98C8691FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EAA5488E-ADF0-4D68-91F4-FAE98C8691FC}.Release|Any CPU.Build.0 = Release|Any CPU
{D05A9DEA-A5D1-43DC-AB41-36B07598B749}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D05A9DEA-A5D1-43DC-AB41-36B07598B749}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D05A9DEA-A5D1-43DC-AB41-36B07598B749}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D05A9DEA-A5D1-43DC-AB41-36B07598B749}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{EAA5488E-ADF0-4D68-91F4-FAE98C8691FC} = {40F3B724-88A1-4D4F-93AB-FE0DC07A347E}
EndGlobalSection
EndGlobal

View File

@@ -1,4 +1,4 @@
namespace Quik.CommandMachine namespace Dashboard.CommandMachine
{ {
/// <summary> /// <summary>
/// Enumeration of built-in Quik commands. /// Enumeration of built-in Quik commands.

View File

@@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Quik.CommandMachine namespace Dashboard.CommandMachine
{ {
public class CommandEngine public class CommandEngine
{ {
@@ -170,5 +170,63 @@ namespace Quik.CommandMachine
iterator.Dequeue(); iterator.Dequeue();
} }
} }
private static readonly Dictionary<Type, ICommandListSerializer> s_serializers = new Dictionary<Type, ICommandListSerializer>();
/// <summary>
/// Add a custom serializer to the command engine.
/// </summary>
/// <typeparam name="T">Type object type.</typeparam>
/// <param name="serializer">The serializer.</param>
/// <param name="overwrite">True to allow overwriting.</param>
public static void AddSerializer<T>(ICommandListSerializer serializer, bool overwrite = false)
{
if (overwrite)
{
s_serializers[typeof(T)] = serializer;
}
else
{
s_serializers.Add(typeof(T), serializer);
}
}
/// <summary>
/// Add a custom serializer to the command engine.
/// </summary>
/// <typeparam name="T">Type object type.</typeparam>
/// <param name="serializer">The serializer.</param>
/// <param name="overwrite">True to allow overwriting.</param>
public static void AddSerializer<T>(ICommandListSerializer<T> serializer, bool overwrite = false)
=> AddSerializer<T>((ICommandListSerializer)serializer, overwrite);
/// <summary>
/// Get a serializer for the given object.
/// </summary>
/// <typeparam name="T">The object type.</typeparam>
/// <param name="value">Required parameter for the C# type inference to work.</param>
/// <returns>The serializer.</returns>
public static ICommandListSerializer<T> GetSerializer<T>(ICommandListSerializable<T>? value)
where T : ICommandListSerializable<T>, new()
{
if (!s_serializers.TryGetValue(typeof(T), out var serializer))
{
serializer = new CommandListSerializableSerializer<T>();
AddSerializer<T>(serializer);
}
return (ICommandListSerializer<T>)serializer;
}
/// <summary>
/// Get a serializer for the given object.
/// </summary>
/// <typeparam name="T">The object type.</typeparam>
/// <param name="value">Required parameter for the C# type inference to work.</param>
/// <returns>The serializer.</returns>
public static ICommandListSerializer<T> GetSerializer<T>(T? value)
{
return (ICommandListSerializer<T>)s_serializers[typeof(T)];
}
} }
} }

View File

@@ -1,4 +1,4 @@
namespace Quik.CommandMachine namespace Dashboard.CommandMachine
{ {
/// <summary> /// <summary>
/// A delegate for a QUIK command. /// A delegate for a QUIK command.

View File

@@ -1,11 +1,10 @@
using Quik.Media; using Dashboard.Media;
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
namespace Quik.CommandMachine namespace Dashboard.CommandMachine
{ {
public class CommandList : IEnumerable<Frame> public class CommandList : IEnumerable<Frame>
{ {
@@ -316,6 +315,27 @@ namespace Quik.CommandMachine
} }
} }
/// <summary>
/// Serialize an object into the command list.
/// </summary>
/// <typeparam name="T">The type of the value to serialize.</typeparam>
/// <param name="value">What to write into the command list.</param>
public void Write<T>(T value)
{
CommandEngine.GetSerializer(value).Serialize(value, this);
}
/// <summary>
/// Serialize an object into the command list.
/// </summary>
/// <typeparam name="T">The type of the value to serialize.</typeparam>
/// <param name="value">What to write into the command list.</param>
public void Write<T>(ICommandListSerializable<T> value)
where T : ICommandListSerializable<T>, new()
{
CommandEngine.GetSerializer(value).Serialize((T)value, this);
}
public CommandQueue GetEnumerator() => new CommandQueue(_frames); public CommandQueue GetEnumerator() => new CommandQueue(_frames);
IEnumerator<Frame> IEnumerable<Frame>.GetEnumerator() => GetEnumerator(); IEnumerator<Frame> IEnumerable<Frame>.GetEnumerator() => GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
@@ -372,6 +392,28 @@ namespace Quik.CommandMachine
public Frame Peek() => TryPeek(out Frame frame) ? frame : throw new Exception("No more frames left."); public Frame Peek() => TryPeek(out Frame frame) ? frame : throw new Exception("No more frames left.");
/// <summary>
/// Deserialize an object from the command queue.
/// </summary>
/// <typeparam name="T">Type of the object to deserialize.</typeparam>
/// <param name="value">The deserialized value.</param>
public void Read<T>([NotNull] out T? value)
{
value = CommandEngine.GetSerializer(default(T)).Deserialize(this);
}
/// <summary>
/// Deserialize an object from the command queue.
/// </summary>
/// <typeparam name="T">Type of the object to deserialize.</typeparam>
/// <param name="value">The deserialized value.</param>
public void Read<T>([NotNull] out ICommandListSerializable<T>? value)
where T : ICommandListSerializable<T>, new()
{
value = CommandEngine.GetSerializer(value = null).Deserialize(this);
}
/// <inheritdoc/>
public bool MoveNext() public bool MoveNext()
{ {
if (_current + 1 < _frames.Count) if (_current + 1 < _frames.Count)
@@ -382,6 +424,7 @@ namespace Quik.CommandMachine
return false; return false;
} }
/// <inheritdoc/>
public void Reset() public void Reset()
{ {
_current = -1; _current = -1;

View File

@@ -1,7 +1,7 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace Quik.CommandMachine namespace Dashboard.CommandMachine
{ {
[StructLayout(LayoutKind.Explicit)] [StructLayout(LayoutKind.Explicit)]
public struct Frame public struct Frame
@@ -28,7 +28,7 @@ namespace Quik.CommandMachine
private float _f4; private float _f4;
[FieldOffset(24)] [FieldOffset(24)]
private object _object; private object? _object = null;
public bool IsCommand => _type == FrameType.Command; public bool IsCommand => _type == FrameType.Command;
public bool IsInteger => public bool IsInteger =>
@@ -200,7 +200,7 @@ namespace Quik.CommandMachine
public T As<T>() public T As<T>()
{ {
return (T)_object; return (T)_object!;
} }
public float GetF(int i) public float GetF(int i)

View File

@@ -0,0 +1,68 @@
namespace Dashboard.CommandMachine
{
/// <summary>
/// Enumeration of command types in the Dashboard command lists.
/// </summary>
public enum FrameType
{
/// <summary>
/// A null value.
/// </summary>
None,
/// <summary>
/// A command frame.
/// </summary>
Command,
/// <summary>
/// An integer frame.
/// </summary>
IVec1,
/// <summary>
/// A two dimensional integer vector frame.
/// </summary>
IVec2,
/// <summary>
/// A three dimensional integer vector frame.
/// </summary>
IVec3,
/// <summary>
/// A four dimensional integer vector frame.
/// </summary>
IVec4,
/// <summary>
/// A floating point frame.
/// </summary>
Vec1,
/// <summary>
/// A two dimensional floating point vector frame.
/// </summary>
Vec2,
/// <summary>
/// A three dimensional floating point vector frame.
/// </summary>
Vec3,
/// <summary>
/// A four dimensional floating point vector frame.
/// </summary>
Vec4,
/// <summary>
/// A serialized object frame.
/// </summary>
Serialized,
/// <summary>
/// A .Net object frame.
/// </summary>
Object,
}
}

View File

@@ -1,4 +1,4 @@
namespace Quik.CommandMachine namespace Dashboard.CommandMachine
{ {
public enum ImageCommandFlags public enum ImageCommandFlags
{ {

View File

@@ -0,0 +1,69 @@
using System.Diagnostics.CodeAnalysis;
using System.Threading;
namespace Dashboard.CommandMachine
{
public interface ICommandListSerializable { }
/// <summary>
/// Interface for objects that can be serialized into the Dashboard command stream.
/// </summary>
public interface ICommandListSerializable<T> : ICommandListSerializable
{
/// <summary>
/// Seralize object.
/// </summary>
/// <param name="list">The object to serialize into.</param>
void Serialize(CommandList list);
/// <summary>
/// Deserialize object.
/// </summary>
/// <param name="queue">The command queue to deserialize from.</param>
void Deserialize(CommandQueue queue);
}
/// <summary>
/// Base interface for all Command List serializers.
/// </summary>
public interface ICommandListSerializer { }
public interface ICommandListSerializer<T> : ICommandListSerializer
{
/// <summary>
/// Serialize an object into the command list.
/// </summary>
/// <param name="value">The object to serialize.</param>
/// <param name="list">The command list to serialize into.</param>
void Serialize(T value, CommandList list);
/// <summary>
/// Deserialize an object from the command queue.
/// </summary>
/// <param name="queue">The command queue.</param>
/// <returns>The object deserialized from the command queue.</returns>
[return: NotNull]
T Deserialize(CommandQueue queue);
}
/// <summary>
/// Class for automatic serialization of <see cref="ICommandListSerializable"/> objects.
/// </summary>
/// <typeparam name="T">The object type to convert.</typeparam>
internal class CommandListSerializableSerializer<T> : ICommandListSerializer<T>
where T : ICommandListSerializable<T>, new()
{
public T Deserialize(CommandQueue queue)
{
T value = new T();
value.Deserialize(queue);
return value;
}
public void Serialize(T value, CommandList list)
{
value.Serialize(list);
}
}
}

View File

@@ -0,0 +1,56 @@
using System;
namespace Dashboard.Controls
{
public enum Dock
{
None,
Top,
Left,
Bottom,
Right,
Center
}
[Flags]
public enum Anchor
{
None = 0,
Top = 1 << 0,
Left = 1 << 1,
Bottom = 1 << 2,
Right = 1 << 3,
All = Top | Left | Bottom | Right
}
public enum Direction
{
Vertical,
Horizontal
}
public enum TextAlignment
{
Left,
Center,
Right,
Justify,
}
public enum VerticalAlignment
{
Top,
Center,
Bottom,
Justify,
}
public enum HorizontalAlignment
{
Left,
Center,
Right,
Justify
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.Collections;
using System.Collections.Generic;
namespace Dashboard.Controls
{
public abstract class ContainerControl : Control, ICollection<Control>
{
private readonly List<Control> children = new List<Control>();
public int Count => children.Count;
public bool IsReadOnly => false;
public void Add(Control item)
{
children.Add(item);
}
public void Clear()
{
children.Clear();
}
public bool Contains(Control item)
{
return children.Contains(item);
}
public void CopyTo(Control[] array, int arrayIndex)
{
children.CopyTo(array, arrayIndex);
}
public IEnumerator<Control> GetEnumerator()
{
return children.GetEnumerator();
}
public bool Remove(Control item)
{
return children.Remove(item);
}
IEnumerator IEnumerable.GetEnumerator()
{
return children.GetEnumerator();
}
}
}

View File

@@ -0,0 +1,125 @@
using System;
using System.Collections.Generic;
using Dashboard.CommandMachine;
namespace Dashboard.Controls
{
public abstract class Control : UIBase
{
private readonly CommandList drawCommands = new CommandList();
public Style Style { get; set; } = new Style();
public float Padding
{
get => (float)(Style["padding"] ?? 0.0f);
set => Style["padding"] = value;
}
public bool IsVisualsValid { get; private set; } = false;
public bool IsLayoutValid { get; private set; } = false;
protected bool IsLayoutSuspended { get; private set; } = false;
public void InvalidateVisual()
{
IsVisualsValid = false;
OnVisualsInvalidated(this, EventArgs.Empty);
}
public void InvalidateLayout()
{
IsLayoutValid = false;
OnLayoutInvalidated(this, EventArgs.Empty);
}
public void SuspendLayout()
{
IsLayoutSuspended = true;
}
public void ResumeLayout()
{
IsLayoutSuspended = false;
InvalidateLayout();
}
protected abstract void ValidateVisual(CommandList cmd);
protected abstract void ValidateLayout();
protected override void PaintBegin(CommandList cmd)
{
base.PaintBegin(cmd);
if (!IsLayoutValid && !IsLayoutSuspended)
{
ValidateLayout();
OnLayoutValidated(this, EventArgs.Empty);
IsLayoutValid = true;
InvalidateVisual();
}
if (!IsVisualsValid)
{
ValidateVisual(drawCommands);
OnVisualsValidated(this, EventArgs.Empty);
IsVisualsValid = true;
}
cmd.PushStyle(Style);
cmd.PushViewport();
cmd.StoreViewport(AbsoluteBounds);
cmd.Splice(drawCommands);
cmd.PopViewport();
cmd.PopStyle();
}
public event EventHandler? StyleChanged;
public event EventHandler? VisualsInvalidated;
public event EventHandler? VisualsValidated;
public event EventHandler? LayoutInvalidated;
public event EventHandler? LayoutValidated;
protected virtual void OnStyleChanged(object sender, EventArgs ea)
{
StyleChanged?.Invoke(sender, ea);
InvalidateLayout();
}
protected virtual void OnVisualsInvalidated(object sender, EventArgs ea)
{
VisualsInvalidated?.Invoke(sender, ea);
}
protected virtual void OnVisualsValidated(object sender, EventArgs ea)
{
VisualsValidated?.Invoke(sender, ea);
}
protected virtual void OnLayoutInvalidated(object sender, EventArgs ea)
{
LayoutInvalidated?.Invoke(sender, ea);
}
protected virtual void OnLayoutValidated(object sender, EventArgs ea)
{
LayoutValidated?.Invoke(sender, ea);
}
protected void ValidateChildrenLayout()
{
if (this is IEnumerable<Control> enumerable)
{
foreach (Control child in enumerable)
{
if (child.IsLayoutValid)
continue;
child.ValidateLayout();
}
}
}
}
}

View File

@@ -0,0 +1,100 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Dashboard.CommandMachine;
namespace Dashboard.Controls
{
public class FlowBox : ContainerControl
{
public Direction FlowDirection { get; set; }
public bool AllowWrap { get; set; }
public VerticalAlignment VerticalAlignment { get; set; }
public HorizontalAlignment HorizontalAlignment { get; set; }
public float ItemPadding { get; set; } = 4f;
protected override void ValidateLayout()
{
ValidateChildrenLayout();
}
protected override void ValidateVisual(CommandList cmd)
{
throw new NotImplementedException();
}
private void FlowHorizontal()
{
IEnumerator<Control> controls = this.GetEnumerator();
List<Control> row;
}
// Enumerate a row.
private bool EnumerateRows(IEnumerator<Control> iterator, List<Control> row)
{
float width = 0;
do
{
if (width + iterator.Current.Size.X < Size.X)
{
row.Add(iterator.Current);
width += iterator.Current.Size.X + ItemPadding;
}
else
{
return true;
}
} while (iterator.MoveNext());
return false;
}
// Flows a row of children.
private void FlowRow(List<Control> line, QVec2 offset, QVec2 size, float packedWidth)
{
QVec2 pointer = offset;
pointer.X += hstart();
foreach (Control child in line)
{
child.Position = pointer;
pointer += new QVec2(child.Size.X + hoffset(child), voffset(child));
}
float hstart()
{
return HorizontalAlignment switch {
HorizontalAlignment.Center => (size.Y - packedWidth) / 2,
HorizontalAlignment.Right => size.Y - packedWidth,
_ => 0f
};
}
float hoffset(Control child)
{
if (line.Count == 1)
return 0;
else if (HorizontalAlignment == HorizontalAlignment.Justify)
{
return ItemPadding + ((size.Y - packedWidth) / (line.Count - 1));
}
else
{
return ItemPadding;
}
}
float voffset(Control child)
{
return VerticalAlignment switch {
VerticalAlignment.Top => 0f,
VerticalAlignment.Bottom => size.Y - child.Size.Y,
_ => (size.Y - child.Size.Y) / 2,
};
}
}
}
}

View File

@@ -0,0 +1,31 @@
using Dashboard.CommandMachine;
using Dashboard.Media;
using Dashboard.Typography;
namespace Dashboard.Controls
{
public class Label : Control
{
public string Text { get; set; } = string.Empty;
public QFont? Font { get; set; }
public float TextSize { get; set; }
public bool AutoSize { get; set; } = true;
protected override void ValidateLayout()
{
if (AutoSize)
{
QVec2 size = Typesetter.MeasureHorizontal(Text, TextSize, Font!);
Size = size;
}
}
protected override void ValidateVisual(CommandList cmd)
{
float padding = Padding;
QVec2 origin = new QVec2(padding, padding);
cmd.TypesetHorizontalDirect(Text, origin, TextSize, Font!);
}
}
}

View File

@@ -0,0 +1,102 @@
using System;
using Dashboard.CommandMachine;
namespace Dashboard.Controls
{
/// <summary>
/// Bases for all UI elements.
/// </summary>
public abstract class UIBase
{
private QVec2 size;
public UIBase? Parent { get; protected set; }
public string? Id { get; set; }
public QRectangle Bounds
{
get => new QRectangle(Position + Size, Position);
set
{
Size = value.Size;
Position = value.Min;
}
}
public QVec2 Position { get; set; }
public QVec2 Size
{
get => size;
set
{
QVec2 oldSize = size;
size = value;
OnResized(this, new ResizedEventArgs(size, oldSize));
}
}
public QRectangle AbsoluteBounds
{
get
{
if (Parent == null)
{
return Bounds;
}
else
{
return new QRectangle(Bounds.Max + Parent.Position, Bounds.Min + Parent.Position);
}
}
}
public QVec2 MaximumSize { get; set; } = new QVec2(-1, -1);
public QVec2 MinimumSize { get; set; } = new QVec2(-1, -1);
public bool IsMaximumSizeSet => MaximumSize != new QVec2(-1, -1);
public bool IsMinimumSizeSet => MinimumSize != new QVec2(-1, -1);
public virtual void NotifyEvent(object? sender, EventArgs args)
{
}
protected virtual void PaintBegin(CommandList cmd)
{
cmd.PushViewport();
cmd.StoreViewport(AbsoluteBounds);
cmd.PushZ();
}
protected virtual void PaintEnd(CommandList cmd)
{
cmd.PopViewport();
}
public void Paint(CommandList cmd)
{
PaintBegin(cmd);
PaintEnd(cmd);
}
public event EventHandler<ResizedEventArgs>? Resized;
public virtual void OnResized(object sender, ResizedEventArgs ea)
{
Resized?.Invoke(sender, ea);
}
}
public class ResizedEventArgs : EventArgs
{
public QVec2 NewSize { get; }
public QVec2 OldSize { get; }
public ResizedEventArgs(QVec2 newSize, QVec2 oldSize)
{
NewSize = newSize;
OldSize = oldSize;
}
}
}

View File

@@ -1,6 +1,6 @@
using System; using System;
namespace Quik.Controls namespace Dashboard.Controls
{ {
public class View : UIBase public class View : UIBase
{ {

View File

@@ -2,8 +2,8 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<Nullable>disable</Nullable> <Nullable>enable</Nullable>
<LangVersion>8</LangVersion> <LangVersion>latest</LangVersion>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks> <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup> </PropertyGroup>

View File

@@ -1,6 +1,6 @@
using System; using System;
namespace Quik.Media.Color namespace Dashboard.Media.Color
{ {
public static class FormatConvert public static class FormatConvert
{ {

View File

@@ -1,7 +1,7 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace Quik.Media.Color namespace Dashboard.Media.Color
{ {
public class QImageBuffer : QImage public class QImageBuffer : QImage
{ {
@@ -39,7 +39,6 @@ namespace Quik.Media.Color
protected override void Dispose(bool disposing) protected override void Dispose(bool disposing)
{ {
buffer = null;
if (handle.IsAllocated) handle.Free(); if (handle.IsAllocated) handle.Free();
GC.SuppressFinalize(this); GC.SuppressFinalize(this);

View File

@@ -1,6 +1,6 @@
using System; using System;
namespace Quik.Media.Color namespace Dashboard.Media.Color
{ {
public unsafe struct LockIO public unsafe struct LockIO
{ {

View File

@@ -1,4 +1,4 @@
namespace Quik.Media namespace Dashboard.Media
{ {
public static class Extensions public static class Extensions
{ {

View File

@@ -1,11 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using Dashboard.Media.Color;
using System.IO;
using System.Reflection;
using Quik.Media.Color;
namespace Quik.Media.Font namespace Dashboard.Media.Font
{ {
public struct FontAtlasGlyphInfo public struct FontAtlasGlyphInfo
{ {
@@ -20,7 +17,7 @@ namespace Quik.Media.Font
private readonly List<AtlasPage> atlases = new List<AtlasPage>(); private readonly List<AtlasPage> atlases = new List<AtlasPage>();
private readonly Dictionary<int, FontAtlasGlyphInfo> glyphs = new Dictionary<int, FontAtlasGlyphInfo>(); private readonly Dictionary<int, FontAtlasGlyphInfo> glyphs = new Dictionary<int, FontAtlasGlyphInfo>();
private int index = 0; private int index = 0;
private AtlasPage last = null; private AtlasPage? last = null;
private bool isSdf = false; private bool isSdf = false;
private int expansion; private int expansion;
@@ -31,7 +28,7 @@ namespace Quik.Media.Font
{ {
foreach (AtlasPage page in atlases) foreach (AtlasPage page in atlases)
{ {
(page.Image as QImageBuffer).SetSdf(value); ((QImageBuffer)page.Image).SetSdf(value);
} }
isSdf = value; isSdf = value;
} }
@@ -59,7 +56,7 @@ namespace Quik.Media.Font
AddPage(); AddPage();
} }
last.PutGlyph(source, ref info); last!.PutGlyph(source, ref info);
} }
private void AddPage() private void AddPage()
@@ -73,7 +70,7 @@ namespace Quik.Media.Font
else else
{ {
last = new AtlasPage(width, height, expansion); last = new AtlasPage(width, height, expansion);
(last.Image as QImageBuffer).SetSdf(IsSdf); ((QImageBuffer)last.Image).SetSdf(IsSdf);
atlases.Add(last); atlases.Add(last);
} }
} }

View File

@@ -1,7 +1,7 @@
using System; using System;
using System.Text; using System.Text;
namespace Quik.Media.Font namespace Dashboard.Media.Font
{ {
public readonly struct FontFace : IEquatable<FontFace> public readonly struct FontFace : IEquatable<FontFace>
{ {
@@ -74,9 +74,9 @@ namespace Quik.Media.Font
return this == other; return this == other;
} }
public override bool Equals(object obj) public override bool Equals(object? obj)
{ {
return (obj.GetType() == typeof(FontFace)) && return (obj?.GetType() == typeof(FontFace)) &&
this == (FontFace)obj; this == (FontFace)obj;
} }

View File

@@ -1,4 +1,4 @@
namespace Quik.Media.Font namespace Dashboard.Media.Font
{ {
public enum FontSlant public enum FontSlant
{ {

View File

@@ -1,4 +1,4 @@
namespace Quik.Media.Font namespace Dashboard.Media.Font
{ {
/// <summary> /// <summary>
/// Enumeration of font stretch values. /// Enumeration of font stretch values.

View File

@@ -1,6 +1,6 @@
using System; using System;
namespace Quik.Media.Font namespace Dashboard.Media.Font
{ {
public enum FontWeight public enum FontWeight
{ {

View File

@@ -1,4 +1,4 @@
namespace Quik.Media.Font namespace Dashboard.Media.Font
{ {
public enum SystemFontFamily public enum SystemFontFamily
{ {

View File

@@ -1,6 +1,6 @@
using System; using System;
namespace Quik.Media namespace Dashboard.Media
{ {
public enum QImageFormat public enum QImageFormat
{ {

View File

@@ -1,7 +1,7 @@
using System; using System;
using System.IO; using System.IO;
namespace Quik.Media namespace Dashboard.Media
{ {
public enum MediaHint public enum MediaHint
{ {

View File

@@ -1,10 +1,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Quik.Media; using Dashboard.Media;
using Quik.Media.Font; using Dashboard.Media.Font;
namespace Quik.Media namespace Dashboard.Media
{ {
/// <summary> /// <summary>
/// Abstract class that represents a font. /// Abstract class that represents a font.
@@ -25,7 +25,7 @@ namespace Quik.Media
public void Get(int codepoint, float size, out FontGlyph glyph) public void Get(int codepoint, float size, out FontGlyph glyph)
{ {
SizedFontCollection collection; SizedFontCollection? collection;
if (!_atlasses.TryGetValue(size, out collection)) if (!_atlasses.TryGetValue(size, out collection))
{ {
@@ -59,14 +59,14 @@ namespace Quik.Media
{ {
Size = size; Size = size;
QuikApplication.Current.Platform.GetMaximumImage(out int height, out int width); DashboardApplication.Current.Platform.GetMaximumImage(out int height, out int width);
// Do no allow to create a texture that is greater than 16 square characters at 200 DPI. // Do no allow to create a texture that is greater than 16 square characters at 200 DPI.
width = Math.Min(width, (int)(size * 200 * 16)); width = Math.Min(width, (int)(size * 200 * 16));
height = Math.Min(height, (int)(size * 200 * 16)); height = Math.Min(height, (int)(size * 200 * 16));
// width = height = 256; // width = height = 256;
atlas = new FontAtlas(width, height, QuikApplication.Current.FontProvider.RasterizerOptions.Sdf); atlas = new FontAtlas(width, height, DashboardApplication.Current.FontProvider.RasterizerOptions.Sdf);
} }
public void Get(int codepoint, out FontGlyph glyph, QFont font) public void Get(int codepoint, out FontGlyph glyph, QFont font)
@@ -78,7 +78,7 @@ namespace Quik.Media
out QGlyphMetrics metrics, out QGlyphMetrics metrics,
codepoint, codepoint,
Size, Size,
QuikApplication.Current.FontProvider.RasterizerOptions); DashboardApplication.Current.FontProvider.RasterizerOptions);
if (image != null) if (image != null)
{ {
@@ -102,11 +102,11 @@ namespace Quik.Media
public readonly struct FontGlyph public readonly struct FontGlyph
{ {
public readonly int CodePoint; public readonly int CodePoint;
public readonly QImage Image; public readonly QImage? Image;
public readonly QGlyphMetrics Metrics; public readonly QGlyphMetrics Metrics;
public readonly QRectangle UVs; public readonly QRectangle UVs;
public FontGlyph(int codepoint, QImage image, in QGlyphMetrics metrics, in QRectangle uvs) public FontGlyph(int codepoint, QImage? image, in QGlyphMetrics metrics, in QRectangle uvs)
{ {
CodePoint = codepoint; CodePoint = codepoint;
Image = image; Image = image;

View File

@@ -1,4 +1,4 @@
namespace Quik.Media namespace Dashboard.Media
{ {
/// <summary> /// <summary>
/// Glyph properties with metrics based on FreeType glyph metrics. /// Glyph properties with metrics based on FreeType glyph metrics.

View File

@@ -1,5 +1,5 @@
using System; using System;
namespace Quik.Media namespace Dashboard.Media
{ {
public abstract class QImage : IDisposable public abstract class QImage : IDisposable
{ {

View File

@@ -1,6 +1,6 @@
using System; using System;
namespace Quik namespace Dashboard
{ {
public enum MouseButton : byte public enum MouseButton : byte
{ {

View File

@@ -1,16 +1,16 @@
using System; using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace Quik.OpenGL namespace Dashboard.OpenGL
{ {
public unsafe static partial class GL public unsafe static partial class GL
{ {
private delegate void BufferDataProc(GLEnum target, int size, void* data, GLEnum usageHint); private delegate void BufferDataProc(GLEnum target, int size, void* data, GLEnum usageHint);
private static GenObjectsProc _genBuffers; private static GenObjectsProc? _genBuffers;
private static GenObjectsProc _deleteBuffers; private static GenObjectsProc? _deleteBuffers;
private static BindSlottedProc _bindBuffer; private static BindSlottedProc? _bindBuffer;
private static BufferDataProc _bufferData; private static BufferDataProc? _bufferData;
private static void LoadBuffer() private static void LoadBuffer()
{ {
@@ -24,7 +24,7 @@ namespace Quik.OpenGL
public static void GenBuffers(int count, out int buffers) public static void GenBuffers(int count, out int buffers)
{ {
fixed (int *ptr = &buffers) fixed (int *ptr = &buffers)
_genBuffers(count, ptr); _genBuffers!(count, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
@@ -41,7 +41,7 @@ namespace Quik.OpenGL
public static void DeleteBuffers(int count, ref int buffers) public static void DeleteBuffers(int count, ref int buffers)
{ {
fixed (int *ptr = &buffers) fixed (int *ptr = &buffers)
_deleteBuffers(count, ptr); _deleteBuffers!(count, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
@@ -53,19 +53,19 @@ namespace Quik.OpenGL
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void BindBuffer(GLEnum target, int buffer) public static void BindBuffer(GLEnum target, int buffer)
{ {
_bindBuffer(target, buffer); _bindBuffer!(target, buffer);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void BufferData(GLEnum target, int size, IntPtr data, GLEnum usageHint) => public static void BufferData(GLEnum target, int size, IntPtr data, GLEnum usageHint) =>
_bufferData(target, size, (void*)data, usageHint); _bufferData!(target, size, (void*)data, usageHint);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void BufferData<T>(GLEnum target, int size, ref T data, GLEnum usageHint) public static void BufferData<T>(GLEnum target, int size, ref T data, GLEnum usageHint)
where T : unmanaged where T : unmanaged
{ {
fixed (T* ptr = &data) fixed (T* ptr = &data)
_bufferData(target, size, ptr, usageHint); _bufferData!(target, size, ptr, usageHint);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]

View File

@@ -1,8 +1,8 @@
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using static Quik.OpenGL.GLEnum; using static Dashboard.OpenGL.GLEnum;
namespace Quik.OpenGL namespace Dashboard.OpenGL
{ {
public unsafe static partial class GL public unsafe static partial class GL
{ {
@@ -16,16 +16,16 @@ namespace Quik.OpenGL
private delegate void DeleteProgramProc(int program); private delegate void DeleteProgramProc(int program);
private delegate int GetShaderLocationProc(int program, byte *name); private delegate int GetShaderLocationProc(int program, byte *name);
private static CreateProgramProc _createProgram; private static CreateProgramProc? _createProgram;
private static UseProgramProc _useProgram; private static UseProgramProc? _useProgram;
private static AttachShaderProc _attachShader; private static AttachShaderProc? _attachShader;
private static DetachShaderProc _detachShader; private static DetachShaderProc? _detachShader;
private static LinkProgramProc _linkProgram; private static LinkProgramProc? _linkProgram;
private static GetProgramProc _getProgram; private static GetProgramProc? _getProgram;
private static GetProgramInfoLogProc _getProgramInfoLog; private static GetProgramInfoLogProc? _getProgramInfoLog;
private static DeleteProgramProc _deleteProgram; private static DeleteProgramProc? _deleteProgram;
private static GetShaderLocationProc _getUniformLocation; private static GetShaderLocationProc? _getUniformLocation;
private static GetShaderLocationProc _getAttribLocation; private static GetShaderLocationProc? _getAttribLocation;
private static void LoadProgram() private static void LoadProgram()
{ {
@@ -42,26 +42,26 @@ namespace Quik.OpenGL
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static int CreateProgram() => _createProgram(); public static int CreateProgram() => _createProgram!();
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void UseProgram(int program) => _useProgram(program); public static void UseProgram(int program) => _useProgram!(program);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void AttachShader(int program, int shader) => _attachShader(program, shader); public static void AttachShader(int program, int shader) => _attachShader!(program, shader);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void DetachShader(int program, int shader) => _detachShader(program, shader); public static void DetachShader(int program, int shader) => _detachShader!(program, shader);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void LinkProgram(int program) => _linkProgram(program); public static void LinkProgram(int program) => _linkProgram!(program);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void GetProgram(int program, GLEnum pname, out int value) public static void GetProgram(int program, GLEnum pname, out int value)
{ {
value = default; value = default;
fixed (int* ptr = &value) fixed (int* ptr = &value)
_getProgram(program, pname, ptr); _getProgram!(program, pname, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
@@ -71,26 +71,26 @@ namespace Quik.OpenGL
byte[] infoLog = new byte[length]; byte[] infoLog = new byte[length];
fixed (byte *ptr = infoLog) fixed (byte *ptr = infoLog)
_getProgramInfoLog(program, length, &length, ptr); _getProgramInfoLog!(program, length, &length, ptr);
return Encoding.UTF8.GetString(infoLog); return Encoding.UTF8.GetString(infoLog);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void DeleteProgram(int program) => _deleteProgram(program); public static void DeleteProgram(int program) => _deleteProgram!(program);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static int GetUniformLocation(int program, string name) public static int GetUniformLocation(int program, string name)
{ {
fixed(byte* ptr = Encoding.UTF8.GetBytes(name)) fixed(byte* ptr = Encoding.UTF8.GetBytes(name))
return _getUniformLocation(program, ptr); return _getUniformLocation!(program, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static int GetAttribLocation(int program, string name) public static int GetAttribLocation(int program, string name)
{ {
fixed(byte* ptr = Encoding.UTF8.GetBytes(name)) fixed(byte* ptr = Encoding.UTF8.GetBytes(name))
return _getAttribLocation(program, ptr); return _getAttribLocation!(program, ptr);
} }
} }
} }

View File

@@ -2,9 +2,9 @@ using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using static Quik.OpenGL.GLEnum; using static Dashboard.OpenGL.GLEnum;
namespace Quik.OpenGL namespace Dashboard.OpenGL
{ {
public unsafe static partial class GL public unsafe static partial class GL
{ {
@@ -15,12 +15,12 @@ namespace Quik.OpenGL
private delegate void GetShaderInfoLogProc(int shader, int maxLength, int* length, byte* infoLog); private delegate void GetShaderInfoLogProc(int shader, int maxLength, int* length, byte* infoLog);
private delegate void DeleteShaderProc(int id); private delegate void DeleteShaderProc(int id);
private static CreateShaderProc _createShader; private static CreateShaderProc? _createShader;
private static ShaderSourceProc _shaderSource; private static ShaderSourceProc? _shaderSource;
private static CompileShaderProc _compileShader; private static CompileShaderProc? _compileShader;
private static GetShaderProc _getShader; private static GetShaderProc? _getShader;
private static GetShaderInfoLogProc _getShaderInfoLog; private static GetShaderInfoLogProc? _getShaderInfoLog;
private static DeleteShaderProc _deleteShader; private static DeleteShaderProc? _deleteShader;
private static void LoadShader() private static void LoadShader()
{ {
@@ -33,7 +33,7 @@ namespace Quik.OpenGL
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static int CreateShader(GLEnum type) => _createShader(type); public static int CreateShader(GLEnum type) => _createShader!(type);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void ShaderSource(int shader, string source) public static void ShaderSource(int shader, string source)
@@ -43,7 +43,7 @@ namespace Quik.OpenGL
fixed (byte* ptr = &sourceUTF8[0]) fixed (byte* ptr = &sourceUTF8[0])
{ {
_shaderSource(shader, 1, &ptr, &length); _shaderSource!(shader, 1, &ptr, &length);
} }
} }
@@ -69,7 +69,7 @@ namespace Quik.OpenGL
fixed (byte** ptr = &pointers[0]) fixed (byte** ptr = &pointers[0])
fixed (int * len = &lengths[0]) fixed (int * len = &lengths[0])
{ {
_shaderSource(shader, count, ptr, len); _shaderSource!(shader, count, ptr, len);
} }
} }
finally finally
@@ -82,14 +82,14 @@ namespace Quik.OpenGL
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void CompileShader(int shader) => _compileShader(shader); public static void CompileShader(int shader) => _compileShader!(shader);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void GetShader(int shader, GLEnum pname, out int value) public static void GetShader(int shader, GLEnum pname, out int value)
{ {
value = default; value = default;
fixed (int *ptr = &value) fixed (int *ptr = &value)
_getShader(shader, pname, ptr); _getShader!(shader, pname, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
@@ -99,12 +99,12 @@ namespace Quik.OpenGL
byte[] infoLog = new byte[length]; byte[] infoLog = new byte[length];
fixed (byte *ptr = infoLog) fixed (byte *ptr = infoLog)
_getShaderInfoLog(shader, length, &length, ptr); _getShaderInfoLog!(shader, length, &length, ptr);
return Encoding.UTF8.GetString(infoLog); return Encoding.UTF8.GetString(infoLog);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void DeleteShader(int shader) => _deleteShader(shader); public static void DeleteShader(int shader) => _deleteShader!(shader);
} }
} }

View File

@@ -1,7 +1,7 @@
using System; using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace Quik.OpenGL namespace Dashboard.OpenGL
{ {
public unsafe static partial class GL public unsafe static partial class GL
{ {
@@ -18,21 +18,21 @@ namespace Quik.OpenGL
private delegate void TexParameterfvProc(GLEnum target, GLEnum pname, float* value); private delegate void TexParameterfvProc(GLEnum target, GLEnum pname, float* value);
private delegate void GenerateMipmapProc(GLEnum target); private delegate void GenerateMipmapProc(GLEnum target);
private static GenObjectsProc _genTextures; private static GenObjectsProc? _genTextures;
private static GenObjectsProc _deleteTextures; private static GenObjectsProc? _deleteTextures;
private static BindSlottedProc _bindTexture; private static BindSlottedProc? _bindTexture;
private static ActiveTextureProc _activeTexture; private static ActiveTextureProc? _activeTexture;
private static PixelStoreiProc _pixelStorei; private static PixelStoreiProc? _pixelStorei;
private static PixelStorefProc _pixelStoref; private static PixelStorefProc? _pixelStoref;
private static TexImage2DProc _texImage2D; private static TexImage2DProc? _texImage2D;
private static TexImage3DProc _texImage3D; private static TexImage3DProc? _texImage3D;
private static TexSubImage2DProc _texSubImage2D; private static TexSubImage2DProc? _texSubImage2D;
private static TexSubImage3DProc _texSubImage3D; private static TexSubImage3DProc? _texSubImage3D;
private static TexParameteriProc _texParameteri; private static TexParameteriProc? _texParameteri;
private static TexParameterfProc _texParameterf; private static TexParameterfProc? _texParameterf;
private static TexParameterivProc _texParameteriv; private static TexParameterivProc? _texParameteriv;
private static TexParameterfvProc _texParameterfv; private static TexParameterfvProc? _texParameterfv;
private static GenerateMipmapProc _generateMipmap; private static GenerateMipmapProc? _generateMipmap;
private static void LoadTexture() private static void LoadTexture()
{ {
@@ -57,7 +57,7 @@ namespace Quik.OpenGL
public static void GenTextures(int count, out int textures) public static void GenTextures(int count, out int textures)
{ {
fixed (int *ptr = &textures) fixed (int *ptr = &textures)
_genTextures(count, ptr); _genTextures!(count, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static int GenTexture() public static int GenTexture()
@@ -72,7 +72,7 @@ namespace Quik.OpenGL
public static void DeleteTextures(int count, in int textures) public static void DeleteTextures(int count, in int textures)
{ {
fixed (int* ptr = &textures) fixed (int* ptr = &textures)
_deleteTextures(count, ptr); _deleteTextures!(count, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
@@ -82,26 +82,26 @@ namespace Quik.OpenGL
public static void DeleteTextures(int[] textures) => DeleteTextures(textures.Length, in textures[0]); public static void DeleteTextures(int[] textures) => DeleteTextures(textures.Length, in textures[0]);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void BindTexture(GLEnum target, int texture) => _bindTexture(target, texture); public static void BindTexture(GLEnum target, int texture) => _bindTexture!(target, texture);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void ActiveTexture(GLEnum unit) => _activeTexture(unit); public static void ActiveTexture(GLEnum unit) => _activeTexture!(unit);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void PixelStore(GLEnum pname, int value) => _pixelStorei(pname, value); public static void PixelStore(GLEnum pname, int value) => _pixelStorei!(pname, value);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void PixelStore(GLEnum pname, float value) => _pixelStoref(pname, value); public static void PixelStore(GLEnum pname, float value) => _pixelStoref!(pname, value);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void TexImage2D(GLEnum target, int level, GLEnum internalFormat, int width, int height, int border, GLEnum format, GLEnum pixelType, IntPtr data) => public static void TexImage2D(GLEnum target, int level, GLEnum internalFormat, int width, int height, int border, GLEnum format, GLEnum pixelType, IntPtr data) =>
_texImage2D(target, level, internalFormat, width, height, border, format, pixelType, (void*)data); _texImage2D!(target, level, internalFormat, width, height, border, format, pixelType, (void*)data);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void TexImage2D<T>(GLEnum target, int level, GLEnum internalFormat, int width, int height, int border, GLEnum format, GLEnum pixelType, in T data) where T : unmanaged public static void TexImage2D<T>(GLEnum target, int level, GLEnum internalFormat, int width, int height, int border, GLEnum format, GLEnum pixelType, in T data) where T : unmanaged
{ {
fixed(T *ptr = &data) fixed(T *ptr = &data)
_texImage2D(target, level, internalFormat, width, height, border, format, pixelType, ptr); _texImage2D!(target, level, internalFormat, width, height, border, format, pixelType, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
@@ -110,14 +110,14 @@ namespace Quik.OpenGL
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void TexImage3D(GLEnum target, int level, GLEnum internalFormat, int width, int height, int depth, int border, GLEnum format, GLEnum pixelType, void* data) => public static void TexImage3D(GLEnum target, int level, GLEnum internalFormat, int width, int height, int depth, int border, GLEnum format, GLEnum pixelType, void* data) =>
_texImage3D(target, level, internalFormat, width, height, depth, border, format, pixelType, data); _texImage3D!(target, level, internalFormat, width, height, depth, border, format, pixelType, data);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void TexImage3D<T>(GLEnum target, int level, GLEnum internalFormat, int width, int height, int depth, int border, GLEnum format, GLEnum pixelType, in T data) public static void TexImage3D<T>(GLEnum target, int level, GLEnum internalFormat, int width, int height, int depth, int border, GLEnum format, GLEnum pixelType, in T data)
where T : unmanaged where T : unmanaged
{ {
fixed (T* ptr = &data) fixed (T* ptr = &data)
_texImage3D(target, level, internalFormat, width, height, depth, border, format, pixelType, ptr); _texImage3D!(target, level, internalFormat, width, height, depth, border, format, pixelType, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
@@ -127,13 +127,13 @@ namespace Quik.OpenGL
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void TexSubImage2D(GLEnum target, int level, int x, int y, int width, int height, GLEnum format, GLEnum pixelType, IntPtr data) => public static void TexSubImage2D(GLEnum target, int level, int x, int y, int width, int height, GLEnum format, GLEnum pixelType, IntPtr data) =>
_texSubImage2D(target, level, x, y, width, height,format, pixelType, (void*)data); _texSubImage2D!(target, level, x, y, width, height,format, pixelType, (void*)data);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void TexSubImage2d<T>(GLEnum target, int level, int x, int y, int width, int height, GLEnum format, GLEnum pixelType, in T data) where T : unmanaged public static void TexSubImage2d<T>(GLEnum target, int level, int x, int y, int width, int height, GLEnum format, GLEnum pixelType, in T data) where T : unmanaged
{ {
fixed(T *ptr = &data) fixed(T *ptr = &data)
_texSubImage2D(target, level, x, y, width, height, format, pixelType, ptr); _texSubImage2D!(target, level, x, y, width, height, format, pixelType, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
@@ -142,14 +142,14 @@ namespace Quik.OpenGL
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void TexSubImage3D(GLEnum target, int level, int x, int y, int z, int width, int height, int depth, int border, GLEnum format, GLEnum pixelType, void* data) => public static void TexSubImage3D(GLEnum target, int level, int x, int y, int z, int width, int height, int depth, int border, GLEnum format, GLEnum pixelType, void* data) =>
_texSubImage3D(target, level, x, y, z, width, height, depth, border, format, pixelType, data); _texSubImage3D!(target, level, x, y, z, width, height, depth, border, format, pixelType, data);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void TexSubImage3D<T>(GLEnum target, int level, int x, int y, int z, int width, int height, int depth, int border, GLEnum format, GLEnum pixelType, in T data) public static void TexSubImage3D<T>(GLEnum target, int level, int x, int y, int z, int width, int height, int depth, int border, GLEnum format, GLEnum pixelType, in T data)
where T : unmanaged where T : unmanaged
{ {
fixed (T* ptr = &data) fixed (T* ptr = &data)
_texSubImage3D(target, level, x, y, z, width, height, depth, border, format, pixelType, ptr); _texSubImage3D!(target, level, x, y, z, width, height, depth, border, format, pixelType, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
@@ -158,16 +158,16 @@ namespace Quik.OpenGL
TexSubImage3D(target, level, x, y, z, width, height, depth, border, format, pixelType, in data[0]); TexSubImage3D(target, level, x, y, z, width, height, depth, border, format, pixelType, in data[0]);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void TexParameter(GLEnum target, GLEnum pname, int value) => _texParameteri(target, pname, value); public static void TexParameter(GLEnum target, GLEnum pname, int value) => _texParameteri!(target, pname, value);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void TexParameter(GLEnum target, GLEnum pname, GLEnum value) => _texParameteri(target, pname, (int)value); public static void TexParameter(GLEnum target, GLEnum pname, GLEnum value) => _texParameteri!(target, pname, (int)value);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void TexParameter(GLEnum target, GLEnum pname, float value) => _texParameterf(target, pname, value); public static void TexParameter(GLEnum target, GLEnum pname, float value) => _texParameterf!(target, pname, value);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void TexParameter(GLEnum target, GLEnum pname, ref int values) public static void TexParameter(GLEnum target, GLEnum pname, ref int values)
{ {
fixed (int *ptr = &values) fixed (int *ptr = &values)
_texParameteriv(target, pname, ptr); _texParameteriv!(target, pname, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void TexParameter(GLEnum target, GLEnum pname, int[] values) => TexParameter(target, pname, ref values[0]); public static void TexParameter(GLEnum target, GLEnum pname, int[] values) => TexParameter(target, pname, ref values[0]);
@@ -176,12 +176,12 @@ namespace Quik.OpenGL
public static void TexParameter(GLEnum target, GLEnum pname, ref float values) public static void TexParameter(GLEnum target, GLEnum pname, ref float values)
{ {
fixed (float *ptr = &values) fixed (float *ptr = &values)
_texParameterfv(target, pname, ptr); _texParameterfv!(target, pname, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void TexParameter(GLEnum target, GLEnum pname, float[] values) => TexParameter(target, pname, ref values[0]); public static void TexParameter(GLEnum target, GLEnum pname, float[] values) => TexParameter(target, pname, ref values[0]);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void GenerateMipmap(GLEnum target) => _generateMipmap(target); public static void GenerateMipmap(GLEnum target) => _generateMipmap!(target);
} }
} }

View File

@@ -1,6 +1,6 @@
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace Quik.OpenGL namespace Dashboard.OpenGL
{ {
public unsafe static partial class GL public unsafe static partial class GL
{ {
@@ -16,25 +16,25 @@ namespace Quik.OpenGL
private delegate void UniformNivProc(int location, int count, int* value); private delegate void UniformNivProc(int location, int count, int* value);
private delegate void UniformMatrixNxNfvProc(int location, int count, bool transpose, float *value); private delegate void UniformMatrixNxNfvProc(int location, int count, bool transpose, float *value);
private static Uniform1fProc _uniform1f; private static Uniform1fProc? _uniform1f;
private static Uniform2fProc _uniform2f; private static Uniform2fProc? _uniform2f;
private static Uniform3fProc _uniform3f; private static Uniform3fProc? _uniform3f;
private static Uniform4fProc _uniform4f; private static Uniform4fProc? _uniform4f;
private static Uniform1iProc _uniform1i; private static Uniform1iProc? _uniform1i;
private static Uniform2iProc _uniform2i; private static Uniform2iProc? _uniform2i;
private static Uniform3iProc _uniform3i; private static Uniform3iProc? _uniform3i;
private static Uniform4iProc _uniform4i; private static Uniform4iProc? _uniform4i;
private static UniformNfvProc _uniform1fv; private static UniformNfvProc? _uniform1fv;
private static UniformNfvProc _uniform2fv; private static UniformNfvProc? _uniform2fv;
private static UniformNfvProc _uniform3fv; private static UniformNfvProc? _uniform3fv;
private static UniformNfvProc _uniform4fv; private static UniformNfvProc? _uniform4fv;
private static UniformNivProc _uniform1iv; private static UniformNivProc? _uniform1iv;
private static UniformNivProc _uniform2iv; private static UniformNivProc? _uniform2iv;
private static UniformNivProc _uniform3iv; private static UniformNivProc? _uniform3iv;
private static UniformNivProc _uniform4iv; private static UniformNivProc? _uniform4iv;
private static UniformMatrixNxNfvProc _uniformMatrix2fv; private static UniformMatrixNxNfvProc? _uniformMatrix2fv;
private static UniformMatrixNxNfvProc _uniformMatrix3fv; private static UniformMatrixNxNfvProc? _uniformMatrix3fv;
private static UniformMatrixNxNfvProc _uniformMatrix4fv; private static UniformMatrixNxNfvProc? _uniformMatrix4fv;
public static void LoadUniform() public static void LoadUniform()
{ {
@@ -62,161 +62,161 @@ namespace Quik.OpenGL
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void Uniform1(int location, float x) public static void Uniform1(int location, float x)
{ {
_uniform1f(location, x); _uniform1f!(location, x);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void Uniform2(int location, float x, float y) public static void Uniform2(int location, float x, float y)
{ {
_uniform2f(location, x, y); _uniform2f!(location, x, y);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void Uniform3(int location, float x, float y, float z) public static void Uniform3(int location, float x, float y, float z)
{ {
_uniform3f(location, x, y, z); _uniform3f!(location, x, y, z);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void Uniform4(int location, float x, float y, float z, float w) public static void Uniform4(int location, float x, float y, float z, float w)
{ {
_uniform4f(location, x, y, z, w); _uniform4f!(location, x, y, z, w);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void Uniform1(int location, int x) public static void Uniform1(int location, int x)
{ {
_uniform1i(location, x); _uniform1i!(location, x);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void Uniform2(int location, int x, int y) public static void Uniform2(int location, int x, int y)
{ {
_uniform2i(location, x, y); _uniform2i!(location, x, y);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void Uniform3(int location, int x, int y, int z) public static void Uniform3(int location, int x, int y, int z)
{ {
_uniform3i(location, x, y, z); _uniform3i!(location, x, y, z);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void Uniform4(int location, int x, int y, int z, int w) public static void Uniform4(int location, int x, int y, int z, int w)
{ {
_uniform4i(location, x, y, z, w); _uniform4i!(location, x, y, z, w);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void Uniform1(int location, int count, ref float first) public static void Uniform1(int location, int count, ref float first)
{ {
fixed(float *ptr = &first) fixed(float *ptr = &first)
_uniform1fv(location, count, ptr); _uniform1fv!(location, count, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void Uniform2(int location, int count, ref float first) public static void Uniform2(int location, int count, ref float first)
{ {
fixed(float *ptr = &first) fixed(float *ptr = &first)
_uniform2fv(location, count, ptr); _uniform2fv!(location, count, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void Uniform3(int location, int count, ref float first) public static void Uniform3(int location, int count, ref float first)
{ {
fixed(float *ptr = &first) fixed(float *ptr = &first)
_uniform3fv(location, count, ptr); _uniform3fv!(location, count, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void Uniform4(int location, int count, ref float first) public static void Uniform4(int location, int count, ref float first)
{ {
fixed(float *ptr = &first) fixed(float *ptr = &first)
_uniform4fv(location, count, ptr); _uniform4fv!(location, count, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void Uniform1(int location, int count, ref int first) public static void Uniform1(int location, int count, ref int first)
{ {
fixed(int *ptr = &first) fixed(int *ptr = &first)
_uniform1iv(location, count, ptr); _uniform1iv!(location, count, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void Uniform2(int location, int count, ref int first) public static void Uniform2(int location, int count, ref int first)
{ {
fixed(int *ptr = &first) fixed(int *ptr = &first)
_uniform2iv(location, count, ptr); _uniform2iv!(location, count, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void Uniform3(int location, int count, ref int first) public static void Uniform3(int location, int count, ref int first)
{ {
fixed(int *ptr = &first) fixed(int *ptr = &first)
_uniform3iv(location, count, ptr); _uniform3iv!(location, count, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void Uniform4(int location, int count, ref int first) public static void Uniform4(int location, int count, ref int first)
{ {
fixed(int *ptr = &first) fixed(int *ptr = &first)
_uniform4iv(location, count, ptr); _uniform4iv!(location, count, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void UniformMatrix2(int location, bool transpose, ref float m11) public static void UniformMatrix2(int location, bool transpose, ref float m11)
{ {
fixed (float* ptr = &m11) fixed (float* ptr = &m11)
_uniformMatrix2fv(location, 1, transpose, ptr); _uniformMatrix2fv!(location, 1, transpose, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void UniformMatrix3(int location, bool transpose, ref float m11) public static void UniformMatrix3(int location, bool transpose, ref float m11)
{ {
fixed (float* ptr = &m11) fixed (float* ptr = &m11)
_uniformMatrix3fv(location, 1, transpose, ptr); _uniformMatrix3fv!(location, 1, transpose, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void UniformMatrix4(int location, bool transpose, ref float m11) public static void UniformMatrix4(int location, bool transpose, ref float m11)
{ {
fixed (float* ptr = &m11) fixed (float* ptr = &m11)
_uniformMatrix4fv(location, 1, transpose, ptr); _uniformMatrix4fv!(location, 1, transpose, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void UniformMatrix2(int location, int count, bool transpose, ref float m11) public static void UniformMatrix2(int location, int count, bool transpose, ref float m11)
{ {
fixed (float* ptr = &m11) fixed (float* ptr = &m11)
_uniformMatrix2fv(location, count, transpose, ptr); _uniformMatrix2fv!(location, count, transpose, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void UniformMatrix3(int location, int count, bool transpose, ref float m11) public static void UniformMatrix3(int location, int count, bool transpose, ref float m11)
{ {
fixed (float* ptr = &m11) fixed (float* ptr = &m11)
_uniformMatrix3fv(location, count, transpose, ptr); _uniformMatrix3fv!(location, count, transpose, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void UniformMatrix4(int location, int count, bool transpose, ref float m11) public static void UniformMatrix4(int location, int count, bool transpose, ref float m11)
{ {
fixed (float* ptr = &m11) fixed (float* ptr = &m11)
_uniformMatrix4fv(location, count, transpose, ptr); _uniformMatrix4fv!(location, count, transpose, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void UniformMatrix4(int location, bool transpose, in QMat4 m4) public static void UniformMatrix4(int location, bool transpose, in QMat4 m4)
{ {
fixed (float* ptr = &m4.M11) fixed (float* ptr = &m4.M11)
_uniformMatrix4fv(location, 1, transpose, ptr); _uniformMatrix4fv!(location, 1, transpose, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void UniformMatrix4(int location, int count, bool transpose, ref QMat4 m4) public static void UniformMatrix4(int location, int count, bool transpose, ref QMat4 m4)
{ {
fixed (float* ptr = &m4.M11) fixed (float* ptr = &m4.M11)
_uniformMatrix4fv(location, count, transpose, ptr); _uniformMatrix4fv!(location, count, transpose, ptr);
} }
} }
} }

View File

@@ -1,7 +1,7 @@
using System; using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace Quik.OpenGL namespace Dashboard.OpenGL
{ {
public unsafe static partial class GL public unsafe static partial class GL
{ {
@@ -9,13 +9,13 @@ namespace Quik.OpenGL
private delegate void VertexAttribPointerProc(int location, int size, GLEnum type, bool normalized, int stride, IntPtr offset); private delegate void VertexAttribPointerProc(int location, int size, GLEnum type, bool normalized, int stride, IntPtr offset);
private delegate void VertexAttribIPointerProc(int location, int size, GLEnum type, int stride, IntPtr offset); private delegate void VertexAttribIPointerProc(int location, int size, GLEnum type, int stride, IntPtr offset);
private static GenObjectsProc _genVertexArrays; private static GenObjectsProc? _genVertexArrays;
private static GenObjectsProc _deleteVertexArrays; private static GenObjectsProc? _deleteVertexArrays;
private static BindObjectProc _bindVertexArray; private static BindObjectProc? _bindVertexArray;
private static EnableVertexAttribArrayProc _enableVertexAttribArray; private static EnableVertexAttribArrayProc? _enableVertexAttribArray;
private static EnableVertexAttribArrayProc _disableVertexAttribArray; private static EnableVertexAttribArrayProc? _disableVertexAttribArray;
private static VertexAttribPointerProc _vertexAttribPointer; private static VertexAttribPointerProc? _vertexAttribPointer;
private static VertexAttribIPointerProc _vertexAttribIPointer; private static VertexAttribIPointerProc? _vertexAttribIPointer;
private static void LoadVertexArrays() private static void LoadVertexArrays()
{ {
@@ -32,7 +32,7 @@ namespace Quik.OpenGL
public static void GenVertexArrays(int count, out int vertexArrays) public static void GenVertexArrays(int count, out int vertexArrays)
{ {
fixed (int *ptr = &vertexArrays) fixed (int *ptr = &vertexArrays)
_genVertexArrays(count, ptr); _genVertexArrays!(count, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
@@ -49,7 +49,7 @@ namespace Quik.OpenGL
public static void DeleteVertexArrays(int count, ref int vertexArrays) public static void DeleteVertexArrays(int count, ref int vertexArrays)
{ {
fixed (int *ptr = &vertexArrays) fixed (int *ptr = &vertexArrays)
_deleteVertexArrays(count, ptr); _deleteVertexArrays!(count, ptr);
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
@@ -59,20 +59,20 @@ namespace Quik.OpenGL
public static void DeleteVertexArray(int vertexArray) => DeleteVertexArrays(1, ref vertexArray); public static void DeleteVertexArray(int vertexArray) => DeleteVertexArrays(1, ref vertexArray);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void BindVertexArray(int vertexArray) => _bindVertexArray(vertexArray); public static void BindVertexArray(int vertexArray) => _bindVertexArray!(vertexArray);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void EnableVertexAttribArray(int location) => _enableVertexAttribArray(location); public static void EnableVertexAttribArray(int location) => _enableVertexAttribArray!(location);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void DisableVertexAttribArray(int location) => _disableVertexAttribArray(location); public static void DisableVertexAttribArray(int location) => _disableVertexAttribArray!(location);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void VertexAttribPointer(int location, int size, GLEnum type, bool normalized, int stride, int offset) => public static void VertexAttribPointer(int location, int size, GLEnum type, bool normalized, int stride, int offset) =>
_vertexAttribPointer(location, size, type, normalized, stride, (IntPtr)offset); _vertexAttribPointer!(location, size, type, normalized, stride, (IntPtr)offset);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void VertexAttribIPointer(int location, int size, GLEnum type, int stride, int offset) => public static void VertexAttribIPointer(int location, int size, GLEnum type, int stride, int offset) =>
_vertexAttribIPointer(location, size, type, stride, (IntPtr)offset); _vertexAttribIPointer!(location, size, type, stride, (IntPtr)offset);
} }
} }

View File

@@ -2,7 +2,7 @@ using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace Quik.OpenGL namespace Dashboard.OpenGL
{ {
public delegate IntPtr GetProcAddressProc(string procName); public delegate IntPtr GetProcAddressProc(string procName);
@@ -23,25 +23,25 @@ namespace Quik.OpenGL
private const short AggressiveInlining = (short)MethodImplOptions.AggressiveInlining; private const short AggressiveInlining = (short)MethodImplOptions.AggressiveInlining;
private static GetProcAddressProc _getProcAddress; private static GetProcAddressProc? _getProcAddress;
private static GLEnum1Proc _enable; private static GLEnum1Proc? _enable;
private static GLEnum1Proc _disable; private static GLEnum1Proc? _disable;
private static GLEnum2Proc _blendFunc; private static GLEnum2Proc? _blendFunc;
private static GLEnum1Proc _depthFunc; private static GLEnum1Proc? _depthFunc;
private static GLEnum1Proc _clear; private static GLEnum1Proc? _clear;
private static GLI4Proc _viewport; private static GLI4Proc? _viewport;
private static GLI4Proc _scissor; private static GLI4Proc? _scissor;
private static GLF4Proc _clearColor; private static GLF4Proc? _clearColor;
private static DrawElementsProc _drawElements; private static DrawElementsProc? _drawElements;
private static DrawArraysProc _drawArrays; private static DrawArraysProc? _drawArrays;
private static GetIntegervProc _getIntegerv; private static GetIntegervProc? _getIntegerv;
private static GetFloatvProc _getFloatv; private static GetFloatvProc? _getFloatv;
private static GetStringProc _getString; private static GetStringProc? _getString;
private static T GetProcAddress<T>(string procName) private static T GetProcAddress<T>(string procName)
where T : Delegate where T : Delegate
{ {
IntPtr funcptr = _getProcAddress(procName); IntPtr funcptr = _getProcAddress!(procName);
return Marshal.GetDelegateForFunctionPointer<T>(funcptr); return Marshal.GetDelegateForFunctionPointer<T>(funcptr);
} }
@@ -72,27 +72,27 @@ namespace Quik.OpenGL
} }
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void Enable(GLEnum cap) => _enable(cap); public static void Enable(GLEnum cap) => _enable!(cap);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void Disable(GLEnum cap) => _disable(cap); public static void Disable(GLEnum cap) => _disable!(cap);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void BlendFunc(GLEnum src, GLEnum dst) => _blendFunc(src, dst); public static void BlendFunc(GLEnum src, GLEnum dst) => _blendFunc!(src, dst);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void DepthFunc(GLEnum func) => _depthFunc(func); public static void DepthFunc(GLEnum func) => _depthFunc!(func);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void Clear(GLEnum buffer_bits) => _clear(buffer_bits); public static void Clear(GLEnum buffer_bits) => _clear!(buffer_bits);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void Viewport(int x, int y, int w, int h) => _viewport(x, y, w, h); public static void Viewport(int x, int y, int w, int h) => _viewport!(x, y, w, h);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void Scissor(int x, int y, int w, int h) => _scissor(x, y, w, h); public static void Scissor(int x, int y, int w, int h) => _scissor!(x, y, w, h);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void ClearColor(float r, float g, float b, float a) => _clearColor(r, g, b, a); public static void ClearColor(float r, float g, float b, float a) => _clearColor!(r, g, b, a);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void DrawElements(GLEnum primitive, int count, GLEnum type, int offset) => _drawElements(primitive, count, type, (void*)offset); public static void DrawElements(GLEnum primitive, int count, GLEnum type, int offset) => _drawElements!(primitive, count, type, (void*)offset);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void DrawArrays(GLEnum primitive, int offset, int count) => _drawArrays(primitive, offset, count); public static void DrawArrays(GLEnum primitive, int offset, int count) => _drawArrays!(primitive, offset, count);
[MethodImpl(AggressiveInlining)] [MethodImpl(AggressiveInlining)]
public static void Get(GLEnum pname, out int value) public static void Get(GLEnum pname, out int value)
@@ -100,7 +100,7 @@ namespace Quik.OpenGL
value = default; value = default;
fixed(int* ptr = &value) fixed(int* ptr = &value)
{ {
_getIntegerv(pname, ptr); _getIntegerv!(pname, ptr);
} }
} }
@@ -110,7 +110,7 @@ namespace Quik.OpenGL
value = default; value = default;
fixed (float* ptr = &value) fixed (float* ptr = &value)
{ {
_getFloatv(pname, ptr); _getFloatv!(pname, ptr);
} }
} }
@@ -118,7 +118,7 @@ namespace Quik.OpenGL
public static string GetString(GLEnum pname) public static string GetString(GLEnum pname)
{ {
int length; int length;
byte* str = _getString(pname); byte* str = _getString!(pname);
for (length = 0; str[length] == 0 || length < 256; length++); for (length = 0; str[length] == 0 || length < 256; length++);

View File

@@ -1,13 +1,13 @@
using System; using System;
using System.IO; using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
using Quik.VertexGenerator; using Dashboard.VertexGenerator;
using static Quik.OpenGL.GLEnum; using static Dashboard.OpenGL.GLEnum;
using Quik.Media; using Dashboard.Media;
using System.Linq; using System.Linq;
using System.Diagnostics; using System.Diagnostics;
namespace Quik.OpenGL namespace Dashboard.OpenGL
{ {
public class GL21Driver : IDisposable public class GL21Driver : IDisposable
{ {
@@ -31,7 +31,7 @@ namespace Quik.OpenGL
private readonly TextureManager textures = new TextureManager(); private readonly TextureManager textures = new TextureManager();
public bool IsInit { get; private set; } = false; public bool IsInit { get; private set; } = false;
public event Action<GL21Driver> OnGCDispose; public event Action<GL21Driver>? OnGCDispose;
public GL21Driver() public GL21Driver()
{ {
@@ -46,8 +46,8 @@ namespace Quik.OpenGL
{ {
if (IsInit) return; if (IsInit) return;
int vs = CreateShader(GL_VERTEX_SHADER, "Quik.res.gl21.vert"); int vs = CreateShader(GL_VERTEX_SHADER, "Dashboard.res.gl21.vert");
int fs = CreateShader(GL_FRAGMENT_SHADER, "Quik.res.gl21.frag"); int fs = CreateShader(GL_FRAGMENT_SHADER, "Dashboard.res.gl21.frag");
program = GL.CreateProgram(); program = GL.CreateProgram();
GL.AttachShader(program, vs); GL.AttachShader(program, vs);
@@ -91,7 +91,7 @@ namespace Quik.OpenGL
{ {
AssertInit(); AssertInit();
if (!data.TryGetValue(queue, out DrawData draw)) if (!data.TryGetValue(queue, out DrawData? draw))
{ {
draw = new DrawData(this, queue); draw = new DrawData(this, queue);
data.Add(queue, draw); data.Add(queue, draw);
@@ -112,14 +112,16 @@ namespace Quik.OpenGL
GL.Enable(GL_BLEND); GL.Enable(GL_BLEND);
GL.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GL.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GL.Enable(GL_SCISSOR_TEST); GL.Enable(GL_SCISSOR_TEST);
GL.Enable(GL_DEPTH_TEST);
GL.DepthFunc(GL_LESS);
foreach (DrawCall call in queue) foreach (DrawCall call in queue)
{ {
GL.Scissor( GL.Scissor(
(int)MathF.Round(call.Bounds.Left), (int)MathF.Round(call.Bounds.Min.X),
(int)MathF.Round(view.Bottom - call.Bounds.Bottom), (int)MathF.Round(size.Y - call.Bounds.Max.Y),
(int)MathF.Round(call.Bounds.Right), (int)MathF.Round(call.Bounds.Size.X),
(int)MathF.Round(view.Bottom - call.Bounds.Top)); (int)MathF.Round(call.Bounds.Size.Y));
QMat4.Translation(out QMat4 modelMatrix, call.Bounds.Min.X, call.Bounds.Min.Y, 0); QMat4.Translation(out QMat4 modelMatrix, call.Bounds.Min.X, call.Bounds.Min.Y, 0);
QMat4 modelView = viewMatrix * modelMatrix; QMat4 modelView = viewMatrix * modelMatrix;
GL.UniformMatrix4(m4Transforms, false, in modelView); GL.UniformMatrix4(m4Transforms, false, in modelView);
@@ -151,13 +153,17 @@ namespace Quik.OpenGL
GL.DrawElements(GL_TRIANGLES, call.Count, GL_UNSIGNED_INT, sizeof(int)*call.Start); GL.DrawElements(GL_TRIANGLES, call.Count, GL_UNSIGNED_INT, sizeof(int)*call.Start);
} }
GL.Disable(GL_SCISSOR_TEST);
GL.Disable(GL_DEPTH_TEST);
GL.Disable(GL_BLEND);
} }
public void ClearDrawQueue(DrawQueue queue) public void ClearDrawQueue(DrawQueue queue)
{ {
AssertInit(); AssertInit();
if (!data.TryGetValue(queue, out DrawData draw)) if (!data.TryGetValue(queue, out DrawData? draw))
return; return;
draw.Dispose(); draw.Dispose();
data.Remove(queue); data.Remove(queue);
@@ -165,7 +171,7 @@ namespace Quik.OpenGL
private static int CreateShader(GLEnum type, string name) private static int CreateShader(GLEnum type, string name)
{ {
StreamReader source = new StreamReader(typeof(GL21Driver).Assembly.GetManifestResourceStream(name)); StreamReader source = new StreamReader(typeof(GL21Driver).Assembly.GetManifestResourceStream(name) ?? throw new Exception("Resource not found."));
string text = source.ReadToEnd(); string text = source.ReadToEnd();
source.Dispose(); source.Dispose();

View File

@@ -1,4 +1,4 @@
namespace Quik.OpenGL namespace Dashboard.OpenGL
{ {
public enum GLEnum : int public enum GLEnum : int
{ {
@@ -21,6 +21,7 @@ namespace Quik.OpenGL
GL_BLEND = 0x0BE2, GL_BLEND = 0x0BE2,
GL_COLOR_BUFFER_BIT = 0x00004000, GL_COLOR_BUFFER_BIT = 0x00004000,
GL_DEPTH_BUFFER_BIT = 0x00000100,
GL_SRC_ALPHA = 0x0302, GL_SRC_ALPHA = 0x0302,
GL_ONE_MINUS_SRC_ALPHA = 0x0303, GL_ONE_MINUS_SRC_ALPHA = 0x0303,
@@ -81,9 +82,13 @@ namespace Quik.OpenGL
GL_TRIANGLES = 0x0004, GL_TRIANGLES = 0x0004,
GL_SCISSOR_TEST = 0x0C11, GL_SCISSOR_TEST = 0x0C11,
GL_DEPTH_TEST = 0x0B71,
GL_TEXTURE_SWIZZLE_R = 0x8E42, GL_TEXTURE_SWIZZLE_R = 0x8E42,
GL_TEXTURE_SWIZZLE_G = 0x8E43, GL_TEXTURE_SWIZZLE_G = 0x8E43,
GL_TEXTURE_SWIZZLE_B = 0x8E44, GL_TEXTURE_SWIZZLE_B = 0x8E44,
GL_TEXTURE_SWIZZLE_A = 0x8E45 GL_TEXTURE_SWIZZLE_A = 0x8E45,
GL_LESS = 0x0201,
} }
} }

View File

@@ -1,7 +1,7 @@
using System; using System;
using static Quik.OpenGL.GLEnum; using static Dashboard.OpenGL.GLEnum;
namespace Quik.OpenGL namespace Dashboard.OpenGL
{ {
[System.Serializable] [System.Serializable]
public class GraphicsException : System.Exception public class GraphicsException : System.Exception

View File

@@ -1,20 +1,20 @@
using Quik.CommandMachine; using Dashboard.CommandMachine;
using Quik.Controls; using Dashboard.Controls;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Quik.PAL namespace Dashboard.PAL
{ {
/// <summary> /// <summary>
/// An abstraction layer over the UI input and output. /// An abstraction layer over the UI input and output.
/// </summary> /// </summary>
public class QuikPort public class Dash
{ {
private readonly IQuikPortHandle handle; private readonly IDashHandle handle;
private readonly IQuikPlatform platform; private readonly IDashboardPlatform platform;
public string Title public string Title
{ {
@@ -34,7 +34,7 @@ namespace Quik.PAL
set => platform.PortSetPosition(handle, value); set => platform.PortSetPosition(handle, value);
} }
public UIBase UIElement { get; set; } public UIBase? UIElement { get; set; }
public bool IsValid => platform.PortIsValid(handle); public bool IsValid => platform.PortIsValid(handle);
@@ -50,7 +50,7 @@ namespace Quik.PAL
} }
} }
public QuikPort(IQuikPlatform platform) public Dash(IDashboardPlatform platform)
{ {
this.platform = platform; this.platform = platform;
handle = platform.CreatePort(); handle = platform.CreatePort();
@@ -70,13 +70,12 @@ namespace Quik.PAL
platform.PortFocus(handle); platform.PortFocus(handle);
} }
public void Paint(CommandList list = null) public void Paint(CommandList? list = null)
{ {
if (UIElement == null) if (UIElement == null)
return; return;
if(list == null) list ??= new CommandList();
list = new CommandList();
list.Clear(); list.Clear();
UIElement.Bounds = new QRectangle(Size, new QVec2(0,0)); UIElement.Bounds = new QRectangle(Size, new QVec2(0,0));

View File

@@ -0,0 +1,61 @@
using System;
using Dashboard.CommandMachine;
using Dashboard.Media;
namespace Dashboard.PAL
{
/// <summary>
/// An empty interface to statically type Quik port handles.
/// </summary>
public interface IDashHandle
{
}
/// <summary>
/// The primary primary platform abstraction interface for dashboard hosts.
/// </summary>
public interface IDashboardPlatform : IDisposable
{
/// <summary>
/// The title of the application.
/// </summary>
string? Title { get; set; }
/// <summary>
/// The default icon for the application.
/// </summary>
QImage? Icon { get; set; }
/// <summary>
/// The event raised when an event is received.
/// </summary>
event EventHandler? EventRaised;
/// <summary>
/// Raise the events that have been enqueued.
/// </summary>
/// <param name="block">True to block until a new event arrives.</param>
void ProcessEvents(bool block);
/// <summary>
/// Create a window.
/// </summary>
/// <returns>The window instance.</returns>
IDashHandle CreatePort();
void DestroyPort(IDashHandle port);
string PortGetTitle(IDashHandle port);
void PortSetTitle(IDashHandle port, string title);
QVec2 PortGetSize(IDashHandle port);
void PortSetSize(IDashHandle port, QVec2 size);
QVec2 PortGetPosition(IDashHandle port);
void PortSetPosition(IDashHandle port, QVec2 position);
bool PortIsValid(IDashHandle port);
void PortSubscribeEvent(IDashHandle port, EventHandler handler);
void PortUnsubscribeEvent(IDashHandle port, EventHandler handler);
void PortFocus(IDashHandle port);
void PortShow(IDashHandle port, bool shown = true);
void PortPaint(IDashHandle port, CommandList commands);
void GetMaximumImage(out int width, out int height);
void GetMaximumImage(out int width, out int height, out int depth);
}
}

View File

@@ -1,9 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using Quik.Media.Font; using Dashboard.Media.Font;
namespace Quik.PAL namespace Dashboard.PAL
{ {
/// <summary> /// <summary>
/// Flags that effect font search criterea. /// Flags that effect font search criterea.

View File

@@ -0,0 +1,12 @@
using System.Diagnostics.CodeAnalysis;
using System.IO;
using Dashboard.Media;
namespace Dashboard.PAL
{
public interface IFontFactory
{
bool TryOpen(Stream stream, [NotNullWhen(true)] out QFont font);
}
}

View File

@@ -1,27 +1,28 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Quik.CommandMachine; using System.Threading;
using Quik.Controls; using Dashboard.CommandMachine;
using Quik.Media; using Dashboard.Controls;
using Quik.PAL; using Dashboard.Media;
using Quik.Typography; using Dashboard.PAL;
using Dashboard.Typography;
namespace Quik namespace Dashboard
{ {
/// <summary> /// <summary>
/// Main class for Quik applications. /// Main class for Quik applications.
/// </summary> /// </summary>
public class QuikApplication public class DashboardApplication
{ {
/// <summary> /// <summary>
/// The application platform driver. /// The application platform driver.
/// </summary> /// </summary>
public IQuikPlatform Platform { get; } public IDashboardPlatform Platform { get; }
/// <summary> /// <summary>
/// Title of the application. /// Title of the application.
/// </summary> /// </summary>
public string Title public string? Title
{ {
get => Platform.Title; get => Platform.Title;
set => Platform.Title = value; set => Platform.Title = value;
@@ -30,13 +31,13 @@ namespace Quik
/// <summary> /// <summary>
/// Application icon. /// Application icon.
/// </summary> /// </summary>
public QImage Icon public QImage? Icon
{ {
get => Platform.Icon; get => Platform.Icon;
set => Platform.Icon = value; set => Platform.Icon = value;
} }
public QuikPort MainPort { get; private set; } = null; public PAL.Dash? MainPort { get; private set; } = null;
public FontProvider FontProvider { get; } public FontProvider FontProvider { get; }
@@ -45,16 +46,16 @@ namespace Quik
/// </summary> /// </summary>
public List<MediaLoader> MediaLoaders { get; } = new List<MediaLoader>(); public List<MediaLoader> MediaLoaders { get; } = new List<MediaLoader>();
public QuikApplication(IQuikPlatform platform) public DashboardApplication(IDashboardPlatform platform)
{ {
Platform = platform; Platform = platform;
FontProvider = new FontProvider(this); FontProvider = new FontProvider(this);
Current = this; Current = this;
} }
public IDisposable GetMedia(object key, MediaHint hint) public IDisposable? GetMedia(object key, MediaHint hint)
{ {
IDisposable disposable = null; IDisposable? disposable = null;
foreach (MediaLoader loader in MediaLoaders) foreach (MediaLoader loader in MediaLoaders)
{ {
@@ -67,9 +68,9 @@ namespace Quik
return disposable; return disposable;
} }
public IDisposable GetMedia<T>(T key, MediaHint hint) public IDisposable? GetMedia<T>(T key, MediaHint hint)
{ {
IDisposable disposable = null; IDisposable? disposable = null;
foreach (MediaLoader loader in MediaLoaders) foreach (MediaLoader loader in MediaLoaders)
{ {
@@ -85,27 +86,46 @@ namespace Quik
return disposable; return disposable;
} }
public void Run(View mainView) private CommandList cmd = new CommandList();
public void Run(View mainView, bool yield = true)
{ {
MainPort = new QuikPort(Platform) { UIElement = mainView }; Init(mainView);
CommandList cmd = new CommandList();
MainPort.EventRaised += (sender, ea) => mainView.NotifyEvent(sender, ea); while (RunSync())
while (MainPort.IsValid)
{ {
Platform.ProcessEvents(false); if (yield)
if (MainPort.IsValid)
{ {
cmd.Clear(); Thread.Yield();
MainPort.Paint(cmd);
} }
} }
} }
public static QuikApplication Current { get; private set; } public void Init(View mainView)
{
MainPort = new PAL.Dash(Platform) { UIElement = mainView };
MainPort.EventRaised += (sender, ea) => mainView.NotifyEvent(sender, ea);
}
public static void SetCurrentApplication(QuikApplication application) public bool RunSync()
{
if (!MainPort!.IsValid)
return false;
Platform.ProcessEvents(false);
if (MainPort.IsValid)
{
cmd.Clear();
MainPort.Paint(cmd);
}
return true;
}
public static DashboardApplication Current { get; private set; } = null!;
public static void SetCurrentApplication(DashboardApplication application)
{ {
Current = application; Current = application;
} }

View File

@@ -2,7 +2,7 @@ using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Diagnostics; using System.Diagnostics;
namespace Quik namespace Dashboard
{ {
/// <summary> /// <summary>
/// A 2 dimensional Vector. /// A 2 dimensional Vector.
@@ -66,7 +66,7 @@ namespace Quik
public static bool operator !=(QVec2 a, QVec2 b) => a.X != b.X || a.Y != b.Y; public static bool operator !=(QVec2 a, QVec2 b) => a.X != b.X || a.Y != b.Y;
public override bool Equals(object obj) public override bool Equals(object? obj)
{ {
if (obj is QVec2) if (obj is QVec2)
{ {

View File

@@ -1,9 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Quik.Media; using Dashboard.Media;
using Quik.Media.Font; using Dashboard.Media.Font;
namespace Quik namespace Dashboard
{ {
public enum TextAlignment public enum TextAlignment
{ {
@@ -53,7 +53,7 @@ namespace Quik
public abstract class StyleBase public abstract class StyleBase
{ {
public abstract object this[string key] { get; set; } public abstract object? this[string key] { get; set; }
public QColor? Color public QColor? Color
{ {
@@ -109,9 +109,9 @@ namespace Quik
set => this["list-marker-position"] = value; set => this["list-marker-position"] = value;
} }
public QImage ListMarkerImage public QImage? ListMarkerImage
{ {
get => (QImage)this["list-marker-image"]; get => (QImage?)this["list-marker-image"];
set => this["list-marker-image"] = value; set => this["list-marker-image"] = value;
} }
@@ -127,9 +127,9 @@ namespace Quik
set => this["stroke-color"] = value; set => this["stroke-color"] = value;
} }
public FontFace Font public FontFace? Font
{ {
get => (FontFace)this["font"]; get => (FontFace?)this["font"];
set => this["font"] = value; set => this["font"] = value;
} }
@@ -144,9 +144,9 @@ namespace Quik
{ {
private readonly Dictionary<string, object> _keys = new Dictionary<string, object>(); private readonly Dictionary<string, object> _keys = new Dictionary<string, object>();
public override object this[string styleKey] public override object? this[string styleKey]
{ {
get => _keys.TryGetValue(styleKey, out object value) ? value : null; get => _keys.TryGetValue(styleKey, out object? value) ? value : null;
set set
{ {
if (value == null) if (value == null)
@@ -163,11 +163,11 @@ namespace Quik
public Style BaseStyle { get; } public Style BaseStyle { get; }
public override object this[string key] public override object? this[string key]
{ {
get get
{ {
object value = null; object? value = null;
for (int i = _styles.Count; i != 0 && value == null; i--) for (int i = _styles.Count; i != 0 && value == null; i--)
{ {

View File

@@ -0,0 +1,108 @@
using Dashboard.Media;
using Dashboard.Media.Font;
using Dashboard.PAL;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
namespace Dashboard.Typography
{
/// <summary>
/// The font provider is a caching object that provides fonts for typesetting classes.
/// </summary>
public class FontProvider : IDisposable
{
private Dictionary<FontFace, QFont> Fonts { get; } = new Dictionary<FontFace, QFont>();
private HashSet<QFont> UsedFonts { get; } = new HashSet<QFont>();
public readonly FontRasterizerOptions RasterizerOptions;
public IFontDataBase? Database { get; set; }
public IFontFactory? FontFactory { get; set; }
private readonly DashboardApplication App;
public QFont this[FontFace info]
{
get
{
if (!Fonts.TryGetValue(info, out QFont? font))
{
using Stream str = Database?.Open(info) ?? throw new Exception("Font could not be found.");
if (FontFactory?.TryOpen(str, out font) ?? false)
{
Fonts.Add(info, font);
}
else
{
throw new Exception("Font not found.");
}
}
UsedFonts.Add(font);
return font;
}
}
public QFont this[SystemFontFamily family]
{
get
{
return this[Database?.GetSystemFontFace(family) ?? throw new Exception("No font database.")];
}
}
public FontProvider(DashboardApplication app, in FontRasterizerOptions options)
{
RasterizerOptions = options;
App = app;
Type? fdb = Type.GetType("Quik.Media.Defaults.FontDataBaseProvider, Quik.Media.Defaults");
if (fdb != null)
{
PropertyInfo? instanceProperty = fdb.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.GetProperty);
if (instanceProperty != null)
{
Database = (IFontDataBase)instanceProperty.GetValue(null)!;
}
}
Type? ffact = Type.GetType("Quik.Media.Defaults.FreeTypeFontFactory, Quik.Media.Defaults");
if (ffact != null)
{
ConstructorInfo? ctor = ffact.GetConstructor(Array.Empty<Type>());
FontFactory = (IFontFactory?)ctor?.Invoke(null);
}
}
public FontProvider(DashboardApplication app)
: this(app, FontRasterizerOptions.Default)
{
}
/// <summary>
/// Tracks the use of fonts used by this typesetter and removes any that haven't been referenced since the last cycle.
/// </summary>
public void Collect()
{
// foreach (FontJar jar in Fonts.Values.ToArray())
// {
// if (!UsedFonts.Contains(jar))
// {
// Fonts.Remove(jar.Info);
// }
// }
// UsedFonts.Clear();
}
private bool isDisposed = false;
public void Dispose()
{
if (isDisposed) return;
isDisposed = true;
foreach (QFont font in Fonts.Values)
{
font.Dispose();
}
}
}
}

View File

@@ -3,9 +3,9 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Text; using System.Text;
using Quik.Media; using Dashboard.Media;
namespace Quik.Typography namespace Dashboard.Typography
{ {
/// <summary> /// <summary>
/// An atomic horizontal block of text which cannot be further divided. /// An atomic horizontal block of text which cannot be further divided.

View File

@@ -1,12 +1,10 @@
using Quik.CommandMachine; using Dashboard.CommandMachine;
using Quik.Media; using Dashboard.Media;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks;
namespace Quik.Typography namespace Dashboard.Typography
{ {
public static class Typesetter public static class Typesetter
{ {
@@ -76,10 +74,38 @@ namespace Quik.Typography
} }
} }
public static void TypesetHorizontalDirect(this CommandList list, string str, QVec2 origin, float size, QFont font) public static QVec2 MeasureHorizontal(ReadOnlySpan<char> str, float size, QFont font)
{
var enumerator = new LineEnumerator(str);
float width = 0.0f;
float height = 0.0f;
while (enumerator.MoveNext())
{
ReadOnlySpan<char> line = enumerator.Current;
float lineHeight = 0.0f;
foreach (Rune r in line.EnumerateRunes())
{
int codepoint = r.Value;
font.Get(codepoint, size, out FontGlyph glyph);
width += glyph.Metrics.Advance.X;
lineHeight = Math.Max(lineHeight, glyph.Metrics.Size.Y);
}
height += lineHeight;
}
return new QVec2(width, height);
}
public static void TypesetHorizontalDirect(this CommandList list, ReadOnlySpan<char> str, QVec2 origin, float size, QFont font)
{ {
Dictionary<QImage, FontDrawInfo> drawInfo = new Dictionary<QImage, FontDrawInfo>(); Dictionary<QImage, FontDrawInfo> drawInfo = new Dictionary<QImage, FontDrawInfo>();
var enumerator = new LineEnumerator(str.AsSpan()); var enumerator = new LineEnumerator(str);
QVec2 pen = origin; QVec2 pen = origin;
while (enumerator.MoveNext()) while (enumerator.MoveNext())
@@ -109,7 +135,7 @@ namespace Quik.Typography
font.Get(codepoint, size, out FontGlyph glyph); font.Get(codepoint, size, out FontGlyph glyph);
ref readonly QGlyphMetrics metrics = ref glyph.Metrics; ref readonly QGlyphMetrics metrics = ref glyph.Metrics;
QImage image = glyph.Image; QImage? image = glyph.Image;
if (image == null) if (image == null)
{ {

View File

@@ -1,7 +1,7 @@
using System; using System;
using System.Text; using System.Text;
namespace Quik.Typography namespace Dashboard.Typography
{ {
public static class UnicodeUtil public static class UnicodeUtil
{ {

View File

@@ -1,10 +1,10 @@
using Quik.Media; using Dashboard.Media;
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace Quik.VertexGenerator namespace Dashboard.VertexGenerator
{ {
public class DrawQueue : IEnumerable<DrawCall> public class DrawQueue : IEnumerable<DrawCall>
{ {
@@ -14,7 +14,7 @@ namespace Quik.VertexGenerator
private int _start; private int _start;
private int _baseOffset; private int _baseOffset;
private QRectangle _bounds; private QRectangle _bounds;
private QImage _texture; private QImage? _texture;
public int ZDepth { get; private set; } public int ZDepth { get; private set; }
public QuikVertex[] VertexArray => _vertices.InternalArray; public QuikVertex[] VertexArray => _vertices.InternalArray;
@@ -33,7 +33,7 @@ namespace Quik.VertexGenerator
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void StartDrawCall(in QRectangle bounds, QImage texture, int baseOffset) public void StartDrawCall(in QRectangle bounds, QImage? texture, int baseOffset)
{ {
_start = ElementCount; _start = ElementCount;
_texture = texture; _texture = texture;
@@ -100,9 +100,9 @@ namespace Quik.VertexGenerator
public int Start { get; } public int Start { get; }
public int Count { get; } public int Count { get; }
public QRectangle Bounds { get; } public QRectangle Bounds { get; }
public QImage Texture { get; } public QImage? Texture { get; }
public DrawCall(int start, int count, in QRectangle bounds, QImage texture) public DrawCall(int start, int count, in QRectangle bounds, QImage? texture)
{ {
Start = start; Start = start;
Count = count; Count = count;

View File

@@ -1,6 +1,6 @@
using System.Diagnostics; using System.Diagnostics;
namespace Quik.VertexGenerator namespace Dashboard.VertexGenerator
{ {
/// <summary> /// <summary>
/// Represents a GPU vertex. /// Represents a GPU vertex.

View File

@@ -1,6 +1,6 @@
using System; using System;
namespace Quik.VertexGenerator namespace Dashboard.VertexGenerator
{ {
/// <summary> /// <summary>
/// A small list which whose items can be used by reference. /// A small list which whose items can be used by reference.

View File

@@ -1,10 +1,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Quik.CommandMachine; using Dashboard.CommandMachine;
using Quik.Media; using Dashboard.Media;
using Quik.Typography; using Dashboard.Typography;
namespace Quik.VertexGenerator namespace Dashboard.VertexGenerator
{ {
public class VertexGeneratorEngine : CommandEngine public class VertexGeneratorEngine : CommandEngine
{ {

View File

@@ -1,84 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.9.34701.34
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Quik", "Quik\Quik.csproj", "{B86B2B99-DAE4-43CE-A040-1D8E143B94A7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Quik.OpenTK", "Quik.OpenTK\Quik.OpenTK.csproj", "{586E5E28-1D07-4CC2-B04F-0BC420564F57}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{AE05ADE5-A809-479F-97D5-BEAFE7604285}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QuikDemo", "tests\QuikDemo\QuikDemo.csproj", "{79CBF97F-4884-4692-94FB-75DDEB61E26F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Quik.Media.Defaults", "Quik.Media.Defaults\Quik.Media.Defaults.csproj", "{B517D2BF-CB9D-4448-BE50-EA85E100EB47}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B86B2B99-DAE4-43CE-A040-1D8E143B94A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B86B2B99-DAE4-43CE-A040-1D8E143B94A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B86B2B99-DAE4-43CE-A040-1D8E143B94A7}.Debug|x64.ActiveCfg = Debug|Any CPU
{B86B2B99-DAE4-43CE-A040-1D8E143B94A7}.Debug|x64.Build.0 = Debug|Any CPU
{B86B2B99-DAE4-43CE-A040-1D8E143B94A7}.Debug|x86.ActiveCfg = Debug|Any CPU
{B86B2B99-DAE4-43CE-A040-1D8E143B94A7}.Debug|x86.Build.0 = Debug|Any CPU
{B86B2B99-DAE4-43CE-A040-1D8E143B94A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B86B2B99-DAE4-43CE-A040-1D8E143B94A7}.Release|Any CPU.Build.0 = Release|Any CPU
{B86B2B99-DAE4-43CE-A040-1D8E143B94A7}.Release|x64.ActiveCfg = Release|Any CPU
{B86B2B99-DAE4-43CE-A040-1D8E143B94A7}.Release|x64.Build.0 = Release|Any CPU
{B86B2B99-DAE4-43CE-A040-1D8E143B94A7}.Release|x86.ActiveCfg = Release|Any CPU
{B86B2B99-DAE4-43CE-A040-1D8E143B94A7}.Release|x86.Build.0 = Release|Any CPU
{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Debug|Any CPU.Build.0 = Debug|Any CPU
{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Debug|x64.ActiveCfg = Debug|Any CPU
{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Debug|x64.Build.0 = Debug|Any CPU
{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Debug|x86.ActiveCfg = Debug|Any CPU
{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Debug|x86.Build.0 = Debug|Any CPU
{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Release|Any CPU.ActiveCfg = Release|Any CPU
{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Release|Any CPU.Build.0 = Release|Any CPU
{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Release|x64.ActiveCfg = Release|Any CPU
{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Release|x64.Build.0 = Release|Any CPU
{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Release|x86.ActiveCfg = Release|Any CPU
{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Release|x86.Build.0 = Release|Any CPU
{79CBF97F-4884-4692-94FB-75DDEB61E26F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{79CBF97F-4884-4692-94FB-75DDEB61E26F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{79CBF97F-4884-4692-94FB-75DDEB61E26F}.Debug|x64.ActiveCfg = Debug|Any CPU
{79CBF97F-4884-4692-94FB-75DDEB61E26F}.Debug|x64.Build.0 = Debug|Any CPU
{79CBF97F-4884-4692-94FB-75DDEB61E26F}.Debug|x86.ActiveCfg = Debug|Any CPU
{79CBF97F-4884-4692-94FB-75DDEB61E26F}.Debug|x86.Build.0 = Debug|Any CPU
{79CBF97F-4884-4692-94FB-75DDEB61E26F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{79CBF97F-4884-4692-94FB-75DDEB61E26F}.Release|Any CPU.Build.0 = Release|Any CPU
{79CBF97F-4884-4692-94FB-75DDEB61E26F}.Release|x64.ActiveCfg = Release|Any CPU
{79CBF97F-4884-4692-94FB-75DDEB61E26F}.Release|x64.Build.0 = Release|Any CPU
{79CBF97F-4884-4692-94FB-75DDEB61E26F}.Release|x86.ActiveCfg = Release|Any CPU
{79CBF97F-4884-4692-94FB-75DDEB61E26F}.Release|x86.Build.0 = Release|Any CPU
{B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Debug|x64.ActiveCfg = Debug|Any CPU
{B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Debug|x64.Build.0 = Debug|Any CPU
{B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Debug|x86.ActiveCfg = Debug|Any CPU
{B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Debug|x86.Build.0 = Debug|Any CPU
{B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Release|Any CPU.Build.0 = Release|Any CPU
{B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Release|x64.ActiveCfg = Release|Any CPU
{B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Release|x64.Build.0 = Release|Any CPU
{B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Release|x86.ActiveCfg = Release|Any CPU
{B517D2BF-CB9D-4448-BE50-EA85E100EB47}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{79CBF97F-4884-4692-94FB-75DDEB61E26F} = {AE05ADE5-A809-479F-97D5-BEAFE7604285}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {EF011093-DA56-4E14-B2AB-D565B64F73E1}
EndGlobalSection
EndGlobal

View File

@@ -1,17 +0,0 @@
namespace Quik.CommandMachine
{
public enum FrameType
{
None,
Command,
IVec1,
IVec2,
IVec3,
IVec4,
Vec1,
Vec2,
Vec3,
Vec4,
Object,
}
}

View File

@@ -1,67 +0,0 @@
using System;
using Quik.CommandMachine;
namespace Quik.Controls
{
public abstract class Control : UIBase
{
private readonly CommandList drawCommands = new CommandList();
public Style Style { get; set; } = new Style();
public float Padding
{
get => (float)(Style["padding"] ?? 0.0f);
set => Style["padding"] = value;
}
public bool IsVisualsValid { get; private set; }
public void InvalidateVisual()
{
IsVisualsValid = false;
OnVisualsInvalidated(this, EventArgs.Empty);
}
protected abstract void ValidateVisual(CommandList cmd);
protected override void PaintBegin(CommandList cmd)
{
base.PaintBegin(cmd);
if (!IsVisualsValid)
{
ValidateVisual(drawCommands);
OnVisualsValidated(this, EventArgs.Empty);
IsVisualsValid = true;
}
cmd.PushStyle(Style);
cmd.PushViewport();
cmd.StoreViewport(AbsoluteBounds);
cmd.Splice(drawCommands);
cmd.PopViewport();
cmd.PopStyle();
}
public event EventHandler StyleChanged;
public event EventHandler VisualsInvalidated;
public event EventHandler VisualsValidated;
protected virtual void OnStyleChanged(object sender, EventArgs ea)
{
StyleChanged?.Invoke(sender, ea);
InvalidateVisual();
}
protected virtual void OnVisualsInvalidated(object sender, EventArgs ea)
{
VisualsInvalidated?.Invoke(sender, ea);
}
protected virtual void OnVisualsValidated(object sender, EventArgs ea)
{
VisualsValidated?.Invoke(sender, ea);
}
}
}

View File

@@ -1,21 +0,0 @@
using Quik.CommandMachine;
using Quik.Media;
using Quik.Typography;
namespace Quik.Controls
{
public class Label : Control
{
public string Text { get; set; }
public QFont TextFont { get; set; }
public float TextSize { get; set; }
protected override void ValidateVisual(CommandList cmd)
{
float padding = Padding;
QVec2 origin = new QVec2(padding, padding);
cmd.TypesetHorizontalDirect(Text, origin, TextSize, TextFont);
}
}
}

View File

@@ -1,65 +0,0 @@
using System;
using Quik.CommandMachine;
namespace Quik.Controls
{
/// <summary>
/// Bases for all UI elements.
/// </summary>
public abstract class UIBase
{
public UIBase Parent { get; protected set; }
public string Id { get; set; }
public QRectangle Bounds { get; set; }
public QVec2 Position
{
get => Bounds.Min;
set => Bounds = new QRectangle(Bounds.Max - Bounds.Min + value, value);
}
public QVec2 Size
{
get => Bounds.Max - Bounds.Min;
set => Bounds = new QRectangle(value + Bounds.Min, Bounds.Min);
}
public QRectangle AbsoluteBounds
{
get
{
if (Parent == null)
{
return Bounds;
}
else
{
return new QRectangle(Bounds.Max + Parent.Position, Bounds.Min + Parent.Position);
}
}
}
public void NotifyEvent(object sender, EventArgs args)
{
}
protected virtual void PaintBegin(CommandList cmd)
{
cmd.PushViewport();
cmd.StoreViewport(AbsoluteBounds);
cmd.PushZ();
}
protected virtual void PaintEnd(CommandList cmd)
{
cmd.PopViewport();
}
public void Paint(CommandList cmd)
{
PaintBegin(cmd);
PaintEnd(cmd);
}
}
}

View File

@@ -1,61 +0,0 @@
using System;
using Quik.CommandMachine;
using Quik.Media;
namespace Quik.PAL
{
/// <summary>
/// An empty interface to statically type Quik port handles.
/// </summary>
public interface IQuikPortHandle
{
}
/// <summary>
/// The primary primary platform abstraction interface for Quik hosts.
/// </summary>
public interface IQuikPlatform : IDisposable
{
/// <summary>
/// The title of the application.
/// </summary>
string Title { get; set; }
/// <summary>
/// The default icon for the application.
/// </summary>
QImage Icon { get; set; }
/// <summary>
/// The event raised when an event is received.
/// </summary>
event EventHandler EventRaised;
/// <summary>
/// Raise the events that have been enqueued.
/// </summary>
/// <param name="block">True to block until a new event arrives.</param>
void ProcessEvents(bool block);
/// <summary>
/// Create a window.
/// </summary>
/// <returns>The window instance.</returns>
IQuikPortHandle CreatePort();
void DestroyPort(IQuikPortHandle port);
string PortGetTitle(IQuikPortHandle port);
void PortSetTitle(IQuikPortHandle port, string title);
QVec2 PortGetSize(IQuikPortHandle port);
void PortSetSize(IQuikPortHandle port, QVec2 size);
QVec2 PortGetPosition(IQuikPortHandle port);
void PortSetPosition(IQuikPortHandle port, QVec2 position);
bool PortIsValid(IQuikPortHandle port);
void PortSubscribeEvent(IQuikPortHandle port, EventHandler handler);
void PortUnsubscribeEvent(IQuikPortHandle port, EventHandler handler);
void PortFocus(IQuikPortHandle port);
void PortShow(IQuikPortHandle port, bool shown = true);
void PortPaint(IQuikPortHandle port, CommandList commands);
void GetMaximumImage(out int width, out int height);
void GetMaximumImage(out int width, out int height, out int depth);
}
}

View File

@@ -1,71 +0,0 @@
using Quik.Media;
using Quik.Media.Font;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Quik.Typography
{
/// <summary>
/// The font provider is a caching object that provides fonts for typesetting classes.
/// </summary>
public class FontProvider : IDisposable
{
private Dictionary<FontFace, QFont> Fonts { get; } = new Dictionary<FontFace, QFont>();
private HashSet<QFont> UsedFonts { get; } = new HashSet<QFont>();
public readonly FontRasterizerOptions RasterizerOptions;
private readonly QuikApplication App;
public QFont this[FontFace info]
{
get
{
if (!Fonts.TryGetValue(info, out QFont font))
{
font = (QFont)App.GetMedia(info, MediaHint.Font);
Fonts[info] = font;
}
UsedFonts.Add(font);
return font;
}
}
public FontProvider(QuikApplication app, in FontRasterizerOptions options)
{
RasterizerOptions = options;
App = app;
}
public FontProvider(QuikApplication app)
: this(app, FontRasterizerOptions.Default)
{
}
/// <summary>
/// Tracks the use of fonts used by this typesetter and removes any that haven't been referenced since the last cycle.
/// </summary>
public void Collect()
{
// foreach (FontJar jar in Fonts.Values.ToArray())
// {
// if (!UsedFonts.Contains(jar))
// {
// Fonts.Remove(jar.Info);
// }
// }
// UsedFonts.Clear();
}
private bool isDisposed = false;
public void Dispose()
{
if (isDisposed) return;
isDisposed = true;
foreach (QFont font in Fonts.Values)
{
font.Dispose();
}
}
}
}

View File

@@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\Quik\Quik.csproj" /> <ProjectReference Include="..\..\Dashboard\Dashboard.csproj" />
<ProjectReference Include="..\..\Quik.Media.Defaults\Quik.Media.Defaults.csproj" /> <ProjectReference Include="..\..\Dashboard.Media.Defaults\Dashboard.Media.Defaults.csproj" />
<ProjectReference Include="..\..\Quik.OpenTK\Quik.OpenTK.csproj" /> <ProjectReference Include="..\..\Dashboard.OpenTK\Dashboard.OpenTK.csproj" />
</ItemGroup> </ItemGroup>
<PropertyGroup> <PropertyGroup>

View File

@@ -1,16 +1,16 @@
using Quik; using Dashboard;
using Quik.CommandMachine; using Dashboard.CommandMachine;
using Quik.Controls; using Dashboard.Controls;
using Quik.OpenTK; using Dashboard.OpenTK;
using Quik.Media.Defaults; using Dashboard.Media.Defaults;
using Quik.Media; using Dashboard.Media;
using Quik.PAL; using Dashboard.PAL;
namespace QuikDemo namespace Dashboard.Demo
{ {
public static class Program public static class Program
{ {
public static readonly QuikApplication Application = new QuikApplication(new OpenTKPlatform()); public static readonly DashboardApplication Application = new DashboardApplication(new OpenTKPlatform());
public static void Main(string[] args) public static void Main(string[] args)
{ {
@@ -20,8 +20,8 @@ namespace QuikDemo
public class EmptyView : View public class EmptyView : View
{ {
private QFont font; private QFont? font;
private readonly Label Label = new Label() { Text = "Hello world!", Size = new QVec2(256, 32), Position = new QVec2(300, 300) }; private readonly Label Label = new Label() { Text = "Hello world!", Position = new QVec2(300, 300) };
protected override void PaintBegin(CommandList cmd) protected override void PaintBegin(CommandList cmd)
{ {
@@ -32,8 +32,8 @@ namespace QuikDemo
IFontDataBase db = FontDataBaseProvider.Instance; IFontDataBase db = FontDataBaseProvider.Instance;
font = new QFontFreeType(db.FontFileInfo(db.Sans).OpenRead()); font = new QFontFreeType(db.FontFileInfo(db.Sans).OpenRead());
Label.TextFont = font; Label.Font = font;
Label.TextSize = 16; Label.TextSize = 12;
Label.InvalidateVisual(); Label.InvalidateVisual();
} }