Create the first immediate mode UI base.
This commit is contained in:
		
							parent
							
								
									ef860f39bf
								
							
						
					
					
						commit
						1cd005f827
					
				| @ -97,7 +97,7 @@ namespace Dashboard.Drawing.OpenGL.Executors | ||||
|         private void DrawText(ICommandFrame frame) | ||||
|         { | ||||
|             TextCommandArgs args = frame.GetParameter<TextCommandArgs>(); | ||||
|             DbBlurgFont font = (DbBlurgFont)args.Font; | ||||
|             DbBlurgFont font = Engine.InternFont(args.Font); | ||||
| 
 | ||||
|             BlurgColor color; | ||||
|             switch (args.TextBrush) | ||||
|  | ||||
							
								
								
									
										55
									
								
								Dashboard.Drawing.OpenGL/Executors/gradient.glsl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								Dashboard.Drawing.OpenGL/Executors/gradient.glsl
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | ||||
| #ifndef _GRADIENT_GLSL_ | ||||
| #define _GRADIENT_GLSL_ | ||||
| 
 | ||||
| #define DB_GRADIENT_MAX 16 | ||||
| 
 | ||||
| struct Gradient_t { | ||||
|     float fPosition; | ||||
|     float pad0; | ||||
|     float pad1; | ||||
|     float pad2; | ||||
|     vec4  v4Color; | ||||
| }; | ||||
| 
 | ||||
| uniform GradientBlock | ||||
| { | ||||
|     Gradient_t vstGradientStops[DB_GRADIENT_MAX]; | ||||
| }; | ||||
| 
 | ||||
| vec4 getGradientColor(float position, int index, int count) | ||||
| { | ||||
|     position = clamp(position, 0, 1); | ||||
| 
 | ||||
|     int i0 = 0; | ||||
|     float p0 = vstGradientStops[index + i0].fPosition; | ||||
| 
 | ||||
|     int i1 = count - 1; | ||||
|     float p1 = vstGradientStops[index + i1].fPosition; | ||||
| 
 | ||||
|     for (int i = 0; i < count; i++) | ||||
|     { | ||||
|         float px = vstGradientStops[index + i].fPosition; | ||||
| 
 | ||||
|         if (px > p0 && px <= position) | ||||
|         { | ||||
|             p0 = px; | ||||
|             i0 = i; | ||||
|         } | ||||
| 
 | ||||
|         if (px < p1 && px >= position) | ||||
|         { | ||||
|             p1 = px; | ||||
|             i1 = i; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     vec4 c0 = vstGradientStops[index + i0].v4Color; | ||||
|     vec4 c1 = vstGradientStops[index + i1].v4Color; | ||||
| 
 | ||||
|     float l = p1 - p0; | ||||
|     float w = (l > 0) ? (position - p0) / (p1 - p0) : 0; | ||||
| 
 | ||||
|     return mix(c0, c1, w); | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| @ -93,7 +93,7 @@ namespace Dashboard.Drawing.OpenGL.Text | ||||
|                 throw new Exception("Font not found."); | ||||
|         } | ||||
| 
 | ||||
|         private DbBlurgFont InternFont(IFont font) | ||||
|         public DbBlurgFont InternFont(IFont font) | ||||
|         { | ||||
|             if (font is NamedFont named) | ||||
|             { | ||||
|  | ||||
							
								
								
									
										13
									
								
								Dashboard.ImmediateUI/Dashboard.ImmediateUI.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								Dashboard.ImmediateUI/Dashboard.ImmediateUI.csproj
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| <Project Sdk="Microsoft.NET.Sdk"> | ||||
| 
 | ||||
|     <PropertyGroup> | ||||
|         <TargetFramework>net8.0</TargetFramework> | ||||
|         <ImplicitUsings>disable</ImplicitUsings> | ||||
|         <Nullable>enable</Nullable> | ||||
|     </PropertyGroup> | ||||
| 
 | ||||
|     <ItemGroup> | ||||
|       <ProjectReference Include="..\Dashboard.Drawing\Dashboard.Drawing.csproj" /> | ||||
|     </ItemGroup> | ||||
| 
 | ||||
| </Project> | ||||
							
								
								
									
										157
									
								
								Dashboard.ImmediateUI/DimUI.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								Dashboard.ImmediateUI/DimUI.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,157 @@ | ||||
| using System; | ||||
| using System.Diagnostics.CodeAnalysis; | ||||
| using System.Drawing; | ||||
| using System.Net.Http; | ||||
| using System.Numerics; | ||||
| using System.Text; | ||||
| using Dashboard.Drawing; | ||||
| 
 | ||||
| namespace Dashboard.ImmediateUI | ||||
| { | ||||
|     public class DimUIConfig | ||||
|     { | ||||
|         public float Margin = 4f; | ||||
|         public float Padding = 4f; | ||||
| 
 | ||||
|         public required IFont Font { get; init; } | ||||
|         public IBrush TextBrush = new SolidBrush(Color.Black); | ||||
| 
 | ||||
|         public float ButtonBorderSize = 2f; | ||||
|         public IBrush ButtonBorderBrush = new SolidBrush(Color.DarkSlateGray); | ||||
|         public IBrush ButtonFillBrush = new SolidBrush(Color.SlateGray); | ||||
|         public IBrush? ButtonShadowBrush = new SolidBrush(Color.FromArgb(32, Color.LightSteelBlue)); | ||||
|         public float ButtonShadowOffset = 4f; | ||||
| 
 | ||||
|         public float InputBorderSize = 2f; | ||||
|         public IBrush InputPlaceholderTextBrush = new SolidBrush(Color.SlateGray); | ||||
|         public IBrush InputBorderBrush = new SolidBrush(Color.SlateGray); | ||||
|         public IBrush InputFillBrush = new SolidBrush(Color.LightGray); | ||||
|         public IBrush? InputShadowBrush = new SolidBrush(Color.FromArgb(32, Color.LightSteelBlue)); | ||||
|         public float InputShadowOffset = -4f; | ||||
| 
 | ||||
|         public float MenuBorderSize = 2f; | ||||
|         public IBrush MenuBorderBrush = new SolidBrush(Color.DarkSlateGray); | ||||
|         public IBrush MenuFillBrush = new SolidBrush(Color.SlateGray); | ||||
|         public IBrush? MenuShadowBrush = new SolidBrush(Color.FromArgb(32, Color.LightSteelBlue)); | ||||
|         public float MenuShadowOffset = 6f; | ||||
|     } | ||||
| 
 | ||||
|     public class DimUI | ||||
|     { | ||||
|         private readonly DimUIConfig _config; | ||||
|         private Vector2 _pen; | ||||
|         private Box2d _bounds; | ||||
|         private bool _firstLine = false; | ||||
|         private bool _sameLine = false; | ||||
|         private float _z = -1; | ||||
|         private float _lineHeight; | ||||
|         private DrawQueue _queue; | ||||
| 
 | ||||
|         public DimUI(DimUIConfig config) | ||||
|         { | ||||
|             _config = config; | ||||
|         } | ||||
| 
 | ||||
|         [MemberNotNull(nameof(_queue))] | ||||
|         public void Begin(Box2d bounds, DrawQueue queue) | ||||
|         { | ||||
|             _bounds = bounds; | ||||
|             _pen = _bounds.Min; | ||||
|             _queue = queue; | ||||
|             _firstLine = true; | ||||
|             _lineHeight = 0; | ||||
|             _z = -1; | ||||
|         } | ||||
| 
 | ||||
|         public void SameLine() | ||||
|         { | ||||
|             _sameLine = true; | ||||
|         } | ||||
| 
 | ||||
|         private void Line() | ||||
|         { | ||||
|             if (!_firstLine && !_sameLine) | ||||
|             { | ||||
|                 _pen = new Vector2(_bounds.Left, _pen.Y + _lineHeight); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 _firstLine = false; | ||||
|                 _sameLine = false; | ||||
|             } | ||||
| 
 | ||||
|             _pen.X += _config.Margin; | ||||
|             _lineHeight = 0; | ||||
|         } | ||||
| 
 | ||||
|         private float Z() | ||||
|         { | ||||
|             return _z += 0.001f; | ||||
|         } | ||||
| 
 | ||||
|         public void Text(string text) | ||||
|         { | ||||
|             Line(); | ||||
| 
 | ||||
|             SizeF sz = Typesetter.MeasureString(_config.Font, text); | ||||
|             float z = Z(); | ||||
|             float h = _config.Margin * 2 + sz.Height; | ||||
|             _queue.Text(new Vector3(_pen + new Vector2(0, _config.Margin), z), _config.TextBrush, text, _config.Font); | ||||
| 
 | ||||
|             _lineHeight = Math.Max(_lineHeight, h); | ||||
|             _pen.X += sz.Width; | ||||
|         } | ||||
| 
 | ||||
|         public bool Button(string label) | ||||
|         { | ||||
|             Line(); | ||||
| 
 | ||||
|             SizeF sz = Typesetter.MeasureString(_config.Font, label); | ||||
| 
 | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         public bool Input(string placeholder, StringBuilder value) | ||||
|         { | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         public void BeginMenu() | ||||
|         { | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         public bool MenuItem(string name) | ||||
|         { | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         public void EndMenu() | ||||
|         { | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         public int Id(ReadOnlySpan<char> str) | ||||
|         { | ||||
|             // Uses the FVN-1A algorithm in 32-bit mode. | ||||
|             const int PRIME = 0x01000193; | ||||
|             const int BASIS = unchecked((int)0x811c9dc5); | ||||
| 
 | ||||
|             int hash = BASIS; | ||||
|             for (int i = 0; i < str.Length; i++) | ||||
|             { | ||||
|                 hash ^= str[i] & 0xFF; | ||||
|                 hash *= PRIME; | ||||
|                 hash ^= str[i] >> 8; | ||||
|                 hash *= PRIME; | ||||
|             } | ||||
| 
 | ||||
|             return hash; | ||||
|         } | ||||
| 
 | ||||
|         public void Finish() | ||||
|         { | ||||
|             // TODO: | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -19,6 +19,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dashboard.Common", "Dashboa | ||||
| EndProject | ||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dashboard.Drawing.OpenGL", "Dashboard.Drawing.OpenGL\Dashboard.Drawing.OpenGL.csproj", "{454198BA-CB95-41C5-A934-B1C8FDA35A6B}" | ||||
| EndProject | ||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dashboard.ImmediateUI", "Dashboard.ImmediateUI\Dashboard.ImmediateUI.csproj", "{3F33197F-0B7B-4CD8-98BD-05D6D5EC76B2}" | ||||
| EndProject | ||||
| Global | ||||
| 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
| 		Debug|Any CPU = Debug|Any CPU | ||||
| @ -45,6 +47,10 @@ Global | ||||
| 		{454198BA-CB95-41C5-A934-B1C8FDA35A6B}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||
| 		{454198BA-CB95-41C5-A934-B1C8FDA35A6B}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||
| 		{454198BA-CB95-41C5-A934-B1C8FDA35A6B}.Release|Any CPU.Build.0 = Release|Any CPU | ||||
| 		{3F33197F-0B7B-4CD8-98BD-05D6D5EC76B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||
| 		{3F33197F-0B7B-4CD8-98BD-05D6D5EC76B2}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||
| 		{3F33197F-0B7B-4CD8-98BD-05D6D5EC76B2}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||
| 		{3F33197F-0B7B-4CD8-98BD-05D6D5EC76B2}.Release|Any CPU.Build.0 = Release|Any CPU | ||||
| 	EndGlobalSection | ||||
| 	GlobalSection(SolutionProperties) = preSolution | ||||
| 		HideSolutionNode = FALSE | ||||
|  | ||||
| @ -10,6 +10,7 @@ | ||||
|   <ItemGroup> | ||||
|     <ProjectReference Include="..\..\Dashboard.Drawing.OpenGL\Dashboard.Drawing.OpenGL.csproj" /> | ||||
|     <ProjectReference Include="..\..\Dashboard.Drawing\Dashboard.Drawing.csproj" /> | ||||
|     <ProjectReference Include="..\..\Dashboard.ImmediateUI\Dashboard.ImmediateUI.csproj" /> | ||||
|   </ItemGroup> | ||||
| 
 | ||||
|   <ItemGroup> | ||||
|  | ||||
| @ -3,17 +3,19 @@ using System.Drawing; | ||||
| using Dashboard; | ||||
| using Dashboard.Drawing.OpenGL; | ||||
| using Dashboard.Drawing.OpenGL.Text; | ||||
| using Dashboard.ImmediateUI; | ||||
| using OpenTK.Graphics; | ||||
| using OpenTK.Platform; | ||||
| using OpenTK.Graphics.OpenGL; | ||||
| using OpenTK.Mathematics; | ||||
| using Box2d = Dashboard.Box2d; | ||||
| using TK = OpenTK.Platform.Toolkit; | ||||
| using sys = System.Numerics; | ||||
| using otk = OpenTK.Mathematics; | ||||
| 
 | ||||
| TK.Init(new ToolkitOptions() | ||||
| { | ||||
|     ApplicationName = "Paper Punch Out!", | ||||
|     ApplicationName = "DashTerm", | ||||
|     Windows = new ToolkitOptions.WindowsOptions() | ||||
|     { | ||||
|         EnableVisualStyles = true, | ||||
| @ -39,11 +41,11 @@ WindowHandle wnd = TK.Window.Create(new OpenGLGraphicsApiHints() | ||||
| 
 | ||||
|     SupportTransparentFramebufferX11 = true, | ||||
| }); | ||||
| TK.Window.SetTitle(wnd, "Paper Punch Out!"); | ||||
| TK.Window.SetTitle(wnd, "DashTerm"); | ||||
| TK.Window.SetMinClientSize(wnd, 300, 200); | ||||
| TK.Window.SetClientSize(wnd, new Vector2i(320, 240)); | ||||
| TK.Window.SetBorderStyle(wnd, WindowBorderStyle.ResizableBorder); | ||||
| TK.Window.SetTransparencyMode(wnd, WindowTransparencyMode.TransparentFramebuffer, 0.1f); | ||||
| // TK.Window.SetTransparencyMode(wnd, WindowTransparencyMode.TransparentFramebuffer, 0.1f); | ||||
| 
 | ||||
| OpenGLContextHandle context = TK.OpenGL.CreateFromWindow(wnd); | ||||
| 
 | ||||
| @ -62,6 +64,10 @@ engine.Initialize(); | ||||
| 
 | ||||
| GlContext dbGlContext = new GlContext(wnd, context); | ||||
| ContextExecutor executor = engine.GetExecutor(dbGlContext); | ||||
| DimUI dimUI = new DimUI(new DimUIConfig() | ||||
| { | ||||
|     Font = new NamedFont("Noto Sans", 9f), | ||||
| }); | ||||
| 
 | ||||
| Vector2 mousePos = Vector2.Zero; | ||||
| Random r = new Random(); | ||||
| @ -78,19 +84,6 @@ EventQueue.EventRaised += (handle, type, eventArgs) => | ||||
|         case PlatformEventType.MouseMove: | ||||
|             mousePos = ((MouseMoveEventArgs)eventArgs).ClientPosition; | ||||
|             break; | ||||
|         case PlatformEventType.MouseUp: | ||||
|             MouseButtonUpEventArgs mouseUp = (MouseButtonUpEventArgs)eventArgs; | ||||
|             if (mouseUp.Button == MouseButton.Button1) | ||||
|             { | ||||
|                 SolidBrush brush = new SolidBrush(Color.FromArgb(r.Next(256), r.Next(256), r.Next(256), 0)); | ||||
|                 queue.Point(new sys::Vector2(mousePos.X, mousePos.Y), 0f, 24f, brush); | ||||
|             } | ||||
|             break; | ||||
|         case PlatformEventType.KeyDown: | ||||
|             KeyDownEventArgs keyDown = (KeyDownEventArgs)eventArgs; | ||||
|             if (keyDown.Key == Key.Escape || keyDown.Key == Key.Delete || keyDown.Key == Key.Backspace) | ||||
|                 queue.Clear(); | ||||
|             break; | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| @ -100,31 +93,74 @@ List<Vector3> points = new List<Vector3>(); | ||||
| 
 | ||||
| IFont font = Typesetter.LoadFont("Nimbus Mono", 12f); | ||||
| 
 | ||||
| queue.Text(new sys.Vector3(96, 96, 0), bg, "Hello World!", font); | ||||
| queue.Text(new sys.Vector3(128, 12, 0), bg, "japenis too! uwa ~~~ アホ", font); | ||||
| queue.Line(new sys.Vector2(64, 256), new sys.Vector2(64+256, 256), 0, 64f, fg); | ||||
| queue.Rect(new sys.Vector2(16, 16), new sys.Vector2(96, 96), 0, fg, bg, 8f); | ||||
| 
 | ||||
| while (!shouldExit) | ||||
| { | ||||
|     TK.Window.ProcessEvents(true); | ||||
| 
 | ||||
|     TK.Window.GetFramebufferSize(wnd, out Vector2i framebufferSize); | ||||
|     executor.BeginFrame(); | ||||
| 
 | ||||
|     // queue.Line(Vector3.Zero, new Vector3(System.Numerics.Vector2.One * 256f, 0), 4f, bg); | ||||
|     // queue.Rect(Vector3.UnitX, 2 * Vector3.UnitX + Vector3.UnitY, fg, bg, 2f); | ||||
|     dimUI.Begin(new Box2d(0, 0, framebufferSize.X, framebufferSize.Y), queue); | ||||
|     dimUI.Text("Hello World!"); | ||||
| 
 | ||||
|     dimUI.BeginMenu(); | ||||
| 
 | ||||
|     if (dimUI.MenuItem("File")) | ||||
|     { | ||||
|         dimUI.BeginMenu(); | ||||
|         dimUI.MenuItem("New Window"); | ||||
|         dimUI.MenuItem("Preferences"); | ||||
|         dimUI.MenuItem("Exit"); | ||||
|         dimUI.EndMenu(); | ||||
|     } | ||||
| 
 | ||||
|     if (dimUI.MenuItem("Edit")) | ||||
|     { | ||||
|         dimUI.BeginMenu(); | ||||
|         dimUI.MenuItem("Cut"); | ||||
|         dimUI.MenuItem("Copy"); | ||||
|         dimUI.MenuItem("Paste"); | ||||
| 
 | ||||
|         if (dimUI.MenuItem("Send Char")) | ||||
|         { | ||||
|             dimUI.BeginMenu(); | ||||
|             dimUI.EndMenu(); | ||||
|         } | ||||
| 
 | ||||
|         dimUI.EndMenu(); | ||||
|     } | ||||
| 
 | ||||
|     if (dimUI.MenuItem("View")) | ||||
|     { | ||||
|         dimUI.BeginMenu(); | ||||
|         dimUI.MenuItem("Clear"); | ||||
| 
 | ||||
|         if (dimUI.MenuItem("Set Size")) | ||||
|         { | ||||
|             dimUI.BeginMenu(); | ||||
|             dimUI.MenuItem("24 x 40"); | ||||
|             dimUI.MenuItem("25 x 40"); | ||||
|             dimUI.MenuItem("24 x 80"); | ||||
|             dimUI.MenuItem("25 x 80"); | ||||
|             dimUI.MenuItem("25 x 120"); | ||||
|             dimUI.EndMenu(); | ||||
|         } | ||||
| 
 | ||||
|         dimUI.EndMenu(); | ||||
|     } | ||||
| 
 | ||||
|     dimUI.Finish(); | ||||
| 
 | ||||
|     GL.Viewport(0, 0, framebufferSize.X, framebufferSize.Y); | ||||
|     GL.ClearColor(0.9f, 0.9f, 0.7f, 1.0f); | ||||
|     GL.ClearColor(0.3f, 0.3f, 0.3f, 1.0f); | ||||
|     GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); | ||||
|     GL.Disable(EnableCap.DepthTest); | ||||
|     // GL.Enable(EnableCap.Blend); | ||||
|     // GL.BlendFuncSeparate(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha, BlendingFactor.One, BlendingFactor.Zero); | ||||
|     GL.Enable(EnableCap.Blend); | ||||
|     GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); | ||||
|     GL.ColorMask(true, true, true, true); | ||||
| 
 | ||||
|     executor.Draw(queue); | ||||
|     executor.EndFrame(); | ||||
|     queue.Clear(); | ||||
| 
 | ||||
|     TK.OpenGL.SwapBuffers(context); | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user