Essgee.Unity/Assets/Plugins/Essgee/Graphics/OnScreenDisplayHandler.cs
2025-01-02 17:55:16 +08:00

375 lines
12 KiB
C#

//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Threading.Tasks;
//using System.Drawing;
//using System.Runtime.InteropServices;
//using System.Reflection;
//using OpenTK;
//using OpenTK.Graphics;
//using Essgee.Graphics.Shaders;
//namespace Essgee.Graphics
//{
// public class OnScreenDisplayHandler : IDisposable
// {
// readonly static int messageDefaultSeconds = 5;
// readonly static int maxStringListLength = 128;
// readonly static int stringListPurgeSize = 16;
// readonly static string glslUniformProjection = "projection";
// readonly static string glslUniformModelview = "modelview";
// readonly static string glslUniformSourceSampler = "source";
// readonly static string glslUniformTextColor = "textColor";
// readonly static string glslUniformFontSize = "fontSize";
// readonly static string glslUniformCharacterOffset = "characterOffset";
// readonly static string glslVersion = "#version 300 es\n";
// readonly static string glslESPrecision = "precision mediump float; precision mediump int;\n";
// readonly static string glslMainStart = "void main(void){";
// readonly static string glslMainEnd = "}\n";
// readonly static string vertexUniforms = $"uniform mat4 {glslUniformProjection}; uniform mat4 {glslUniformModelview};\n";
// readonly static string vertexOuts = "out vec2 vertTexCoord;\n";
// readonly static string vertexMain = $"vertTexCoord = inTextureCoords; gl_Position = {glslUniformProjection} * {glslUniformModelview} * vec4(inPosition.x, inPosition.y, 0.0, 1.0);\n";
// readonly static string fragmentUniforms = $"uniform sampler2D {glslUniformSourceSampler}; uniform vec4 {glslUniformTextColor}; uniform vec2 {glslUniformFontSize}; uniform vec2 {glslUniformCharacterOffset};\n";
// readonly static string fragmentIns = "in vec2 vertTexCoord;\n";
// readonly static string fragmentOuts = "out vec4 fragColor;\n";
// readonly static string fragmentMain =
// $"vec2 localTexCoord = vec2(({glslUniformCharacterOffset}.x + vertTexCoord.x) / {glslUniformFontSize}.x, ({glslUniformCharacterOffset}.y + vertTexCoord.y) / {glslUniformFontSize}.y);\n" +
// $"vec4 outColor = textColor * texture(source, localTexCoord);\n" +
// "if(outColor.a == 0.0) discard;\n" +
// "fragColor = outColor;\n";
// readonly static ushort[] characterIndices = new ushort[] { 0, 1, 2, 2, 3, 0 };
// readonly static Color4 colorSuccess = new Color4(192, 255, 192, 255);
// readonly static Color4 colorWarning = new Color4(255, 192, 160, 255);
// readonly static Color4 colorError = new Color4(255, 128, 128, 255);
// readonly static Color4 colorCore = new Color4(192, 192, 255, 255);
// readonly static Color4 colorDebug = new Color4(192, 128, 255, 255);
// readonly OnScreenDisplayVertex[] characterVertices;
// readonly List<VertexElement> vertexElements;
// readonly int vertexStructSize;
// readonly VertexBuffer characterVertexBuffer;
// readonly Texture fontTexture;
// readonly float characterSourceSize;
// readonly float characterDefaultWidth;
// readonly GLSLShader shader;
// readonly Dictionary<char, Vector2> characterOffsetDict;
// readonly Dictionary<char, (float start, float width)> characterWidthDict;
// readonly List<OnScreenDisplayMessage> stringList;
// (int X, int Y, int Width, int Height) viewport;
// bool disposed = false;
// public OnScreenDisplayHandler(Bitmap osdFontBitmap)
// {
// characterSourceSize = (osdFontBitmap.Width / 16.0f);
// characterDefaultWidth = characterSourceSize - (2.0f * (characterSourceSize / 8));
// characterOffsetDict = new Dictionary<char, Vector2>();
// characterWidthDict = new Dictionary<char, (float, float)>();
// for (var ch = '\0'; ch < (char)((osdFontBitmap.Width / characterSourceSize) * (osdFontBitmap.Height / characterSourceSize)); ch++)
// {
// float x = (ch % (osdFontBitmap.Width / (int)characterSourceSize)) * characterSourceSize;
// float y = (ch / (osdFontBitmap.Width / (int)characterSourceSize)) * characterSourceSize;
// float width = characterSourceSize;
// float start = 0.0f;
// for (float xc = x + (characterSourceSize - 1); xc >= x; xc--)
// {
// var pixel = osdFontBitmap.GetPixel((int)xc, (int)y);
// if (pixel.R == 0xFF && pixel.G == 0x00 && pixel.B == 0x00 && pixel.A == 0xFF)
// {
// width = (xc - x);
// osdFontBitmap.SetPixel((int)xc, (int)y, Color.Transparent);
// }
// if (pixel.R == 0xFF && pixel.G == 0xFF && pixel.B == 0x00 && pixel.A == 0xFF)
// {
// start = (xc - x);
// osdFontBitmap.SetPixel((int)xc, (int)y, Color.Transparent);
// }
// }
// characterOffsetDict.Add(ch, new Vector2(x, y));
// characterWidthDict.Add(ch, (start, width));
// }
// fontTexture = new Texture(osdFontBitmap, filter: FilterMode.Nearest);
// (vertexElements, vertexStructSize) = VertexBuffer.DeconstructVertexLayout<OnScreenDisplayVertex>();
// characterVertices = new OnScreenDisplayVertex[]
// {
// new OnScreenDisplayVertex() { Position = new Vector2(0.0f, characterSourceSize), TextureCoords = new Vector2(0.0f, characterSourceSize) },
// new OnScreenDisplayVertex() { Position = new Vector2(0.0f, 0.0f), TextureCoords = new Vector2(0.0f, 0.0f) },
// new OnScreenDisplayVertex() { Position = new Vector2(characterSourceSize, 0.0f), TextureCoords = new Vector2(characterSourceSize, 0.0f) },
// new OnScreenDisplayVertex() { Position = new Vector2(characterSourceSize, characterSourceSize), TextureCoords = new Vector2(characterSourceSize, characterSourceSize) },
// };
// characterVertexBuffer = new VertexBuffer();
// characterVertexBuffer.SetVertexData(characterVertices);
// characterVertexBuffer.SetIndices(characterIndices);
// shader = new GLSLShader();
// shader.SetVertexShaderCode(glslVersion, glslESPrecision, vertexUniforms, VertexBuffer.GetShaderPreamble(vertexElements), vertexOuts, glslMainStart, vertexMain, glslMainEnd);
// shader.SetFragmentShaderCode(glslVersion, glslESPrecision, fragmentUniforms, fragmentIns, fragmentOuts, glslMainStart, fragmentMain, glslMainEnd);
// shader.LinkProgram();
// shader.SetUniformMatrix(glslUniformProjection, false, Matrix4.Identity);
// shader.SetUniformMatrix(glslUniformModelview, false, Matrix4.Identity);
// shader.SetUniform(glslUniformSourceSampler, 0);
// shader.SetUniform(glslUniformTextColor, Color4.White);
// shader.SetUniform(glslUniformFontSize, new Vector2(fontTexture.Width, fontTexture.Height));
// shader.SetUniform(glslUniformCharacterOffset, Vector2.Zero);
// stringList = new List<OnScreenDisplayMessage>();
// }
// ~OnScreenDisplayHandler()
// {
// Dispose(false);
// }
// public void Dispose()
// {
// Dispose(true);
// GC.SuppressFinalize(this);
// }
// protected virtual void Dispose(bool disposing)
// {
// if (disposed) return;
// if (disposing)
// {
// if (fontTexture != null) fontTexture.Dispose();
// if (characterVertexBuffer != null) characterVertexBuffer.Dispose();
// if (shader != null) shader.Dispose();
// }
// disposed = true;
// }
// public void SetViewport(ValueTuple<int, int, int, int> view)
// {
// viewport = view;
// }
// public void SetProjectionMatrix(Matrix4 mat4)
// {
// shader.SetUniformMatrix(glslUniformProjection, false, mat4);
// }
// public void SetModelviewMatrix(Matrix4 mat4)
// {
// shader.SetUniformMatrix(glslUniformModelview, false, mat4);
// }
// public void SendString(string str, int x, int y)
// {
// SendString(str, x, y, Color4.White);
// }
// public void SendString(string str, int x, int y, Color4 color)
// {
// stringList.Add(new OnScreenDisplayMessage()
// {
// X = x,
// Y = y,
// Color = color,
// Text = str,
// ShowUntil = DateTime.Now,
// IsLogEntry = false
// });
// }
// public void EnqueueMessage(string str)
// {
// EnqueueMessage(str, Color4.White);
// }
// public void EnqueueMessage(string str, Color4 color)
// {
// var split = str.Split(new string[] { Environment.NewLine, "\n" }, StringSplitOptions.RemoveEmptyEntries);
// for (var i = 0; i < split.Length; i++)
// {
// stringList.Add(new OnScreenDisplayMessage()
// {
// X = 0,
// Y = 0,
// Color = color,
// Text = split[i],
// ShowUntil = DateTime.Now + TimeSpan.FromTicks(i) + TimeSpan.FromSeconds(messageDefaultSeconds),
// IsLogEntry = true
// });
// }
// }
// public void EnqueueMessageSuccess(string str)
// {
// EnqueueMessage(str, colorSuccess);
// }
// public void EnqueueMessageWarning(string str)
// {
// EnqueueMessage(str, colorWarning);
// }
// public void EnqueueMessageError(string str)
// {
// EnqueueMessage(str, colorError);
// }
// public void EnqueueMessageCore(string str)
// {
// EnqueueMessage(str, colorCore);
// }
// public void EnqueueMessageDebug(string str)
// {
// if (Program.AppEnvironment.DebugMode)
// EnqueueMessage(str, colorDebug);
// }
// public void Render(float deltaTime)
// {
// shader.Activate();
// fontTexture.Activate();
// RenderStrings(deltaTime);
// RenderLogMessages(deltaTime);
// stringList.RemoveAll(x => !x.IsLogEntry && x.ShowUntil < DateTime.Now);
// stringList.RemoveAll(x => x.IsLogEntry && x.Color.A <= 0.0f);
// if (stringList.Count > maxStringListLength)
// stringList.RemoveRange(0, stringListPurgeSize);
// fontTexture.Deactivate();
// }
// private int MeasureString(string @string)
// {
// float width = 0.0f;
// foreach (var ch in @string)
// {
// if (characterWidthDict.ContainsKey(ch))
// {
// width -= characterWidthDict[ch].start;
// width += characterWidthDict[ch].width;
// }
// else
// width += characterDefaultWidth;
// }
// return (int)width;
// }
// private void RenderStrings(float deltaTime)
// {
// foreach (var @string in stringList.ToList().Where(x => !x.IsLogEntry))
// {
// float x = @string.X, y = @string.Y;
// if (x < 0.0f) x = (viewport.Width + x) - MeasureString(@string.Text);
// if (y < 0.0f) y = (viewport.Height + y) - characterSourceSize;
// shader.SetUniform(glslUniformTextColor, @string.Color);
// ParseAndRenderString(@string, ref x, ref y);
// }
// }
// private void RenderLogMessages(float deltaTime)
// {
// var logY = (viewport.Height - (characterSourceSize + (characterSourceSize / 2)));
// foreach (var @string in stringList.ToList().Where(x => x.IsLogEntry).OrderByDescending(x => x.ShowUntil))
// {
// float x = characterSourceSize / 2.0f, y = logY;
// logY -= characterSourceSize;
// shader.SetUniform(glslUniformTextColor, @string.Color);
// ParseAndRenderString(@string, ref x, ref y);
// if ((logY + characterSourceSize) < 0) break;
// }
// var timeNow = DateTime.Now;
// foreach (var @string in stringList.ToList().Where(x => x.IsLogEntry))
// {
// if ((@string.ShowUntil.Ticks - timeNow.Ticks) < TimeSpan.TicksPerSecond)
// @string.Color = new Color4(@string.Color.R, @string.Color.G, @string.Color.B, Math.Max(0.0f, @string.Color.A - (deltaTime / 25.0f)));
// }
// }
// private void ParseAndRenderString(OnScreenDisplayMessage @string, ref float x, ref float y)
// {
// foreach (var c in @string.Text)
// {
// var ch = c;
// if (!characterWidthDict.ContainsKey(ch))
// ch = '\0';
// x -= characterWidthDict[ch].start;
// if (ch == '\n' || ch == '\r')
// {
// x = @string.X;
// y += characterSourceSize;
// continue;
// }
// else if (ch != ' ')
// {
// var osdModelview = Matrix4.Identity;
// osdModelview *= Matrix4.CreateTranslation(x, y, 0.0f);
// shader.SetUniformMatrix(glslUniformModelview, false, osdModelview);
// shader.SetUniform(glslUniformCharacterOffset, characterOffsetDict[ch]);
// characterVertexBuffer.Render();
// }
// x += characterWidthDict[ch].width;
// }
// }
// [StructLayout(LayoutKind.Sequential, Pack = 1)]
// public struct OnScreenDisplayVertex : IVertexStruct
// {
// [VertexElement(AttributeIndex = 0)]
// public Vector2 Position;
// [VertexElement(AttributeIndex = 1)]
// public Vector2 TextureCoords;
// }
// public class OnScreenDisplayMessage
// {
// public int X { get; set; }
// public int Y { get; set; }
// public Color4 Color { get; set; }
// public string Text { get; set; }
// public DateTime ShowUntil { get; set; }
// public bool IsLogEntry { get; set; }
// public OnScreenDisplayMessage()
// {
// X = Y = 0;
// Color = Color4.White;
// Text = string.Empty;
// ShowUntil = DateTime.Now;
// IsLogEntry = false;
// }
// }
// }
//}