diff --git a/.idea/.idea.Nerfed/.idea/vcs.xml b/.idea/.idea.Nerfed/.idea/vcs.xml index 3886124..ee62db1 100644 --- a/.idea/.idea.Nerfed/.idea/vcs.xml +++ b/.idea/.idea.Nerfed/.idea/vcs.xml @@ -3,6 +3,7 @@ + diff --git a/Nerfed.Builder/Builder/BuildArgs.cs b/Nerfed.Builder/Builder/BuildArgs.cs index f9a8580..0a74bfc 100644 --- a/Nerfed.Builder/Builder/BuildArgs.cs +++ b/Nerfed.Builder/Builder/BuildArgs.cs @@ -5,12 +5,15 @@ public class BuildArgs [Argument("-build")] public bool Build { get; set; } - [Argument("-projectPath")] - public string ProjectPath { get; set; } + [Argument("-resourcePath")] + public string ResourcePath { get; set; } + + [Argument("-resourceOutPath")] + public string ResourceOutPath { get; set; } [Argument("-platform")] public string Platform { get; set; } - [Argument("-content")] - public List ContentFiles { get; set; } + [Argument("-resourceFiles")] + public List ResourceFiles { get; set; } } diff --git a/Nerfed.Builder/Builder/Builder.cs b/Nerfed.Builder/Builder/Builder.cs index 292e26f..cee3206 100644 --- a/Nerfed.Builder/Builder/Builder.cs +++ b/Nerfed.Builder/Builder/Builder.cs @@ -11,13 +11,12 @@ public Builder() { rawFileImporter = new RawFileImporter(); - ShaderImporter shaderImporter = new ShaderImporter(); - importers.Add(".vert", shaderImporter); // Vertex shader - importers.Add(".frag", shaderImporter); // Fragment shader - importers.Add(".tesc", shaderImporter); // Tessellation control shader - importers.Add(".tese", shaderImporter); // Tessellation evaluation shader - importers.Add(".geom", shaderImporter); // Geometry shader - importers.Add(".comp", shaderImporter); // Compute shader + importers.Add(".vert", new ShaderImporter(ShaderStage.Vertex)); // Vertex shader + importers.Add(".frag", new ShaderImporter(ShaderStage.Fragment)); // Fragment shader + //importers.Add(".tesc", shaderImporter); // Tessellation control shader + //importers.Add(".tese", shaderImporter); // Tessellation evaluation shader + //importers.Add(".geom", shaderImporter); // Geometry shader + //importers.Add(".comp", shaderImporter); // Compute shader } public void Run(BuildArgs args) @@ -25,22 +24,19 @@ public void Run(BuildArgs args) Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); - CopyLibs(args.ProjectPath); + //CopyLibs(args.ResourcePath); - List contentFiles = args.ContentFiles; - string absContentPath = $"{args.ProjectPath}/{PathUtil.ContentFolderName}"; + List contentFiles = args.ResourceFiles; // If no files are provided, build all content. - if (args.ContentFiles == null) + if (args.ResourceFiles == null) { contentFiles = []; - CollectAssetFiles(absContentPath, absContentPath, ref contentFiles); + CollectAssetFiles(args.ResourcePath, args.ResourcePath, ref contentFiles); } if (contentFiles.Count > 0) { - string importPath = $"{args.ProjectPath}/{PathUtil.ImportFolderName}"; - ParallelOptions parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = contentFiles.Count @@ -50,7 +46,7 @@ public void Run(BuildArgs args) { try { - string inFile = $"{args.ProjectPath}/{PathUtil.ContentFolderName}/{relativeFile}"; + string inFile = $"{args.ResourcePath}/{relativeFile}"; if (!File.Exists(inFile)) { @@ -58,7 +54,7 @@ public void Run(BuildArgs args) return; } - string outFile = $"{importPath}/{relativeFile}{PathUtil.ImportedFileExtension}"; + string outFile = $"{args.ResourceOutPath}/{relativeFile}{PathUtil.ImportedFileExtension}"; FileInfo inFileInfo = new FileInfo(inFile); FileInfo outFileInfo = new FileInfo(outFile); @@ -97,7 +93,7 @@ public void Run(BuildArgs args) Console.WriteLine($"Build content completed in {stopwatch.Elapsed.TotalSeconds:F2} seconds"); } - private void CopyLibs(string projectPath) + /*private void CopyLibs(string projectPath) { string libDir = $"{AppDomain.CurrentDomain.BaseDirectory}/../../Native/"; if (OperatingSystem.IsWindows()) @@ -123,17 +119,12 @@ private void CopyLibs(string projectPath) FileUtil.Copy(srcFileInfo, dstFileInfo); } } - } + }*/ private void CollectAssetFiles(string assetDir, string dir, ref List files) { foreach (string file in Directory.EnumerateFiles(dir)) { - if (Path.GetExtension(file).Equals(PathUtil.ImportFileExtension, StringComparison.CurrentCultureIgnoreCase)) - { - continue; - } - string relativeFile = file.Substring(assetDir.Length, file.Length - assetDir.Length); if (relativeFile[0] == Path.DirectorySeparatorChar || relativeFile[0] == Path.AltDirectorySeparatorChar) { diff --git a/Nerfed.Builder/Builder/Importers/ShaderImporter.cs b/Nerfed.Builder/Builder/Importers/ShaderImporter.cs index fbaa887..a7910f0 100644 --- a/Nerfed.Builder/Builder/Importers/ShaderImporter.cs +++ b/Nerfed.Builder/Builder/Importers/ShaderImporter.cs @@ -1,33 +1,157 @@ -using System.Diagnostics; +using Vortice.ShaderCompiler; +using Vortice.SPIRV.Reflect; namespace Nerfed.Builder; +// Values should match the ShaderStage enum in the runtime. +public enum ShaderStage +{ + Vertex, + Fragment +} + +// Values should match the ShaderFormat enum in the runtime. +public enum ShaderFormat +{ + Invalid, + SPIRV, + HLSL, + DXBC, + DXIL, + MSL, + METALLIB, + SECRET +} + public class ShaderImporter : IImporter { - public void Import(string inFile, string outFile) + private readonly ShaderStage shaderStage; + + public ShaderImporter(ShaderStage shaderStage) { - using (Process proc = new Process()) + this.shaderStage = shaderStage; + } + + public unsafe void Import(string inFile, string outFile) + { + string name = Path.GetFileNameWithoutExtension(inFile); + string nameWithExt = Path.GetFileName(inFile); + + // Compile the shader. + Result compileResult; + using (Compiler compiler = new Compiler()) { - string glslc; - if (OperatingSystem.IsWindows()) + string shaderSource = File.ReadAllText(inFile); + compileResult = compiler.Compile(shaderSource, nameWithExt, ToShaderKind(shaderStage)); + } + + if (compileResult.Status != CompilationStatus.Success) + { + Console.Error.WriteLine($"Failed to compile {nameWithExt}\n{compileResult.ErrorMessage}"); + return; + } + + if (compileResult.ErrorsCount > 0 || compileResult.WarningsCount > 0) + { + Console.Error.WriteLine(compileResult.ErrorMessage); + } + + Span byteCode = compileResult.GetBytecode(); + + // Inspect SPIR-V bytecode for information which the runtime requires to create a shader resource. + SpvReflectShaderModule module = new SpvReflectShaderModule(); + if (!CheckReflectResult(SPIRVReflectApi.spvReflectCreateShaderModule(byteCode, &module), name)) + { + return; + } + + uint descriptorSetCount = 0; + if (!CheckReflectResult(SPIRVReflectApi.spvReflectEnumerateDescriptorSets(&module, &descriptorSetCount, null), name)) + { + return; + } + + int uniformBufferCount = 0; + int storageBufferCount = 0; + int storageTextureCount = 0; + int samplerCount = 0; + + if (descriptorSetCount > 0) + { + SpvReflectDescriptorSet* descriptorSets = stackalloc SpvReflectDescriptorSet[(int)descriptorSetCount]; + if (!CheckReflectResult( + SPIRVReflectApi.spvReflectEnumerateDescriptorSets(&module, &descriptorSetCount, &descriptorSets), + name + )) { - glslc = "Win64/glslc.exe"; - } - else if (OperatingSystem.IsLinux()) - { - glslc = "Linux/glslc"; - } - else - { - throw new PlatformNotSupportedException("No shader compiler found for current platform"); + return; } - proc.StartInfo.FileName = glslc; - proc.StartInfo.Arguments = @$"""{inFile}"" -o ""{outFile}"" -c"; - proc.StartInfo.CreateNoWindow = true; - proc.StartInfo.UseShellExecute = false; - proc.Start(); - proc.WaitForExit(); + for (int i = 0; i < descriptorSetCount; i++) + { + SpvReflectDescriptorSet set = descriptorSets[i]; + for (int j = 0; j < set.binding_count; j++) + { + SpvReflectDescriptorBinding binding = *set.bindings[j]; + if (binding.descriptor_type == SpvReflectDescriptorType.UniformBuffer) + { + uniformBufferCount++; + } + else if (binding.descriptor_type == SpvReflectDescriptorType.StorageBuffer) + { + storageBufferCount++; + } + else if (binding.descriptor_type == SpvReflectDescriptorType.StorageTexelBuffer) + { + storageTextureCount++; + } + else if (binding.descriptor_type == SpvReflectDescriptorType.Sampler || + binding.descriptor_type == SpvReflectDescriptorType.CombinedImageSampler) + { + samplerCount++; + } + } + } + } + + //TODO: Convert SPIR-V to other bytecode formats here (DX/Consoles). + ShaderFormat format = ShaderFormat.SPIRV; + + // Write shader meta-data and bytecode to the output file. + using (FileStream stream = new FileStream(outFile, FileMode.Create, FileAccess.Write)) + { + using (BinaryWriter writer = new BinaryWriter(stream)) + { + writer.Write((int)format); + writer.Write((int)shaderStage); + writer.Write(uniformBufferCount); + writer.Write(storageBufferCount); + writer.Write(storageTextureCount); + writer.Write(samplerCount); + writer.Write(byteCode.Length); + writer.Write(byteCode); + } + } + } + + private bool CheckReflectResult(SpvReflectResult result, string name) + { + if (result != SpvReflectResult.Success) + { + Console.Error.WriteLine($"SpirV-Reflect failure for '{name}': {result}"); + return false; + } + + return true; + } + + private ShaderKind ToShaderKind(ShaderStage shaderStage) + { + switch (shaderStage) + { + case ShaderStage.Vertex: return ShaderKind.VertexShader; + case ShaderStage.Fragment: return ShaderKind.FragmentShader; + default: throw new ArgumentOutOfRangeException(nameof(shaderStage)); } } } diff --git a/Nerfed.Builder/Nerfed.Builder.csproj b/Nerfed.Builder/Nerfed.Builder.csproj index 15c7be9..e8fd134 100644 --- a/Nerfed.Builder/Nerfed.Builder.csproj +++ b/Nerfed.Builder/Nerfed.Builder.csproj @@ -12,14 +12,22 @@ + true true + true true + true + + + + + diff --git a/Nerfed.Builder/PathUtil.cs b/Nerfed.Builder/PathUtil.cs index 98129e5..880cfe2 100644 --- a/Nerfed.Builder/PathUtil.cs +++ b/Nerfed.Builder/PathUtil.cs @@ -3,8 +3,4 @@ namespace Nerfed.Builder; public static class PathUtil { public const string ImportedFileExtension = ".bin"; - public const string BuildFolderName = ".build"; - public const string ImportFileExtension = ".import"; - public const string ImportFolderName = $"{BuildFolderName}/Import"; - public const string ContentFolderName = "Content"; } diff --git a/Nerfed.Editor/Nerfed.Editor.csproj b/Nerfed.Editor/Nerfed.Editor.csproj index fe96bfe..3e76714 100644 --- a/Nerfed.Editor/Nerfed.Editor.csproj +++ b/Nerfed.Editor/Nerfed.Editor.csproj @@ -27,4 +27,8 @@ + + + + \ No newline at end of file diff --git a/Nerfed.Editor/Resources/Shaders/Fullscreen.vert b/Nerfed.Editor/Resources/Shaders/Fullscreen.vert new file mode 100644 index 0000000..447e258 --- /dev/null +++ b/Nerfed.Editor/Resources/Shaders/Fullscreen.vert @@ -0,0 +1,9 @@ +#version 450 + +layout(location = 0) out vec2 outTexCoord; + +void main() +{ + outTexCoord = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2); + gl_Position = vec4(outTexCoord * vec2(2.0, -2.0) + vec2(-1.0, 1.0), 0.0, 1.0); +} diff --git a/Nerfed.Runtime/Content/Shaders/imgui-frag.glsl b/Nerfed.Editor/Resources/Shaders/ImGui.frag similarity index 100% rename from Nerfed.Runtime/Content/Shaders/imgui-frag.glsl rename to Nerfed.Editor/Resources/Shaders/ImGui.frag diff --git a/Nerfed.Runtime/Content/Shaders/imgui-vertex.glsl b/Nerfed.Editor/Resources/Shaders/ImGui.vert similarity index 100% rename from Nerfed.Runtime/Content/Shaders/imgui-vertex.glsl rename to Nerfed.Editor/Resources/Shaders/ImGui.vert diff --git a/Nerfed.Editor/Resources/Shaders/Text.frag b/Nerfed.Editor/Resources/Shaders/Text.frag new file mode 100644 index 0000000..e3a5f55 --- /dev/null +++ b/Nerfed.Editor/Resources/Shaders/Text.frag @@ -0,0 +1,34 @@ +#version 450 + +layout(location = 0) in vec2 inTexCoord; +layout(location = 1) in vec4 inColor; + +layout(location = 0) out vec4 outColor; + +layout(set = 2, binding = 0) uniform sampler2D msdf; + +layout(set = 3, binding = 0) uniform UBO +{ + float pxRange; +} ubo; + +float median(float r, float g, float b) +{ + return max(min(r, g), min(max(r, g), b)); +} + +float screenPxRange() +{ + vec2 unitRange = vec2(ubo.pxRange)/vec2(textureSize(msdf, 0)); + vec2 screenTexSize = vec2(1.0)/fwidth(inTexCoord); + return max(0.5*dot(unitRange, screenTexSize), 1.0); +} + +void main() +{ + vec3 msd = texture(msdf, inTexCoord).rgb; + float sd = median(msd.r, msd.g, msd.b); + float screenPxDistance = screenPxRange() * (sd - 0.5); + float opacity = clamp(screenPxDistance + 0.5, 0.0, 1.0); + outColor = mix(vec4(0.0, 0.0, 0.0, 0.0), inColor, opacity); +} diff --git a/Nerfed.Editor/Resources/Shaders/Text.vert b/Nerfed.Editor/Resources/Shaders/Text.vert new file mode 100644 index 0000000..42f7827 --- /dev/null +++ b/Nerfed.Editor/Resources/Shaders/Text.vert @@ -0,0 +1,20 @@ +#version 450 + +layout(location = 0) in vec3 inPos; +layout(location = 1) in vec2 inTexCoord; +layout(location = 2) in vec4 inColor; + +layout(location = 0) out vec2 outTexCoord; +layout(location = 1) out vec4 outColor; + +layout(set = 1, binding = 0) uniform UBO +{ + mat4 ViewProjection; +} ubo; + +void main() +{ + gl_Position = ubo.ViewProjection * vec4(inPos, 1.0); + outTexCoord = inTexCoord; + outColor = inColor; +} diff --git a/Nerfed.Editor/Resources/Shaders/Video.frag b/Nerfed.Editor/Resources/Shaders/Video.frag new file mode 100644 index 0000000..d0d5510 --- /dev/null +++ b/Nerfed.Editor/Resources/Shaders/Video.frag @@ -0,0 +1,38 @@ +/* + * This effect is based on the YUV-to-RGBA GLSL shader found in SDL. + * Thus, it also released under the zlib license: + * http://libsdl.org/license.php + */ +#version 450 + +layout(location = 0) in vec2 TexCoord; + +layout(location = 0) out vec4 FragColor; + +layout(set = 2, binding = 0) uniform sampler2D YSampler; +layout(set = 2, binding = 1) uniform sampler2D USampler; +layout(set = 2, binding = 2) uniform sampler2D VSampler; + +/* More info about colorspace conversion: + * http://www.equasys.de/colorconversion.html + * http://www.equasys.de/colorformat.html + */ + +const vec3 offset = vec3(-0.0625, -0.5, -0.5); +const vec3 Rcoeff = vec3(1.164, 0.000, 1.793); +const vec3 Gcoeff = vec3(1.164, -0.213, -0.533); +const vec3 Bcoeff = vec3(1.164, 2.112, 0.000); + +void main() +{ + vec3 yuv; + yuv.x = texture(YSampler, TexCoord).r; + yuv.y = texture(USampler, TexCoord).r; + yuv.z = texture(VSampler, TexCoord).r; + yuv += offset; + + FragColor.r = dot(yuv, Rcoeff); + FragColor.g = dot(yuv, Gcoeff); + FragColor.b = dot(yuv, Bcoeff); + FragColor.a = 1.0; +} diff --git a/Nerfed.Runtime/Content/Shaders/generate-spirv.bat b/Nerfed.Runtime/Content/Shaders/generate-spirv.bat deleted file mode 100644 index 62d1d99..0000000 --- a/Nerfed.Runtime/Content/Shaders/generate-spirv.bat +++ /dev/null @@ -1,2 +0,0 @@ -glslangvalidator -V imgui-vertex.glsl -o imgui-vertex.spv -S vert -glslangvalidator -V imgui-frag.glsl -o imgui-frag.spv -S frag diff --git a/Nerfed.Runtime/Content/Shaders/imgui-frag.spv b/Nerfed.Runtime/Content/Shaders/imgui-frag.spv deleted file mode 100644 index 550f9a0..0000000 Binary files a/Nerfed.Runtime/Content/Shaders/imgui-frag.spv and /dev/null differ diff --git a/Nerfed.Runtime/Content/Shaders/imgui-vertex.spv b/Nerfed.Runtime/Content/Shaders/imgui-vertex.spv deleted file mode 100644 index a63373f..0000000 Binary files a/Nerfed.Runtime/Content/Shaders/imgui-vertex.spv and /dev/null differ diff --git a/Nerfed.Runtime/Engine.cs b/Nerfed.Runtime/Engine.cs index 7dd741e..80f114e 100644 --- a/Nerfed.Runtime/Engine.cs +++ b/Nerfed.Runtime/Engine.cs @@ -61,6 +61,7 @@ public static void Run(string[] args) } GraphicsDevice = new GraphicsDevice(BackendFlags.All); + GraphicsDevice.LoadDefaultPipelines(); MainWindow = new Window(GraphicsDevice, new WindowCreateInfo(WindowTitle, WindowWidth, WindowHeight, ScreenMode.Windowed)); if (!GraphicsDevice.ClaimWindow(MainWindow, SwapchainComposition.SDR, VSync ? PresentMode.VSync : PresentMode.Mailbox)) diff --git a/Nerfed.Runtime/Graphics/EmbeddedShadersSpirV.cs b/Nerfed.Runtime/Graphics/EmbeddedShadersSpirV.cs deleted file mode 100644 index 567fe09..0000000 --- a/Nerfed.Runtime/Graphics/EmbeddedShadersSpirV.cs +++ /dev/null @@ -1,716 +0,0 @@ -namespace Nerfed.Runtime.Graphics; - -internal class EmbeddedShadersSpirV : IEmbeddedShaders -{ - public ShaderFormat ShaderFormat => ShaderFormat.SPIRV; - - public byte[] FullscreenVert { get; } = - [ - 0x3, 0x2, 0x23, 0x7, 0x0, 0x0, 0x1, 0x0, 0xB, 0x0, - 0x8, 0x0, 0x2E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x11, 0x0, 0x2, 0x0, 0x1, 0x0, 0x0, 0x0, 0xB, 0x0, - 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x47, 0x4C, 0x53, 0x4C, - 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30, 0x0, 0x0, - 0x0, 0x0, 0xE, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0xF, 0x0, 0x8, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x6D, 0x61, 0x69, 0x6E, - 0x0, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0xC, 0x0, - 0x0, 0x0, 0x1D, 0x0, 0x0, 0x0, 0x3, 0x0, 0x3, 0x0, - 0x2, 0x0, 0x0, 0x0, 0xC2, 0x1, 0x0, 0x0, 0x5, 0x0, - 0x4, 0x0, 0x4, 0x0, 0x0, 0x0, 0x6D, 0x61, 0x69, 0x6E, - 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x5, 0x0, 0x9, 0x0, - 0x0, 0x0, 0x6F, 0x75, 0x74, 0x54, 0x65, 0x78, 0x43, 0x6F, - 0x6F, 0x72, 0x64, 0x0, 0x5, 0x0, 0x6, 0x0, 0xC, 0x0, - 0x0, 0x0, 0x67, 0x6C, 0x5F, 0x56, 0x65, 0x72, 0x74, 0x65, - 0x78, 0x49, 0x6E, 0x64, 0x65, 0x78, 0x0, 0x0, 0x5, 0x0, - 0x6, 0x0, 0x1B, 0x0, 0x0, 0x0, 0x67, 0x6C, 0x5F, 0x50, - 0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x0, 0x0, - 0x0, 0x0, 0x6, 0x0, 0x6, 0x0, 0x1B, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x67, 0x6C, 0x5F, 0x50, 0x6F, 0x73, - 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x0, 0x6, 0x0, 0x7, 0x0, - 0x1B, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x67, 0x6C, - 0x5F, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x53, 0x69, 0x7A, 0x65, - 0x0, 0x0, 0x0, 0x0, 0x6, 0x0, 0x7, 0x0, 0x1B, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x67, 0x6C, 0x5F, 0x43, - 0x6C, 0x69, 0x70, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6E, 0x63, - 0x65, 0x0, 0x6, 0x0, 0x7, 0x0, 0x1B, 0x0, 0x0, 0x0, - 0x3, 0x0, 0x0, 0x0, 0x67, 0x6C, 0x5F, 0x43, 0x75, 0x6C, - 0x6C, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x0, - 0x5, 0x0, 0x3, 0x0, 0x1D, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x47, 0x0, 0x4, 0x0, 0x9, 0x0, 0x0, 0x0, - 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x47, 0x0, - 0x4, 0x0, 0xC, 0x0, 0x0, 0x0, 0xB, 0x0, 0x0, 0x0, - 0x2A, 0x0, 0x0, 0x0, 0x48, 0x0, 0x5, 0x0, 0x1B, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xB, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x48, 0x0, 0x5, 0x0, 0x1B, 0x0, - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0xB, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x48, 0x0, 0x5, 0x0, 0x1B, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0xB, 0x0, 0x0, 0x0, - 0x3, 0x0, 0x0, 0x0, 0x48, 0x0, 0x5, 0x0, 0x1B, 0x0, - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0xB, 0x0, 0x0, 0x0, - 0x4, 0x0, 0x0, 0x0, 0x47, 0x0, 0x3, 0x0, 0x1B, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x13, 0x0, 0x2, 0x0, - 0x2, 0x0, 0x0, 0x0, 0x21, 0x0, 0x3, 0x0, 0x3, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x16, 0x0, 0x3, 0x0, - 0x6, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x17, 0x0, - 0x4, 0x0, 0x7, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x2, 0x0, 0x0, 0x0, 0x20, 0x0, 0x4, 0x0, 0x8, 0x0, - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, - 0x3B, 0x0, 0x4, 0x0, 0x8, 0x0, 0x0, 0x0, 0x9, 0x0, - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x15, 0x0, 0x4, 0x0, - 0xA, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, 0x20, 0x0, 0x4, 0x0, 0xB, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0xA, 0x0, 0x0, 0x0, 0x3B, 0x0, - 0x4, 0x0, 0xB, 0x0, 0x0, 0x0, 0xC, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x2B, 0x0, 0x4, 0x0, 0xA, 0x0, - 0x0, 0x0, 0xE, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x2B, 0x0, 0x4, 0x0, 0xA, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x17, 0x0, 0x4, 0x0, - 0x17, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x4, 0x0, - 0x0, 0x0, 0x15, 0x0, 0x4, 0x0, 0x18, 0x0, 0x0, 0x0, - 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2B, 0x0, - 0x4, 0x0, 0x18, 0x0, 0x0, 0x0, 0x19, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x1C, 0x0, 0x4, 0x0, 0x1A, 0x0, - 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x19, 0x0, 0x0, 0x0, - 0x1E, 0x0, 0x6, 0x0, 0x1B, 0x0, 0x0, 0x0, 0x17, 0x0, - 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x1A, 0x0, 0x0, 0x0, - 0x1A, 0x0, 0x0, 0x0, 0x20, 0x0, 0x4, 0x0, 0x1C, 0x0, - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x1B, 0x0, 0x0, 0x0, - 0x3B, 0x0, 0x4, 0x0, 0x1C, 0x0, 0x0, 0x0, 0x1D, 0x0, - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x2B, 0x0, 0x4, 0x0, - 0xA, 0x0, 0x0, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2B, 0x0, 0x4, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x2B, 0x0, - 0x4, 0x0, 0x6, 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xC0, 0x2C, 0x0, 0x5, 0x0, 0x7, 0x0, - 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x21, 0x0, 0x0, 0x0, 0x2B, 0x0, 0x4, 0x0, 0x6, 0x0, - 0x0, 0x0, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0xBF, - 0x2B, 0x0, 0x4, 0x0, 0x6, 0x0, 0x0, 0x0, 0x25, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x80, 0x3F, 0x2C, 0x0, 0x5, 0x0, - 0x7, 0x0, 0x0, 0x0, 0x26, 0x0, 0x0, 0x0, 0x24, 0x0, - 0x0, 0x0, 0x25, 0x0, 0x0, 0x0, 0x2B, 0x0, 0x4, 0x0, - 0x6, 0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x20, 0x0, 0x4, 0x0, 0x2C, 0x0, 0x0, 0x0, - 0x3, 0x0, 0x0, 0x0, 0x17, 0x0, 0x0, 0x0, 0x36, 0x0, - 0x5, 0x0, 0x2, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0xF8, 0x0, - 0x2, 0x0, 0x5, 0x0, 0x0, 0x0, 0x3D, 0x0, 0x4, 0x0, - 0xA, 0x0, 0x0, 0x0, 0xD, 0x0, 0x0, 0x0, 0xC, 0x0, - 0x0, 0x0, 0xC4, 0x0, 0x5, 0x0, 0xA, 0x0, 0x0, 0x0, - 0xF, 0x0, 0x0, 0x0, 0xD, 0x0, 0x0, 0x0, 0xE, 0x0, - 0x0, 0x0, 0xC7, 0x0, 0x5, 0x0, 0xA, 0x0, 0x0, 0x0, - 0x11, 0x0, 0x0, 0x0, 0xF, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, 0x6F, 0x0, 0x4, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x12, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x3D, 0x0, - 0x4, 0x0, 0xA, 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, 0x0, - 0xC, 0x0, 0x0, 0x0, 0xC7, 0x0, 0x5, 0x0, 0xA, 0x0, - 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, 0x0, - 0x10, 0x0, 0x0, 0x0, 0x6F, 0x0, 0x4, 0x0, 0x6, 0x0, - 0x0, 0x0, 0x15, 0x0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, - 0x50, 0x0, 0x5, 0x0, 0x7, 0x0, 0x0, 0x0, 0x16, 0x0, - 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x15, 0x0, 0x0, 0x0, - 0x3E, 0x0, 0x3, 0x0, 0x9, 0x0, 0x0, 0x0, 0x16, 0x0, - 0x0, 0x0, 0x3D, 0x0, 0x4, 0x0, 0x7, 0x0, 0x0, 0x0, - 0x1F, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x85, 0x0, - 0x5, 0x0, 0x7, 0x0, 0x0, 0x0, 0x23, 0x0, 0x0, 0x0, - 0x1F, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x81, 0x0, - 0x5, 0x0, 0x7, 0x0, 0x0, 0x0, 0x27, 0x0, 0x0, 0x0, - 0x23, 0x0, 0x0, 0x0, 0x26, 0x0, 0x0, 0x0, 0x51, 0x0, - 0x5, 0x0, 0x6, 0x0, 0x0, 0x0, 0x29, 0x0, 0x0, 0x0, - 0x27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x51, 0x0, - 0x5, 0x0, 0x6, 0x0, 0x0, 0x0, 0x2A, 0x0, 0x0, 0x0, - 0x27, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x50, 0x0, - 0x7, 0x0, 0x17, 0x0, 0x0, 0x0, 0x2B, 0x0, 0x0, 0x0, - 0x29, 0x0, 0x0, 0x0, 0x2A, 0x0, 0x0, 0x0, 0x28, 0x0, - 0x0, 0x0, 0x25, 0x0, 0x0, 0x0, 0x41, 0x0, 0x5, 0x0, - 0x2C, 0x0, 0x0, 0x0, 0x2D, 0x0, 0x0, 0x0, 0x1D, 0x0, - 0x0, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x3E, 0x0, 0x3, 0x0, - 0x2D, 0x0, 0x0, 0x0, 0x2B, 0x0, 0x0, 0x0, 0xFD, 0x0, - 0x1, 0x0, 0x38, 0x0, 0x1, 0x0, - ]; - - public byte[] TextMsdfFrag { get; } = - [ - 0x3, 0x2, 0x23, 0x7, 0x0, 0x0, 0x1, 0x0, 0xB, 0x0, - 0x8, 0x0, 0x6C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x11, 0x0, 0x2, 0x0, 0x1, 0x0, 0x0, 0x0, 0x11, 0x0, - 0x2, 0x0, 0x32, 0x0, 0x0, 0x0, 0xB, 0x0, 0x6, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, - 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30, 0x0, 0x0, 0x0, 0x0, - 0xE, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, 0xF, 0x0, 0x8, 0x0, 0x4, 0x0, 0x0, 0x0, - 0x4, 0x0, 0x0, 0x0, 0x6D, 0x61, 0x69, 0x6E, 0x0, 0x0, - 0x0, 0x0, 0x36, 0x0, 0x0, 0x0, 0x64, 0x0, 0x0, 0x0, - 0x67, 0x0, 0x0, 0x0, 0x10, 0x0, 0x3, 0x0, 0x4, 0x0, - 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x3, 0x0, 0x3, 0x0, - 0x2, 0x0, 0x0, 0x0, 0xC2, 0x1, 0x0, 0x0, 0x5, 0x0, - 0x4, 0x0, 0x4, 0x0, 0x0, 0x0, 0x6D, 0x61, 0x69, 0x6E, - 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x7, 0x0, 0xC, 0x0, - 0x0, 0x0, 0x6D, 0x65, 0x64, 0x69, 0x61, 0x6E, 0x28, 0x66, - 0x31, 0x3B, 0x66, 0x31, 0x3B, 0x66, 0x31, 0x3B, 0x0, 0x0, - 0x0, 0x0, 0x5, 0x0, 0x3, 0x0, 0x9, 0x0, 0x0, 0x0, - 0x72, 0x0, 0x0, 0x0, 0x5, 0x0, 0x3, 0x0, 0xA, 0x0, - 0x0, 0x0, 0x67, 0x0, 0x0, 0x0, 0x5, 0x0, 0x3, 0x0, - 0xB, 0x0, 0x0, 0x0, 0x62, 0x0, 0x0, 0x0, 0x5, 0x0, - 0x6, 0x0, 0xF, 0x0, 0x0, 0x0, 0x73, 0x63, 0x72, 0x65, - 0x65, 0x6E, 0x50, 0x78, 0x52, 0x61, 0x6E, 0x67, 0x65, 0x28, - 0x0, 0x0, 0x5, 0x0, 0x5, 0x0, 0x1E, 0x0, 0x0, 0x0, - 0x75, 0x6E, 0x69, 0x74, 0x52, 0x61, 0x6E, 0x67, 0x65, 0x0, - 0x0, 0x0, 0x5, 0x0, 0x3, 0x0, 0x1F, 0x0, 0x0, 0x0, - 0x55, 0x42, 0x4F, 0x0, 0x6, 0x0, 0x5, 0x0, 0x1F, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x70, 0x78, 0x52, 0x61, - 0x6E, 0x67, 0x65, 0x0, 0x5, 0x0, 0x3, 0x0, 0x21, 0x0, - 0x0, 0x0, 0x75, 0x62, 0x6F, 0x0, 0x5, 0x0, 0x4, 0x0, - 0x2B, 0x0, 0x0, 0x0, 0x6D, 0x73, 0x64, 0x66, 0x0, 0x0, - 0x0, 0x0, 0x5, 0x0, 0x6, 0x0, 0x32, 0x0, 0x0, 0x0, - 0x73, 0x63, 0x72, 0x65, 0x65, 0x6E, 0x54, 0x65, 0x78, 0x53, - 0x69, 0x7A, 0x65, 0x0, 0x0, 0x0, 0x5, 0x0, 0x5, 0x0, - 0x36, 0x0, 0x0, 0x0, 0x69, 0x6E, 0x54, 0x65, 0x78, 0x43, - 0x6F, 0x6F, 0x72, 0x64, 0x0, 0x0, 0x5, 0x0, 0x3, 0x0, - 0x44, 0x0, 0x0, 0x0, 0x6D, 0x73, 0x64, 0x0, 0x5, 0x0, - 0x3, 0x0, 0x4A, 0x0, 0x0, 0x0, 0x73, 0x64, 0x0, 0x0, - 0x5, 0x0, 0x4, 0x0, 0x4B, 0x0, 0x0, 0x0, 0x70, 0x61, - 0x72, 0x61, 0x6D, 0x0, 0x0, 0x0, 0x5, 0x0, 0x4, 0x0, - 0x50, 0x0, 0x0, 0x0, 0x70, 0x61, 0x72, 0x61, 0x6D, 0x0, - 0x0, 0x0, 0x5, 0x0, 0x4, 0x0, 0x54, 0x0, 0x0, 0x0, - 0x70, 0x61, 0x72, 0x61, 0x6D, 0x0, 0x0, 0x0, 0x5, 0x0, - 0x7, 0x0, 0x59, 0x0, 0x0, 0x0, 0x73, 0x63, 0x72, 0x65, - 0x65, 0x6E, 0x50, 0x78, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6E, - 0x63, 0x65, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x4, 0x0, - 0x5E, 0x0, 0x0, 0x0, 0x6F, 0x70, 0x61, 0x63, 0x69, 0x74, - 0x79, 0x0, 0x5, 0x0, 0x5, 0x0, 0x64, 0x0, 0x0, 0x0, - 0x6F, 0x75, 0x74, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x0, 0x0, - 0x0, 0x0, 0x5, 0x0, 0x4, 0x0, 0x67, 0x0, 0x0, 0x0, - 0x69, 0x6E, 0x43, 0x6F, 0x6C, 0x6F, 0x72, 0x0, 0x48, 0x0, - 0x5, 0x0, 0x1F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x47, 0x0, - 0x3, 0x0, 0x1F, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x47, 0x0, 0x4, 0x0, 0x21, 0x0, 0x0, 0x0, 0x22, 0x0, - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x47, 0x0, 0x4, 0x0, - 0x21, 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x47, 0x0, 0x4, 0x0, 0x2B, 0x0, 0x0, 0x0, - 0x22, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x47, 0x0, - 0x4, 0x0, 0x2B, 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x47, 0x0, 0x4, 0x0, 0x36, 0x0, - 0x0, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x47, 0x0, 0x4, 0x0, 0x64, 0x0, 0x0, 0x0, 0x1E, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x47, 0x0, 0x4, 0x0, - 0x67, 0x0, 0x0, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, 0x13, 0x0, 0x2, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x21, 0x0, 0x3, 0x0, 0x3, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, 0x16, 0x0, 0x3, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x20, 0x0, 0x0, 0x0, 0x20, 0x0, 0x4, 0x0, 0x7, 0x0, - 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x21, 0x0, 0x6, 0x0, 0x8, 0x0, 0x0, 0x0, 0x6, 0x0, - 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, - 0x7, 0x0, 0x0, 0x0, 0x21, 0x0, 0x3, 0x0, 0xE, 0x0, - 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x17, 0x0, 0x4, 0x0, - 0x1C, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, 0x20, 0x0, 0x4, 0x0, 0x1D, 0x0, 0x0, 0x0, - 0x7, 0x0, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x0, 0x1E, 0x0, - 0x3, 0x0, 0x1F, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x20, 0x0, 0x4, 0x0, 0x20, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, 0x1F, 0x0, 0x0, 0x0, 0x3B, 0x0, 0x4, 0x0, - 0x20, 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, 0x15, 0x0, 0x4, 0x0, 0x22, 0x0, 0x0, 0x0, - 0x20, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2B, 0x0, - 0x4, 0x0, 0x22, 0x0, 0x0, 0x0, 0x23, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x4, 0x0, 0x24, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x19, 0x0, 0x9, 0x0, 0x28, 0x0, 0x0, 0x0, 0x6, 0x0, - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1B, 0x0, 0x3, 0x0, - 0x29, 0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x4, 0x0, 0x2A, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x29, 0x0, 0x0, 0x0, 0x3B, 0x0, 0x4, 0x0, 0x2A, 0x0, - 0x0, 0x0, 0x2B, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x17, 0x0, 0x4, 0x0, 0x2E, 0x0, 0x0, 0x0, 0x22, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x2B, 0x0, 0x4, 0x0, - 0x6, 0x0, 0x0, 0x0, 0x33, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x80, 0x3F, 0x2C, 0x0, 0x5, 0x0, 0x1C, 0x0, 0x0, 0x0, - 0x34, 0x0, 0x0, 0x0, 0x33, 0x0, 0x0, 0x0, 0x33, 0x0, - 0x0, 0x0, 0x20, 0x0, 0x4, 0x0, 0x35, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x0, 0x3B, 0x0, - 0x4, 0x0, 0x35, 0x0, 0x0, 0x0, 0x36, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x2B, 0x0, 0x4, 0x0, 0x6, 0x0, - 0x0, 0x0, 0x3A, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3F, - 0x17, 0x0, 0x4, 0x0, 0x42, 0x0, 0x0, 0x0, 0x6, 0x0, - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x20, 0x0, 0x4, 0x0, - 0x43, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x42, 0x0, - 0x0, 0x0, 0x17, 0x0, 0x4, 0x0, 0x47, 0x0, 0x0, 0x0, - 0x6, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x15, 0x0, - 0x4, 0x0, 0x4C, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x2B, 0x0, 0x4, 0x0, 0x4C, 0x0, - 0x0, 0x0, 0x4D, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2B, 0x0, 0x4, 0x0, 0x4C, 0x0, 0x0, 0x0, 0x51, 0x0, - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2B, 0x0, 0x4, 0x0, - 0x4C, 0x0, 0x0, 0x0, 0x55, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, 0x2B, 0x0, 0x4, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x61, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x4, 0x0, 0x63, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x47, 0x0, 0x0, 0x0, 0x3B, 0x0, 0x4, 0x0, 0x63, 0x0, - 0x0, 0x0, 0x64, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x2C, 0x0, 0x7, 0x0, 0x47, 0x0, 0x0, 0x0, 0x65, 0x0, - 0x0, 0x0, 0x61, 0x0, 0x0, 0x0, 0x61, 0x0, 0x0, 0x0, - 0x61, 0x0, 0x0, 0x0, 0x61, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x4, 0x0, 0x66, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x47, 0x0, 0x0, 0x0, 0x3B, 0x0, 0x4, 0x0, 0x66, 0x0, - 0x0, 0x0, 0x67, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x36, 0x0, 0x5, 0x0, 0x2, 0x0, 0x0, 0x0, 0x4, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - 0xF8, 0x0, 0x2, 0x0, 0x5, 0x0, 0x0, 0x0, 0x3B, 0x0, - 0x4, 0x0, 0x43, 0x0, 0x0, 0x0, 0x44, 0x0, 0x0, 0x0, - 0x7, 0x0, 0x0, 0x0, 0x3B, 0x0, 0x4, 0x0, 0x7, 0x0, - 0x0, 0x0, 0x4A, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, - 0x3B, 0x0, 0x4, 0x0, 0x7, 0x0, 0x0, 0x0, 0x4B, 0x0, - 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x3B, 0x0, 0x4, 0x0, - 0x7, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x7, 0x0, - 0x0, 0x0, 0x3B, 0x0, 0x4, 0x0, 0x7, 0x0, 0x0, 0x0, - 0x54, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x3B, 0x0, - 0x4, 0x0, 0x7, 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, - 0x7, 0x0, 0x0, 0x0, 0x3B, 0x0, 0x4, 0x0, 0x7, 0x0, - 0x0, 0x0, 0x5E, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, - 0x3D, 0x0, 0x4, 0x0, 0x29, 0x0, 0x0, 0x0, 0x45, 0x0, - 0x0, 0x0, 0x2B, 0x0, 0x0, 0x0, 0x3D, 0x0, 0x4, 0x0, - 0x1C, 0x0, 0x0, 0x0, 0x46, 0x0, 0x0, 0x0, 0x36, 0x0, - 0x0, 0x0, 0x57, 0x0, 0x5, 0x0, 0x47, 0x0, 0x0, 0x0, - 0x48, 0x0, 0x0, 0x0, 0x45, 0x0, 0x0, 0x0, 0x46, 0x0, - 0x0, 0x0, 0x4F, 0x0, 0x8, 0x0, 0x42, 0x0, 0x0, 0x0, - 0x49, 0x0, 0x0, 0x0, 0x48, 0x0, 0x0, 0x0, 0x48, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x2, 0x0, 0x0, 0x0, 0x3E, 0x0, 0x3, 0x0, 0x44, 0x0, - 0x0, 0x0, 0x49, 0x0, 0x0, 0x0, 0x41, 0x0, 0x5, 0x0, - 0x7, 0x0, 0x0, 0x0, 0x4E, 0x0, 0x0, 0x0, 0x44, 0x0, - 0x0, 0x0, 0x4D, 0x0, 0x0, 0x0, 0x3D, 0x0, 0x4, 0x0, - 0x6, 0x0, 0x0, 0x0, 0x4F, 0x0, 0x0, 0x0, 0x4E, 0x0, - 0x0, 0x0, 0x3E, 0x0, 0x3, 0x0, 0x4B, 0x0, 0x0, 0x0, - 0x4F, 0x0, 0x0, 0x0, 0x41, 0x0, 0x5, 0x0, 0x7, 0x0, - 0x0, 0x0, 0x52, 0x0, 0x0, 0x0, 0x44, 0x0, 0x0, 0x0, - 0x51, 0x0, 0x0, 0x0, 0x3D, 0x0, 0x4, 0x0, 0x6, 0x0, - 0x0, 0x0, 0x53, 0x0, 0x0, 0x0, 0x52, 0x0, 0x0, 0x0, - 0x3E, 0x0, 0x3, 0x0, 0x50, 0x0, 0x0, 0x0, 0x53, 0x0, - 0x0, 0x0, 0x41, 0x0, 0x5, 0x0, 0x7, 0x0, 0x0, 0x0, - 0x56, 0x0, 0x0, 0x0, 0x44, 0x0, 0x0, 0x0, 0x55, 0x0, - 0x0, 0x0, 0x3D, 0x0, 0x4, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x57, 0x0, 0x0, 0x0, 0x56, 0x0, 0x0, 0x0, 0x3E, 0x0, - 0x3, 0x0, 0x54, 0x0, 0x0, 0x0, 0x57, 0x0, 0x0, 0x0, - 0x39, 0x0, 0x7, 0x0, 0x6, 0x0, 0x0, 0x0, 0x58, 0x0, - 0x0, 0x0, 0xC, 0x0, 0x0, 0x0, 0x4B, 0x0, 0x0, 0x0, - 0x50, 0x0, 0x0, 0x0, 0x54, 0x0, 0x0, 0x0, 0x3E, 0x0, - 0x3, 0x0, 0x4A, 0x0, 0x0, 0x0, 0x58, 0x0, 0x0, 0x0, - 0x39, 0x0, 0x4, 0x0, 0x6, 0x0, 0x0, 0x0, 0x5A, 0x0, - 0x0, 0x0, 0xF, 0x0, 0x0, 0x0, 0x3D, 0x0, 0x4, 0x0, - 0x6, 0x0, 0x0, 0x0, 0x5B, 0x0, 0x0, 0x0, 0x4A, 0x0, - 0x0, 0x0, 0x83, 0x0, 0x5, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x5C, 0x0, 0x0, 0x0, 0x5B, 0x0, 0x0, 0x0, 0x3A, 0x0, - 0x0, 0x0, 0x85, 0x0, 0x5, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x5D, 0x0, 0x0, 0x0, 0x5A, 0x0, 0x0, 0x0, 0x5C, 0x0, - 0x0, 0x0, 0x3E, 0x0, 0x3, 0x0, 0x59, 0x0, 0x0, 0x0, - 0x5D, 0x0, 0x0, 0x0, 0x3D, 0x0, 0x4, 0x0, 0x6, 0x0, - 0x0, 0x0, 0x5F, 0x0, 0x0, 0x0, 0x59, 0x0, 0x0, 0x0, - 0x81, 0x0, 0x5, 0x0, 0x6, 0x0, 0x0, 0x0, 0x60, 0x0, - 0x0, 0x0, 0x5F, 0x0, 0x0, 0x0, 0x3A, 0x0, 0x0, 0x0, - 0xC, 0x0, 0x8, 0x0, 0x6, 0x0, 0x0, 0x0, 0x62, 0x0, - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x2B, 0x0, 0x0, 0x0, - 0x60, 0x0, 0x0, 0x0, 0x61, 0x0, 0x0, 0x0, 0x33, 0x0, - 0x0, 0x0, 0x3E, 0x0, 0x3, 0x0, 0x5E, 0x0, 0x0, 0x0, - 0x62, 0x0, 0x0, 0x0, 0x3D, 0x0, 0x4, 0x0, 0x47, 0x0, - 0x0, 0x0, 0x68, 0x0, 0x0, 0x0, 0x67, 0x0, 0x0, 0x0, - 0x3D, 0x0, 0x4, 0x0, 0x6, 0x0, 0x0, 0x0, 0x69, 0x0, - 0x0, 0x0, 0x5E, 0x0, 0x0, 0x0, 0x50, 0x0, 0x7, 0x0, - 0x47, 0x0, 0x0, 0x0, 0x6A, 0x0, 0x0, 0x0, 0x69, 0x0, - 0x0, 0x0, 0x69, 0x0, 0x0, 0x0, 0x69, 0x0, 0x0, 0x0, - 0x69, 0x0, 0x0, 0x0, 0xC, 0x0, 0x8, 0x0, 0x47, 0x0, - 0x0, 0x0, 0x6B, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x2E, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x0, 0x68, 0x0, - 0x0, 0x0, 0x6A, 0x0, 0x0, 0x0, 0x3E, 0x0, 0x3, 0x0, - 0x64, 0x0, 0x0, 0x0, 0x6B, 0x0, 0x0, 0x0, 0xFD, 0x0, - 0x1, 0x0, 0x38, 0x0, 0x1, 0x0, 0x36, 0x0, 0x5, 0x0, - 0x6, 0x0, 0x0, 0x0, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x37, 0x0, 0x3, 0x0, - 0x7, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x37, 0x0, - 0x3, 0x0, 0x7, 0x0, 0x0, 0x0, 0xA, 0x0, 0x0, 0x0, - 0x37, 0x0, 0x3, 0x0, 0x7, 0x0, 0x0, 0x0, 0xB, 0x0, - 0x0, 0x0, 0xF8, 0x0, 0x2, 0x0, 0xD, 0x0, 0x0, 0x0, - 0x3D, 0x0, 0x4, 0x0, 0x6, 0x0, 0x0, 0x0, 0x11, 0x0, - 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x3D, 0x0, 0x4, 0x0, - 0x6, 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0xA, 0x0, - 0x0, 0x0, 0xC, 0x0, 0x7, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x13, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x25, 0x0, - 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, - 0x3D, 0x0, 0x4, 0x0, 0x6, 0x0, 0x0, 0x0, 0x14, 0x0, - 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x3D, 0x0, 0x4, 0x0, - 0x6, 0x0, 0x0, 0x0, 0x15, 0x0, 0x0, 0x0, 0xA, 0x0, - 0x0, 0x0, 0xC, 0x0, 0x7, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x16, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x28, 0x0, - 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, 0x15, 0x0, 0x0, 0x0, - 0x3D, 0x0, 0x4, 0x0, 0x6, 0x0, 0x0, 0x0, 0x17, 0x0, - 0x0, 0x0, 0xB, 0x0, 0x0, 0x0, 0xC, 0x0, 0x7, 0x0, - 0x6, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, 0x25, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, - 0x17, 0x0, 0x0, 0x0, 0xC, 0x0, 0x7, 0x0, 0x6, 0x0, - 0x0, 0x0, 0x19, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x28, 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, 0x0, 0x18, 0x0, - 0x0, 0x0, 0xFE, 0x0, 0x2, 0x0, 0x19, 0x0, 0x0, 0x0, - 0x38, 0x0, 0x1, 0x0, 0x36, 0x0, 0x5, 0x0, 0x6, 0x0, - 0x0, 0x0, 0xF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0xE, 0x0, 0x0, 0x0, 0xF8, 0x0, 0x2, 0x0, 0x10, 0x0, - 0x0, 0x0, 0x3B, 0x0, 0x4, 0x0, 0x1D, 0x0, 0x0, 0x0, - 0x1E, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x3B, 0x0, - 0x4, 0x0, 0x1D, 0x0, 0x0, 0x0, 0x32, 0x0, 0x0, 0x0, - 0x7, 0x0, 0x0, 0x0, 0x41, 0x0, 0x5, 0x0, 0x24, 0x0, - 0x0, 0x0, 0x25, 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, - 0x23, 0x0, 0x0, 0x0, 0x3D, 0x0, 0x4, 0x0, 0x6, 0x0, - 0x0, 0x0, 0x26, 0x0, 0x0, 0x0, 0x25, 0x0, 0x0, 0x0, - 0x50, 0x0, 0x5, 0x0, 0x1C, 0x0, 0x0, 0x0, 0x27, 0x0, - 0x0, 0x0, 0x26, 0x0, 0x0, 0x0, 0x26, 0x0, 0x0, 0x0, - 0x3D, 0x0, 0x4, 0x0, 0x29, 0x0, 0x0, 0x0, 0x2C, 0x0, - 0x0, 0x0, 0x2B, 0x0, 0x0, 0x0, 0x64, 0x0, 0x4, 0x0, - 0x28, 0x0, 0x0, 0x0, 0x2D, 0x0, 0x0, 0x0, 0x2C, 0x0, - 0x0, 0x0, 0x67, 0x0, 0x5, 0x0, 0x2E, 0x0, 0x0, 0x0, - 0x2F, 0x0, 0x0, 0x0, 0x2D, 0x0, 0x0, 0x0, 0x23, 0x0, - 0x0, 0x0, 0x6F, 0x0, 0x4, 0x0, 0x1C, 0x0, 0x0, 0x0, - 0x30, 0x0, 0x0, 0x0, 0x2F, 0x0, 0x0, 0x0, 0x88, 0x0, - 0x5, 0x0, 0x1C, 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, - 0x27, 0x0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x3E, 0x0, - 0x3, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, - 0x3D, 0x0, 0x4, 0x0, 0x1C, 0x0, 0x0, 0x0, 0x37, 0x0, - 0x0, 0x0, 0x36, 0x0, 0x0, 0x0, 0xD1, 0x0, 0x4, 0x0, - 0x1C, 0x0, 0x0, 0x0, 0x38, 0x0, 0x0, 0x0, 0x37, 0x0, - 0x0, 0x0, 0x88, 0x0, 0x5, 0x0, 0x1C, 0x0, 0x0, 0x0, - 0x39, 0x0, 0x0, 0x0, 0x34, 0x0, 0x0, 0x0, 0x38, 0x0, - 0x0, 0x0, 0x3E, 0x0, 0x3, 0x0, 0x32, 0x0, 0x0, 0x0, - 0x39, 0x0, 0x0, 0x0, 0x3D, 0x0, 0x4, 0x0, 0x1C, 0x0, - 0x0, 0x0, 0x3B, 0x0, 0x0, 0x0, 0x1E, 0x0, 0x0, 0x0, - 0x3D, 0x0, 0x4, 0x0, 0x1C, 0x0, 0x0, 0x0, 0x3C, 0x0, - 0x0, 0x0, 0x32, 0x0, 0x0, 0x0, 0x94, 0x0, 0x5, 0x0, - 0x6, 0x0, 0x0, 0x0, 0x3D, 0x0, 0x0, 0x0, 0x3B, 0x0, - 0x0, 0x0, 0x3C, 0x0, 0x0, 0x0, 0x85, 0x0, 0x5, 0x0, - 0x6, 0x0, 0x0, 0x0, 0x3E, 0x0, 0x0, 0x0, 0x3A, 0x0, - 0x0, 0x0, 0x3D, 0x0, 0x0, 0x0, 0xC, 0x0, 0x7, 0x0, - 0x6, 0x0, 0x0, 0x0, 0x3F, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0x3E, 0x0, 0x0, 0x0, - 0x33, 0x0, 0x0, 0x0, 0xFE, 0x0, 0x2, 0x0, 0x3F, 0x0, - 0x0, 0x0, 0x38, 0x0, 0x1, 0x0, - ]; - - public byte[] TextTransformVert { get; } = - [ - 0x3, 0x2, 0x23, 0x7, 0x0, 0x0, 0x1, 0x0, 0xB, 0x0, - 0x8, 0x0, 0x2D, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x11, 0x0, 0x2, 0x0, 0x1, 0x0, 0x0, 0x0, 0xB, 0x0, - 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x47, 0x4C, 0x53, 0x4C, - 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30, 0x0, 0x0, - 0x0, 0x0, 0xE, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0xF, 0x0, 0xB, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x6D, 0x61, 0x69, 0x6E, - 0x0, 0x0, 0x0, 0x0, 0xD, 0x0, 0x0, 0x0, 0x19, 0x0, - 0x0, 0x0, 0x25, 0x0, 0x0, 0x0, 0x27, 0x0, 0x0, 0x0, - 0x29, 0x0, 0x0, 0x0, 0x2B, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x3, 0x0, 0x2, 0x0, 0x0, 0x0, 0xC2, 0x1, 0x0, 0x0, - 0x5, 0x0, 0x4, 0x0, 0x4, 0x0, 0x0, 0x0, 0x6D, 0x61, - 0x69, 0x6E, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x6, 0x0, - 0xB, 0x0, 0x0, 0x0, 0x67, 0x6C, 0x5F, 0x50, 0x65, 0x72, - 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x0, 0x0, 0x0, 0x0, - 0x6, 0x0, 0x6, 0x0, 0xB, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x67, 0x6C, 0x5F, 0x50, 0x6F, 0x73, 0x69, 0x74, - 0x69, 0x6F, 0x6E, 0x0, 0x6, 0x0, 0x7, 0x0, 0xB, 0x0, - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x67, 0x6C, 0x5F, 0x50, - 0x6F, 0x69, 0x6E, 0x74, 0x53, 0x69, 0x7A, 0x65, 0x0, 0x0, - 0x0, 0x0, 0x6, 0x0, 0x7, 0x0, 0xB, 0x0, 0x0, 0x0, - 0x2, 0x0, 0x0, 0x0, 0x67, 0x6C, 0x5F, 0x43, 0x6C, 0x69, - 0x70, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x0, - 0x6, 0x0, 0x7, 0x0, 0xB, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x0, 0x0, 0x67, 0x6C, 0x5F, 0x43, 0x75, 0x6C, 0x6C, 0x44, - 0x69, 0x73, 0x74, 0x61, 0x6E, 0x63, 0x65, 0x0, 0x5, 0x0, - 0x3, 0x0, 0xD, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x5, 0x0, 0x3, 0x0, 0x11, 0x0, 0x0, 0x0, 0x55, 0x42, - 0x4F, 0x0, 0x6, 0x0, 0x7, 0x0, 0x11, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, - 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x0, 0x0, - 0x5, 0x0, 0x3, 0x0, 0x13, 0x0, 0x0, 0x0, 0x75, 0x62, - 0x6F, 0x0, 0x5, 0x0, 0x4, 0x0, 0x19, 0x0, 0x0, 0x0, - 0x69, 0x6E, 0x50, 0x6F, 0x73, 0x0, 0x0, 0x0, 0x5, 0x0, - 0x5, 0x0, 0x25, 0x0, 0x0, 0x0, 0x6F, 0x75, 0x74, 0x54, - 0x65, 0x78, 0x43, 0x6F, 0x6F, 0x72, 0x64, 0x0, 0x5, 0x0, - 0x5, 0x0, 0x27, 0x0, 0x0, 0x0, 0x69, 0x6E, 0x54, 0x65, - 0x78, 0x43, 0x6F, 0x6F, 0x72, 0x64, 0x0, 0x0, 0x5, 0x0, - 0x5, 0x0, 0x29, 0x0, 0x0, 0x0, 0x6F, 0x75, 0x74, 0x43, - 0x6F, 0x6C, 0x6F, 0x72, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, - 0x4, 0x0, 0x2B, 0x0, 0x0, 0x0, 0x69, 0x6E, 0x43, 0x6F, - 0x6C, 0x6F, 0x72, 0x0, 0x48, 0x0, 0x5, 0x0, 0xB, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xB, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x48, 0x0, 0x5, 0x0, 0xB, 0x0, - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0xB, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x48, 0x0, 0x5, 0x0, 0xB, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0xB, 0x0, 0x0, 0x0, - 0x3, 0x0, 0x0, 0x0, 0x48, 0x0, 0x5, 0x0, 0xB, 0x0, - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0xB, 0x0, 0x0, 0x0, - 0x4, 0x0, 0x0, 0x0, 0x47, 0x0, 0x3, 0x0, 0xB, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x48, 0x0, 0x4, 0x0, - 0x11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, - 0x0, 0x0, 0x48, 0x0, 0x5, 0x0, 0x11, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x48, 0x0, 0x5, 0x0, 0x11, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x10, 0x0, - 0x0, 0x0, 0x47, 0x0, 0x3, 0x0, 0x11, 0x0, 0x0, 0x0, - 0x2, 0x0, 0x0, 0x0, 0x47, 0x0, 0x4, 0x0, 0x13, 0x0, - 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x47, 0x0, 0x4, 0x0, 0x13, 0x0, 0x0, 0x0, 0x21, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x47, 0x0, 0x4, 0x0, - 0x19, 0x0, 0x0, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x47, 0x0, 0x4, 0x0, 0x25, 0x0, 0x0, 0x0, - 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x47, 0x0, - 0x4, 0x0, 0x27, 0x0, 0x0, 0x0, 0x1E, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x47, 0x0, 0x4, 0x0, 0x29, 0x0, - 0x0, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x47, 0x0, 0x4, 0x0, 0x2B, 0x0, 0x0, 0x0, 0x1E, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x13, 0x0, 0x2, 0x0, - 0x2, 0x0, 0x0, 0x0, 0x21, 0x0, 0x3, 0x0, 0x3, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x16, 0x0, 0x3, 0x0, - 0x6, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x17, 0x0, - 0x4, 0x0, 0x7, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x4, 0x0, 0x0, 0x0, 0x15, 0x0, 0x4, 0x0, 0x8, 0x0, - 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x2B, 0x0, 0x4, 0x0, 0x8, 0x0, 0x0, 0x0, 0x9, 0x0, - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1C, 0x0, 0x4, 0x0, - 0xA, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x9, 0x0, - 0x0, 0x0, 0x1E, 0x0, 0x6, 0x0, 0xB, 0x0, 0x0, 0x0, - 0x7, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0xA, 0x0, - 0x0, 0x0, 0xA, 0x0, 0x0, 0x0, 0x20, 0x0, 0x4, 0x0, - 0xC, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0xB, 0x0, - 0x0, 0x0, 0x3B, 0x0, 0x4, 0x0, 0xC, 0x0, 0x0, 0x0, - 0xD, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x15, 0x0, - 0x4, 0x0, 0xE, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x2B, 0x0, 0x4, 0x0, 0xE, 0x0, - 0x0, 0x0, 0xF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x18, 0x0, 0x4, 0x0, 0x10, 0x0, 0x0, 0x0, 0x7, 0x0, - 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x1E, 0x0, 0x3, 0x0, - 0x11, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x4, 0x0, 0x12, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x11, 0x0, 0x0, 0x0, 0x3B, 0x0, 0x4, 0x0, 0x12, 0x0, - 0x0, 0x0, 0x13, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x20, 0x0, 0x4, 0x0, 0x14, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x17, 0x0, 0x4, 0x0, - 0x17, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x0, 0x0, 0x20, 0x0, 0x4, 0x0, 0x18, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x17, 0x0, 0x0, 0x0, 0x3B, 0x0, - 0x4, 0x0, 0x18, 0x0, 0x0, 0x0, 0x19, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x2B, 0x0, 0x4, 0x0, 0x6, 0x0, - 0x0, 0x0, 0x1B, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x3F, - 0x20, 0x0, 0x4, 0x0, 0x21, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x17, 0x0, 0x4, 0x0, - 0x23, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, 0x20, 0x0, 0x4, 0x0, 0x24, 0x0, 0x0, 0x0, - 0x3, 0x0, 0x0, 0x0, 0x23, 0x0, 0x0, 0x0, 0x3B, 0x0, - 0x4, 0x0, 0x24, 0x0, 0x0, 0x0, 0x25, 0x0, 0x0, 0x0, - 0x3, 0x0, 0x0, 0x0, 0x20, 0x0, 0x4, 0x0, 0x26, 0x0, - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x23, 0x0, 0x0, 0x0, - 0x3B, 0x0, 0x4, 0x0, 0x26, 0x0, 0x0, 0x0, 0x27, 0x0, - 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x3B, 0x0, 0x4, 0x0, - 0x21, 0x0, 0x0, 0x0, 0x29, 0x0, 0x0, 0x0, 0x3, 0x0, - 0x0, 0x0, 0x20, 0x0, 0x4, 0x0, 0x2A, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x3B, 0x0, - 0x4, 0x0, 0x2A, 0x0, 0x0, 0x0, 0x2B, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x36, 0x0, 0x5, 0x0, 0x2, 0x0, - 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x3, 0x0, 0x0, 0x0, 0xF8, 0x0, 0x2, 0x0, 0x5, 0x0, - 0x0, 0x0, 0x41, 0x0, 0x5, 0x0, 0x14, 0x0, 0x0, 0x0, - 0x15, 0x0, 0x0, 0x0, 0x13, 0x0, 0x0, 0x0, 0xF, 0x0, - 0x0, 0x0, 0x3D, 0x0, 0x4, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x16, 0x0, 0x0, 0x0, 0x15, 0x0, 0x0, 0x0, 0x3D, 0x0, - 0x4, 0x0, 0x17, 0x0, 0x0, 0x0, 0x1A, 0x0, 0x0, 0x0, - 0x19, 0x0, 0x0, 0x0, 0x51, 0x0, 0x5, 0x0, 0x6, 0x0, - 0x0, 0x0, 0x1C, 0x0, 0x0, 0x0, 0x1A, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x51, 0x0, 0x5, 0x0, 0x6, 0x0, - 0x0, 0x0, 0x1D, 0x0, 0x0, 0x0, 0x1A, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x51, 0x0, 0x5, 0x0, 0x6, 0x0, - 0x0, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x1A, 0x0, 0x0, 0x0, - 0x2, 0x0, 0x0, 0x0, 0x50, 0x0, 0x7, 0x0, 0x7, 0x0, - 0x0, 0x0, 0x1F, 0x0, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x0, - 0x1D, 0x0, 0x0, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x1B, 0x0, - 0x0, 0x0, 0x91, 0x0, 0x5, 0x0, 0x7, 0x0, 0x0, 0x0, - 0x20, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0x1F, 0x0, - 0x0, 0x0, 0x41, 0x0, 0x5, 0x0, 0x21, 0x0, 0x0, 0x0, - 0x22, 0x0, 0x0, 0x0, 0xD, 0x0, 0x0, 0x0, 0xF, 0x0, - 0x0, 0x0, 0x3E, 0x0, 0x3, 0x0, 0x22, 0x0, 0x0, 0x0, - 0x20, 0x0, 0x0, 0x0, 0x3D, 0x0, 0x4, 0x0, 0x23, 0x0, - 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0x27, 0x0, 0x0, 0x0, - 0x3E, 0x0, 0x3, 0x0, 0x25, 0x0, 0x0, 0x0, 0x28, 0x0, - 0x0, 0x0, 0x3D, 0x0, 0x4, 0x0, 0x7, 0x0, 0x0, 0x0, - 0x2C, 0x0, 0x0, 0x0, 0x2B, 0x0, 0x0, 0x0, 0x3E, 0x0, - 0x3, 0x0, 0x29, 0x0, 0x0, 0x0, 0x2C, 0x0, 0x0, 0x0, - 0xFD, 0x0, 0x1, 0x0, 0x38, 0x0, 0x1, 0x0, - ]; - - public byte[] VideoYuv2RgbaFrag { get; } = - [ - 0x3, 0x2, 0x23, 0x7, 0x0, 0x0, 0x1, 0x0, 0xB, 0x0, - 0x8, 0x0, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x11, 0x0, 0x2, 0x0, 0x1, 0x0, 0x0, 0x0, 0xB, 0x0, - 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x47, 0x4C, 0x53, 0x4C, - 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30, 0x0, 0x0, - 0x0, 0x0, 0xE, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0xF, 0x0, 0x7, 0x0, 0x4, 0x0, - 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x6D, 0x61, 0x69, 0x6E, - 0x0, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x2E, 0x0, - 0x0, 0x0, 0x10, 0x0, 0x3, 0x0, 0x4, 0x0, 0x0, 0x0, - 0x7, 0x0, 0x0, 0x0, 0x3, 0x0, 0x3, 0x0, 0x2, 0x0, - 0x0, 0x0, 0xC2, 0x1, 0x0, 0x0, 0x5, 0x0, 0x4, 0x0, - 0x4, 0x0, 0x0, 0x0, 0x6D, 0x61, 0x69, 0x6E, 0x0, 0x0, - 0x0, 0x0, 0x5, 0x0, 0x3, 0x0, 0x9, 0x0, 0x0, 0x0, - 0x79, 0x75, 0x76, 0x0, 0x5, 0x0, 0x5, 0x0, 0xD, 0x0, - 0x0, 0x0, 0x59, 0x53, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x72, - 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x5, 0x0, 0x11, 0x0, - 0x0, 0x0, 0x54, 0x65, 0x78, 0x43, 0x6F, 0x6F, 0x72, 0x64, - 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x5, 0x0, 0x1A, 0x0, - 0x0, 0x0, 0x55, 0x53, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x72, - 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x5, 0x0, 0x21, 0x0, - 0x0, 0x0, 0x56, 0x53, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x72, - 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x5, 0x0, 0x2E, 0x0, - 0x0, 0x0, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6F, 0x6C, 0x6F, - 0x72, 0x0, 0x0, 0x0, 0x47, 0x0, 0x4, 0x0, 0xD, 0x0, - 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x47, 0x0, 0x4, 0x0, 0xD, 0x0, 0x0, 0x0, 0x21, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x47, 0x0, 0x4, 0x0, - 0x11, 0x0, 0x0, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x47, 0x0, 0x4, 0x0, 0x1A, 0x0, 0x0, 0x0, - 0x22, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x47, 0x0, - 0x4, 0x0, 0x1A, 0x0, 0x0, 0x0, 0x21, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x47, 0x0, 0x4, 0x0, 0x21, 0x0, - 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x47, 0x0, 0x4, 0x0, 0x21, 0x0, 0x0, 0x0, 0x21, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x47, 0x0, 0x4, 0x0, - 0x2E, 0x0, 0x0, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x13, 0x0, 0x2, 0x0, 0x2, 0x0, 0x0, 0x0, - 0x21, 0x0, 0x3, 0x0, 0x3, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, 0x16, 0x0, 0x3, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x20, 0x0, 0x0, 0x0, 0x17, 0x0, 0x4, 0x0, 0x7, 0x0, - 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x20, 0x0, 0x4, 0x0, 0x8, 0x0, 0x0, 0x0, 0x7, 0x0, - 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x19, 0x0, 0x9, 0x0, - 0xA, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1B, 0x0, 0x3, 0x0, 0xB, 0x0, 0x0, 0x0, - 0xA, 0x0, 0x0, 0x0, 0x20, 0x0, 0x4, 0x0, 0xC, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xB, 0x0, 0x0, 0x0, - 0x3B, 0x0, 0x4, 0x0, 0xC, 0x0, 0x0, 0x0, 0xD, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0x0, 0x4, 0x0, - 0xF, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, 0x20, 0x0, 0x4, 0x0, 0x10, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0xF, 0x0, 0x0, 0x0, 0x3B, 0x0, - 0x4, 0x0, 0x10, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x17, 0x0, 0x4, 0x0, 0x13, 0x0, - 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, - 0x15, 0x0, 0x4, 0x0, 0x15, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2B, 0x0, 0x4, 0x0, - 0x15, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x20, 0x0, 0x4, 0x0, 0x18, 0x0, 0x0, 0x0, - 0x7, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x3B, 0x0, - 0x4, 0x0, 0xC, 0x0, 0x0, 0x0, 0x1A, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x2B, 0x0, 0x4, 0x0, 0x15, 0x0, - 0x0, 0x0, 0x1F, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x3B, 0x0, 0x4, 0x0, 0xC, 0x0, 0x0, 0x0, 0x21, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2B, 0x0, 0x4, 0x0, - 0x15, 0x0, 0x0, 0x0, 0x26, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, 0x2B, 0x0, 0x4, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x28, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0xBD, 0x2B, 0x0, - 0x4, 0x0, 0x6, 0x0, 0x0, 0x0, 0x29, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xBF, 0x2C, 0x0, 0x6, 0x0, 0x7, 0x0, - 0x0, 0x0, 0x2A, 0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, - 0x29, 0x0, 0x0, 0x0, 0x29, 0x0, 0x0, 0x0, 0x20, 0x0, - 0x4, 0x0, 0x2D, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x13, 0x0, 0x0, 0x0, 0x3B, 0x0, 0x4, 0x0, 0x2D, 0x0, - 0x0, 0x0, 0x2E, 0x0, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, - 0x2B, 0x0, 0x4, 0x0, 0x6, 0x0, 0x0, 0x0, 0x30, 0x0, - 0x0, 0x0, 0xF4, 0xFD, 0x94, 0x3F, 0x2B, 0x0, 0x4, 0x0, - 0x6, 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2B, 0x0, 0x4, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x32, 0x0, 0x0, 0x0, 0x6, 0x81, 0xE5, 0x3F, 0x2C, 0x0, - 0x6, 0x0, 0x7, 0x0, 0x0, 0x0, 0x33, 0x0, 0x0, 0x0, - 0x30, 0x0, 0x0, 0x0, 0x31, 0x0, 0x0, 0x0, 0x32, 0x0, - 0x0, 0x0, 0x20, 0x0, 0x4, 0x0, 0x35, 0x0, 0x0, 0x0, - 0x3, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x2B, 0x0, - 0x4, 0x0, 0x6, 0x0, 0x0, 0x0, 0x38, 0x0, 0x0, 0x0, - 0xAC, 0x1C, 0x5A, 0xBE, 0x2B, 0x0, 0x4, 0x0, 0x6, 0x0, - 0x0, 0x0, 0x39, 0x0, 0x0, 0x0, 0xB0, 0x72, 0x8, 0xBF, - 0x2C, 0x0, 0x6, 0x0, 0x7, 0x0, 0x0, 0x0, 0x3A, 0x0, - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x38, 0x0, 0x0, 0x0, - 0x39, 0x0, 0x0, 0x0, 0x2B, 0x0, 0x4, 0x0, 0x6, 0x0, - 0x0, 0x0, 0x3E, 0x0, 0x0, 0x0, 0x2, 0x2B, 0x7, 0x40, - 0x2C, 0x0, 0x6, 0x0, 0x7, 0x0, 0x0, 0x0, 0x3F, 0x0, - 0x0, 0x0, 0x30, 0x0, 0x0, 0x0, 0x3E, 0x0, 0x0, 0x0, - 0x31, 0x0, 0x0, 0x0, 0x2B, 0x0, 0x4, 0x0, 0x6, 0x0, - 0x0, 0x0, 0x42, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x3F, - 0x2B, 0x0, 0x4, 0x0, 0x15, 0x0, 0x0, 0x0, 0x43, 0x0, - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x36, 0x0, 0x5, 0x0, - 0x2, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0xF8, 0x0, 0x2, 0x0, - 0x5, 0x0, 0x0, 0x0, 0x3B, 0x0, 0x4, 0x0, 0x8, 0x0, - 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, - 0x3D, 0x0, 0x4, 0x0, 0xB, 0x0, 0x0, 0x0, 0xE, 0x0, - 0x0, 0x0, 0xD, 0x0, 0x0, 0x0, 0x3D, 0x0, 0x4, 0x0, - 0xF, 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x11, 0x0, - 0x0, 0x0, 0x57, 0x0, 0x5, 0x0, 0x13, 0x0, 0x0, 0x0, - 0x14, 0x0, 0x0, 0x0, 0xE, 0x0, 0x0, 0x0, 0x12, 0x0, - 0x0, 0x0, 0x51, 0x0, 0x5, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x17, 0x0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x41, 0x0, 0x5, 0x0, 0x18, 0x0, 0x0, 0x0, - 0x19, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x16, 0x0, - 0x0, 0x0, 0x3E, 0x0, 0x3, 0x0, 0x19, 0x0, 0x0, 0x0, - 0x17, 0x0, 0x0, 0x0, 0x3D, 0x0, 0x4, 0x0, 0xB, 0x0, - 0x0, 0x0, 0x1B, 0x0, 0x0, 0x0, 0x1A, 0x0, 0x0, 0x0, - 0x3D, 0x0, 0x4, 0x0, 0xF, 0x0, 0x0, 0x0, 0x1C, 0x0, - 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x57, 0x0, 0x5, 0x0, - 0x13, 0x0, 0x0, 0x0, 0x1D, 0x0, 0x0, 0x0, 0x1B, 0x0, - 0x0, 0x0, 0x1C, 0x0, 0x0, 0x0, 0x51, 0x0, 0x5, 0x0, - 0x6, 0x0, 0x0, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x1D, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x41, 0x0, 0x5, 0x0, - 0x18, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x9, 0x0, - 0x0, 0x0, 0x1F, 0x0, 0x0, 0x0, 0x3E, 0x0, 0x3, 0x0, - 0x20, 0x0, 0x0, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x3D, 0x0, - 0x4, 0x0, 0xB, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, - 0x21, 0x0, 0x0, 0x0, 0x3D, 0x0, 0x4, 0x0, 0xF, 0x0, - 0x0, 0x0, 0x23, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, - 0x57, 0x0, 0x5, 0x0, 0x13, 0x0, 0x0, 0x0, 0x24, 0x0, - 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x23, 0x0, 0x0, 0x0, - 0x51, 0x0, 0x5, 0x0, 0x6, 0x0, 0x0, 0x0, 0x25, 0x0, - 0x0, 0x0, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x41, 0x0, 0x5, 0x0, 0x18, 0x0, 0x0, 0x0, 0x27, 0x0, - 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x26, 0x0, 0x0, 0x0, - 0x3E, 0x0, 0x3, 0x0, 0x27, 0x0, 0x0, 0x0, 0x25, 0x0, - 0x0, 0x0, 0x3D, 0x0, 0x4, 0x0, 0x7, 0x0, 0x0, 0x0, - 0x2B, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x81, 0x0, - 0x5, 0x0, 0x7, 0x0, 0x0, 0x0, 0x2C, 0x0, 0x0, 0x0, - 0x2B, 0x0, 0x0, 0x0, 0x2A, 0x0, 0x0, 0x0, 0x3E, 0x0, - 0x3, 0x0, 0x9, 0x0, 0x0, 0x0, 0x2C, 0x0, 0x0, 0x0, - 0x3D, 0x0, 0x4, 0x0, 0x7, 0x0, 0x0, 0x0, 0x2F, 0x0, - 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x94, 0x0, 0x5, 0x0, - 0x6, 0x0, 0x0, 0x0, 0x34, 0x0, 0x0, 0x0, 0x2F, 0x0, - 0x0, 0x0, 0x33, 0x0, 0x0, 0x0, 0x41, 0x0, 0x5, 0x0, - 0x35, 0x0, 0x0, 0x0, 0x36, 0x0, 0x0, 0x0, 0x2E, 0x0, - 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0x3E, 0x0, 0x3, 0x0, - 0x36, 0x0, 0x0, 0x0, 0x34, 0x0, 0x0, 0x0, 0x3D, 0x0, - 0x4, 0x0, 0x7, 0x0, 0x0, 0x0, 0x37, 0x0, 0x0, 0x0, - 0x9, 0x0, 0x0, 0x0, 0x94, 0x0, 0x5, 0x0, 0x6, 0x0, - 0x0, 0x0, 0x3B, 0x0, 0x0, 0x0, 0x37, 0x0, 0x0, 0x0, - 0x3A, 0x0, 0x0, 0x0, 0x41, 0x0, 0x5, 0x0, 0x35, 0x0, - 0x0, 0x0, 0x3C, 0x0, 0x0, 0x0, 0x2E, 0x0, 0x0, 0x0, - 0x1F, 0x0, 0x0, 0x0, 0x3E, 0x0, 0x3, 0x0, 0x3C, 0x0, - 0x0, 0x0, 0x3B, 0x0, 0x0, 0x0, 0x3D, 0x0, 0x4, 0x0, - 0x7, 0x0, 0x0, 0x0, 0x3D, 0x0, 0x0, 0x0, 0x9, 0x0, - 0x0, 0x0, 0x94, 0x0, 0x5, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x40, 0x0, 0x0, 0x0, 0x3D, 0x0, 0x0, 0x0, 0x3F, 0x0, - 0x0, 0x0, 0x41, 0x0, 0x5, 0x0, 0x35, 0x0, 0x0, 0x0, - 0x41, 0x0, 0x0, 0x0, 0x2E, 0x0, 0x0, 0x0, 0x26, 0x0, - 0x0, 0x0, 0x3E, 0x0, 0x3, 0x0, 0x41, 0x0, 0x0, 0x0, - 0x40, 0x0, 0x0, 0x0, 0x41, 0x0, 0x5, 0x0, 0x35, 0x0, - 0x0, 0x0, 0x44, 0x0, 0x0, 0x0, 0x2E, 0x0, 0x0, 0x0, - 0x43, 0x0, 0x0, 0x0, 0x3E, 0x0, 0x3, 0x0, 0x44, 0x0, - 0x0, 0x0, 0x42, 0x0, 0x0, 0x0, 0xFD, 0x0, 0x1, 0x0, - 0x38, 0x0, 0x1, 0x0, - ]; -} diff --git a/Nerfed.Runtime/Graphics/GraphicsDevice.cs b/Nerfed.Runtime/Graphics/GraphicsDevice.cs index 4bdfde2..ded7baf 100644 --- a/Nerfed.Runtime/Graphics/GraphicsDevice.cs +++ b/Nerfed.Runtime/Graphics/GraphicsDevice.cs @@ -13,12 +13,16 @@ public class GraphicsDevice : IDisposable public BackendFlags Backend { get; } public bool DebugMode { get; } + // Built-in shaders + public Shader FullscreenVertexShader { get; private set; } + public Shader VideoFragmentShader { get; private set; } + public Shader TextVertexShader { get; private set; } + public Shader TextFragmentShader { get; private set; } + // Built-in video pipeline - internal GraphicsPipeline VideoPipeline { get; } + internal GraphicsPipeline VideoPipeline { get; private set; } // Built-in text shader info - public Shader TextVertexShader; - public Shader TextFragmentShader; public VertexInputState TextVertexInputState { get; } // Built-in samplers @@ -53,85 +57,21 @@ internal GraphicsDevice(BackendFlags preferredBackends) Backend = (BackendFlags)Refresh.Refresh_GetBackend(Handle); - IEmbeddedShaders embeddedShaders; - switch (Backend) - { - case BackendFlags.Vulkan: - embeddedShaders = new EmbeddedShadersSpirV(); - break; - case BackendFlags.D3D11: - throw new NotImplementedException("D3D11 embedded shaders"); - break; - case BackendFlags.Metal: - throw new NotImplementedException("Metal embedded shaders"); - break; - default: throw new ArgumentOutOfRangeException(); - } + TextVertexInputState = VertexInputState.CreateSingleBinding(); - Shader fullscreenVertShader; - Shader textVertShader; - Shader textFragShader; - Shader videoFragShader; + PointSampler = new Sampler(this, SamplerCreateInfo.PointClamp); + LinearSampler = new Sampler(this, SamplerCreateInfo.LinearClamp); - using (MemoryStream fullscreenVertStream = new MemoryStream(embeddedShaders.FullscreenVert)) - { - fullscreenVertShader = new Shader( - this, - fullscreenVertStream, - "main", - new ShaderCreateInfo - { - ShaderStage = ShaderStage.Vertex, - ShaderFormat = embeddedShaders.ShaderFormat - } - ); - } + fencePool = new FencePool(this); + commandBufferPool = new CommandBufferPool(this); + } - using (MemoryStream videoYuv2RgbaFragStream = new MemoryStream(embeddedShaders.VideoYuv2RgbaFrag)) - { - videoFragShader = new Shader( - this, - videoYuv2RgbaFragStream, - "main", - new ShaderCreateInfo - { - ShaderStage = ShaderStage.Fragment, - ShaderFormat = embeddedShaders.ShaderFormat, - SamplerCount = 3 - } - ); - } - - using (MemoryStream textTransformVertStream = new MemoryStream(embeddedShaders.TextTransformVert)) - { - textVertShader = new Shader( - this, - textTransformVertStream, - "main", - new ShaderCreateInfo - { - ShaderStage = ShaderStage.Vertex, - ShaderFormat = embeddedShaders.ShaderFormat, - UniformBufferCount = 1 - } - ); - } - - using (MemoryStream textMsdfFragStream = new MemoryStream(embeddedShaders.TextMsdfFrag)) - { - textFragShader = new Shader( - this, - textMsdfFragStream, - "main", - new ShaderCreateInfo - { - ShaderStage = ShaderStage.Fragment, - ShaderFormat = embeddedShaders.ShaderFormat, - SamplerCount = 1, - UniformBufferCount = 1 - } - ); - } + internal void LoadDefaultPipelines() + { + FullscreenVertexShader = ResourceManager.Load("Shaders/Fullscreen.vert"); + VideoFragmentShader = ResourceManager.Load("Shaders/Video.frag"); + TextVertexShader = ResourceManager.Load("Shaders/Text.vert"); + TextFragmentShader = ResourceManager.Load("Shaders/Text.frag"); VideoPipeline = new GraphicsPipeline( this, @@ -144,25 +84,14 @@ internal GraphicsDevice(BackendFlags preferredBackends) ) ), DepthStencilState = DepthStencilState.Disable, - VertexShader = fullscreenVertShader, - FragmentShader = videoFragShader, + VertexShader = FullscreenVertexShader, + FragmentShader = VideoFragmentShader, VertexInputState = VertexInputState.Empty, RasterizerState = RasterizerState.CCW_CullNone, PrimitiveType = PrimitiveType.TriangleList, MultisampleState = MultisampleState.None } ); - - TextVertexShader = textVertShader; - TextFragmentShader = textFragShader; - - TextVertexInputState = VertexInputState.CreateSingleBinding(); - - PointSampler = new Sampler(this, SamplerCreateInfo.PointClamp); - LinearSampler = new Sampler(this, SamplerCreateInfo.LinearClamp); - - fencePool = new FencePool(this); - commandBufferPool = new CommandBufferPool(this); } /// diff --git a/Nerfed.Runtime/Graphics/IEmbeddedShaders.cs b/Nerfed.Runtime/Graphics/IEmbeddedShaders.cs deleted file mode 100644 index d533ca3..0000000 --- a/Nerfed.Runtime/Graphics/IEmbeddedShaders.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Nerfed.Runtime.Graphics; - -internal interface IEmbeddedShaders -{ - ShaderFormat ShaderFormat { get; } - byte[] FullscreenVert { get; } - byte[] TextMsdfFrag { get; } - byte[] TextTransformVert { get; } - byte[] VideoYuv2RgbaFrag { get; } -} diff --git a/Nerfed.Runtime/Graphics/Resources/Shader.cs b/Nerfed.Runtime/Graphics/Resources/Shader.cs deleted file mode 100644 index 0453a6b..0000000 --- a/Nerfed.Runtime/Graphics/Resources/Shader.cs +++ /dev/null @@ -1,91 +0,0 @@ -using RefreshCS; -using System; -using System.IO; -using System.Runtime.InteropServices; - -namespace Nerfed.Runtime.Graphics; - -/// -/// Shaders are used to create graphics pipelines. -/// Graphics pipelines take a vertex shader and a fragment shader. -/// -public class Shader : RefreshResource -{ - protected override Action ReleaseFunction => Refresh.Refresh_ReleaseShader; - - public uint SamplerCount { get; } - public uint StorageTextureCount { get; } - public uint StorageBufferCount { get; } - public uint UniformBufferCount { get; } - - public unsafe Shader( - GraphicsDevice device, - string filePath, - string entryPointName, - in ShaderCreateInfo shaderCreateInfo - ) : base(device) - { - using FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read); - Handle = CreateFromStream( - device, - stream, - entryPointName, - shaderCreateInfo - ); - - SamplerCount = shaderCreateInfo.SamplerCount; - StorageTextureCount = shaderCreateInfo.StorageTextureCount; - StorageBufferCount = shaderCreateInfo.StorageBufferCount; - UniformBufferCount = shaderCreateInfo.UniformBufferCount; - } - - public unsafe Shader( - GraphicsDevice device, - Stream stream, - string entryPointName, - in ShaderCreateInfo shaderCreateInfo - ) : base(device) - { - Handle = CreateFromStream( - device, - stream, - entryPointName, - shaderCreateInfo - ); - - SamplerCount = shaderCreateInfo.SamplerCount; - StorageTextureCount = shaderCreateInfo.StorageTextureCount; - StorageBufferCount = shaderCreateInfo.StorageBufferCount; - UniformBufferCount = shaderCreateInfo.UniformBufferCount; - } - - private static unsafe IntPtr CreateFromStream( - GraphicsDevice device, - Stream stream, - string entryPointName, - in ShaderCreateInfo shaderCreateInfo - ) { - void* bytecodeBuffer = NativeMemory.Alloc((nuint) stream.Length); - Span bytecodeSpan = new Span(bytecodeBuffer, (int) stream.Length); - stream.ReadExactly(bytecodeSpan); - - Refresh.ShaderCreateInfo refreshShaderCreateInfo; - refreshShaderCreateInfo.CodeSize = (nuint) stream.Length; - refreshShaderCreateInfo.Code = (byte*) bytecodeBuffer; - refreshShaderCreateInfo.EntryPointName = entryPointName; - refreshShaderCreateInfo.Stage = (Refresh.ShaderStage) shaderCreateInfo.ShaderStage; - refreshShaderCreateInfo.Format = (Refresh.ShaderFormat) shaderCreateInfo.ShaderFormat; - refreshShaderCreateInfo.SamplerCount = shaderCreateInfo.SamplerCount; - refreshShaderCreateInfo.StorageTextureCount = shaderCreateInfo.StorageTextureCount; - refreshShaderCreateInfo.StorageBufferCount = shaderCreateInfo.StorageBufferCount; - refreshShaderCreateInfo.UniformBufferCount = shaderCreateInfo.UniformBufferCount; - - IntPtr shaderModule = Refresh.Refresh_CreateShader( - device.Handle, - refreshShaderCreateInfo - ); - - NativeMemory.Free(bytecodeBuffer); - return shaderModule; - } -} \ No newline at end of file diff --git a/Nerfed.Runtime/Gui/GuiController.cs b/Nerfed.Runtime/Gui/GuiController.cs index 3db9cdd..a434211 100644 --- a/Nerfed.Runtime/Gui/GuiController.cs +++ b/Nerfed.Runtime/Gui/GuiController.cs @@ -60,20 +60,8 @@ public GuiController(GraphicsDevice graphicsDevice, Window mainWindow, Color cle io.DisplaySize = new Vector2(mainWindow.Width, mainWindow.Height); io.DisplayFramebufferScale = Vector2.One; - ShaderCreateInfo vertexCreateInfo = new ShaderCreateInfo { - ShaderStage = ShaderStage.Vertex, - ShaderFormat = ShaderFormat.SPIRV, - UniformBufferCount = 1, - }; - imGuiVertexShader = new Shader(graphicsDevice, Path.Combine(shaderContentPath, "imgui-vertex.spv"), "main", in vertexCreateInfo); - - ShaderCreateInfo fragCreateInfo = new ShaderCreateInfo { - ShaderStage = ShaderStage.Fragment, - ShaderFormat = ShaderFormat.SPIRV, - SamplerCount = 1, - - }; - imGuiFragmentShader = new Shader(graphicsDevice, Path.Combine(shaderContentPath, "imgui-frag.spv"), "main", in fragCreateInfo); + imGuiVertexShader = ResourceManager.Load("Shaders/ImGui.vert"); + imGuiFragmentShader = ResourceManager.Load("Shaders/ImGui.frag"); imGuiSampler = new Sampler(graphicsDevice, SamplerCreateInfo.LinearClamp); @@ -642,8 +630,8 @@ public void Dispose() fontTexture?.Dispose(); imGuiVertexBuffer?.Dispose(); imGuiIndexBuffer?.Dispose(); - imGuiFragmentShader?.Dispose(); - imGuiVertexShader?.Dispose(); + ResourceManager.Unload(imGuiVertexShader); + ResourceManager.Unload(imGuiFragmentShader); imGuiPipeline?.Dispose(); imGuiSampler?.Dispose(); resourceUploader?.Dispose(); diff --git a/Nerfed.Runtime/Nerfed.Runtime.csproj.DotSettings b/Nerfed.Runtime/Nerfed.Runtime.csproj.DotSettings new file mode 100644 index 0000000..669ba7b --- /dev/null +++ b/Nerfed.Runtime/Nerfed.Runtime.csproj.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/Nerfed.Runtime/Resource/Resource.cs b/Nerfed.Runtime/Resource/Resource.cs new file mode 100644 index 0000000..5a4a545 --- /dev/null +++ b/Nerfed.Runtime/Resource/Resource.cs @@ -0,0 +1,9 @@ +namespace Nerfed.Runtime; + +public abstract class Resource +{ + public string Path { get; internal set; } + + internal abstract void Load(Stream stream); + internal abstract void Unload(); +} diff --git a/Nerfed.Runtime/Resource/ResourceManager.cs b/Nerfed.Runtime/Resource/ResourceManager.cs new file mode 100644 index 0000000..2af777a --- /dev/null +++ b/Nerfed.Runtime/Resource/ResourceManager.cs @@ -0,0 +1,43 @@ +namespace Nerfed.Runtime; + +public static class ResourceManager +{ + private const string rootName = "Resources"; + private static readonly Dictionary loadedResources = new Dictionary(); + + public static T Load(string resourcePath) where T : Resource + { + if (loadedResources.TryGetValue(resourcePath, out Resource resource)) + { + return (T)resource; + } + + if (typeof(T) == typeof(Shader)) + { + resource = new Shader(); + } + else + { + throw new Exception("Failed to create resource"); + } + + Assert.Always(resource != null); + resource.Path = resourcePath; + resource.Load(StorageContainer.OpenStream(Path.Combine(AppContext.BaseDirectory, rootName, resourcePath) + ".bin")); + + loadedResources.Add(resourcePath, resource); + return (T)resource; + } + + public static void Unload(Resource resource) + { + if (!loadedResources.ContainsKey(resource.Path)) + { + return; + } + + resource.Unload(); + resource.Path = string.Empty; + loadedResources.Remove(resource.Path); + } +} diff --git a/Nerfed.Runtime/Resource/Shader.cs b/Nerfed.Runtime/Resource/Shader.cs new file mode 100644 index 0000000..a63f635 --- /dev/null +++ b/Nerfed.Runtime/Resource/Shader.cs @@ -0,0 +1,58 @@ +using System.Runtime.InteropServices; +using RefreshCS; + +namespace Nerfed.Runtime; + +public class Shader : Resource +{ + public IntPtr Handle { get; private set; } + + public uint SamplerCount { get; private set; } + public uint StorageTextureCount { get; private set; } + public uint StorageBufferCount { get; private set; } + public uint UniformBufferCount { get; private set; } + + internal Shader() { } + + internal override unsafe void Load(Stream stream) + { + using (BinaryReader reader = new BinaryReader(stream)) + { + Refresh.ShaderCreateInfo createInfo; + createInfo.Format = (Refresh.ShaderFormat)reader.ReadInt32(); + createInfo.Stage = (Refresh.ShaderStage)reader.ReadInt32(); + createInfo.UniformBufferCount = (uint)reader.ReadInt32(); + createInfo.StorageBufferCount = (uint)reader.ReadInt32(); + createInfo.StorageTextureCount = (uint)reader.ReadInt32(); + createInfo.SamplerCount = (uint)reader.ReadInt32(); + + int byteCodeSize = reader.ReadInt32(); + void* byteCodeBuffer = NativeMemory.Alloc((nuint)byteCodeSize); + Span byteCodeSpan = new Span(byteCodeBuffer, byteCodeSize); + + int bytesRead = 0; + while (bytesRead < byteCodeSize) + { + bytesRead += reader.Read(byteCodeSpan.Slice(bytesRead)); + } + + createInfo.CodeSize = (nuint)byteCodeSize; + createInfo.Code = (byte*)byteCodeBuffer; + createInfo.EntryPointName = "main"; + + Handle = Refresh.Refresh_CreateShader(Engine.GraphicsDevice.Handle, createInfo); + NativeMemory.Free(byteCodeBuffer); + + SamplerCount = createInfo.SamplerCount; + StorageTextureCount = createInfo.StorageTextureCount; + StorageBufferCount = createInfo.StorageBufferCount; + UniformBufferCount = createInfo.UniformBufferCount; + } + } + + internal override void Unload() + { + Refresh.Refresh_ReleaseShader(Engine.GraphicsDevice.Handle, Handle); + Handle = IntPtr.Zero; + } +} diff --git a/Nerfed.Runtime/Storage/StorageContainer.cs b/Nerfed.Runtime/Resource/StorageContainer.cs similarity index 100% rename from Nerfed.Runtime/Storage/StorageContainer.cs rename to Nerfed.Runtime/Resource/StorageContainer.cs diff --git a/Nerfed.sln b/Nerfed.sln index 02931a6..c36f1bf 100644 --- a/Nerfed.sln +++ b/Nerfed.sln @@ -8,6 +8,9 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nerfed.Builder", "Nerfed.Builder\Nerfed.Builder.csproj", "{1B88DE56-2AD8-441E-9B10-073AA43840BF}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nerfed.Editor", "Nerfed.Editor\Nerfed.Editor.csproj", "{FF7D032D-7F0B-4700-A818-0606D66AECF8}" + ProjectSection(ProjectDependencies) = postProject + {1B88DE56-2AD8-441E-9B10-073AA43840BF} = {1B88DE56-2AD8-441E-9B10-073AA43840BF} + EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution