LineAxis.cs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Linq;
  5. using System.Numerics;
  6. using System.Runtime.CompilerServices;
  7. using System.Text;
  8. namespace Veldrid.Common.Axis
  9. {
  10. public sealed class LineAxis : BaseVeldridRender,IZoomRender
  11. {
  12. public float HScale { get; set; } = 1;
  13. public float VScale { get; set; } = 1;
  14. public float HOffset { get; set; }
  15. public float VOffset { get; set; }
  16. public bool ZoomEnbled { get; set; } = true;
  17. public Vector2 WindowScale { get; set; } = Vector2.One;
  18. struct ProjView
  19. {
  20. public Matrix4x4 Proj;
  21. public Matrix4x4 View;
  22. }
  23. private ProjView projView;
  24. Pipeline borderpipeline;
  25. Pipeline pipeline;
  26. DeviceBuffer plotInfoBuffer;
  27. DeviceBuffer projViewBuffer;
  28. DeviceBuffer dataBuffer;
  29. ResourceLayout infoLayout;
  30. ResourceSet infoSet;
  31. Shader[] shaders;
  32. MutiText text;
  33. private object locker = new object();
  34. public LineAxis(VeldridContent control) : base(control)
  35. {
  36. Margin = new Padding(38, 8, 8, 18);
  37. text = new MutiText(control,true,true);
  38. text.CreateResources();
  39. text.FontSize = 10;
  40. text.TextInfos = Enumerable.Range(0, 22).Select(x => new TextInfo()).ToArray();
  41. text.Margin = new Padding(40,10,10,20);
  42. }
  43. internal override void DisposeResources()
  44. {
  45. base.DisposeResources();
  46. borderpipeline?.Dispose();
  47. pipeline?.Dispose();
  48. plotInfoBuffer?.Dispose();
  49. projViewBuffer?.Dispose();
  50. dataBuffer?.Dispose();
  51. infoLayout?.Dispose();
  52. infoSet?.Dispose();
  53. text?.DisposeResources();
  54. }
  55. internal override void CreateResources()
  56. {
  57. base.CreateResources();
  58. Vector2[] positon = new Vector2[5 + 44];
  59. positon[0] = new Vector2(Range.MinX, Range.MaxY);
  60. positon[1] = new Vector2(Range.MaxX, Range.MaxY);
  61. positon[2] = new Vector2(Range.MaxX, Range.MinY);
  62. positon[3] = new Vector2(Range.MinX, Range.MinY);
  63. positon[4] = positon[0];
  64. for (int i = 0; i < 11; i++)
  65. {
  66. positon[5 + i * 2] = new Vector2(Range.MinX + Range.XLenght / 10 * i, Range.MinY);
  67. positon[5 + i * 2 + 1] = new Vector2(Range.MinX + Range.XLenght / 10 * i, Range.MaxY);
  68. positon[5 + i * 2 + 22] = new Vector2(Range.MinX, Range.MinY + Range.YLenght / 10 * i);
  69. positon[5 + i * 2 + 1 + 22] = new Vector2(Range.MaxX, Range.MinY + Range.YLenght / 10 * i);
  70. }
  71. for (int i = 0; i < 11; i++)
  72. {
  73. text.TextInfos[i].Color = RgbaFloat.White;
  74. text.TextInfos[i].HorizontalAlignment = HorizontalAlignment.Center;
  75. text.TextInfos[i].VerticalAlignment = VerticalAlignment.Top;
  76. text.TextInfos[i].Local = new PointF(Range.MinX + i * (Range.XLenght / 10), Range.MinY);
  77. text.TextInfos[i + 11].Color = RgbaFloat.White;
  78. text.TextInfos[i + 11].HorizontalAlignment = HorizontalAlignment.Right;
  79. text.TextInfos[i + 11].VerticalAlignment = VerticalAlignment.Center;
  80. text.TextInfos[i + 11].Local = new PointF(Range.MinX-40, Range.MinY + i * (Range.YLenght / 10));
  81. text.TextInfos[i + 11].Text = i.ToString();
  82. }
  83. dataBuffer = ResourceFactory.CreateBuffer(new BufferDescription((uint)(Unsafe.SizeOf<Vector2>() * positon.Length), BufferUsage.VertexBuffer));
  84. GraphicsDevice.UpdateBuffer(dataBuffer, 0, positon);
  85. projViewBuffer = ResourceFactory.CreateBuffer(new BufferDescription((uint)Unsafe.SizeOf<ProjView>(), BufferUsage.UniformBuffer));
  86. plotInfoBuffer = ResourceFactory.CreateBuffer(new BufferDescription((uint)Unsafe.SizeOf<Vector4>() * 2, BufferUsage.UniformBuffer));
  87. GraphicsDevice.UpdateBuffer(plotInfoBuffer, 0, RgbaFloat.White);
  88. infoLayout = ResourceFactory.CreateResourceLayout(new ResourceLayoutDescription(
  89. new ResourceLayoutElementDescription("InfoBuffer", ResourceKind.UniformBuffer, ShaderStages.Vertex),
  90. new ResourceLayoutElementDescription("ProjView", ResourceKind.UniformBuffer, ShaderStages.Vertex)));
  91. infoSet = ResourceFactory.CreateResourceSet(new ResourceSetDescription(infoLayout, plotInfoBuffer, projViewBuffer));
  92. shaders = CreateShader("LineAxis");
  93. borderpipeline = CreatePipLine(PrimitiveTopology.LineStrip, infoLayout, new VertexLayoutDescription(new VertexElementDescription("In_Position", VertexElementFormat.Float2, VertexElementSemantic.TextureCoordinate)), shaders);
  94. pipeline = CreatePipLine(PrimitiveTopology.LineList, infoLayout, new VertexLayoutDescription(new VertexElementDescription("In_Position", VertexElementFormat.Float2, VertexElementSemantic.TextureCoordinate)), shaders);
  95. }
  96. public float LoopTime;
  97. public ulong TotalCount;
  98. public uint PlotDataLenght;
  99. private string GetTimeString(float time)
  100. {
  101. int s = (int)(time % 60);
  102. int m = (int)(time/60 % 60);
  103. int h = (int)(time / 3600);
  104. return string.Format("{0:D2}:{1:D2}:{2:D2}", h, m, s);
  105. }
  106. internal override void DrawData()
  107. {
  108. lock (locker)
  109. {
  110. float intert = Range.XLenght / PlotDataLenght;
  111. var total = TotalCount - HOffset / (MainSwapchainBuffer.Width/WindowScale.X) * TotalCount;
  112. float offset = (total * intert) % (Range.YLenght / 10);
  113. if (TotalCount <= PlotDataLenght) offset = 0;
  114. float totaltime = LoopTime * total / 1000/HScale;
  115. float plotime = LoopTime * PlotDataLenght / 1000 / 10/HScale;
  116. float maxtime = MathF.Ceiling(total / (PlotDataLenght / 10f)) * plotime;
  117. float mintime = maxtime - plotime * 11;
  118. base.DrawData();
  119. projView.Proj = base.OrthographicMatrix;
  120. projView.View = GetLineMatrix();
  121. CommandList.SetFramebuffer(MainSwapchainBuffer);
  122. CommandList.UpdateBuffer(projViewBuffer, 0, projView);
  123. CommandList.SetPipeline(pipeline);
  124. CommandList.UpdateBuffer(plotInfoBuffer, 0, new RgbaFloat(0.5f,0.5f,0.5f,1));
  125. CommandList.UpdateBuffer(plotInfoBuffer, (uint)Unsafe.SizeOf<Vector4>(), 0);
  126. CommandList.SetVertexBuffer(0, dataBuffer);
  127. CommandList.SetGraphicsResourceSet(0, infoSet);
  128. CommandList.Draw(22, 1, 5+22, 0);
  129. CommandList.UpdateBuffer(plotInfoBuffer, (uint)Unsafe.SizeOf<Vector4>(), offset);
  130. CommandList.Draw(22, 1, 5, 0);
  131. CommandList.SetPipeline(borderpipeline);
  132. CommandList.UpdateBuffer(plotInfoBuffer, 0, RgbaFloat.White);
  133. CommandList.UpdateBuffer(plotInfoBuffer, (uint)Unsafe.SizeOf<Vector4>(), 0f);
  134. CommandList.SetVertexBuffer(0, dataBuffer);
  135. CommandList.SetGraphicsResourceSet(0, infoSet);
  136. CommandList.Draw(5);
  137. CommandList.SetFramebuffer(MainSwapchainBuffer);
  138. float tempoffset = (VOffset * VScale) / Rectangle.Height * 10 * Range.YLenght + Range.MinY;
  139. for (int i = 0; i < 11; i++)
  140. {
  141. text.TextInfos[i].BackColor = RgbaFloat.Clear;
  142. text.TextInfos[i].Local = new PointF(Range.XLenght / 10 * i - offset, text.TextInfos[i].Local.Y);
  143. if (TotalCount <= PlotDataLenght)
  144. {
  145. text.TextInfos[i].Text = GetTimeString(i * plotime);
  146. }
  147. else
  148. {
  149. text.TextInfos[i].Text = GetTimeString(mintime + plotime * i);
  150. }
  151. text.TextInfos[i + 11].Text = Tools.SiHelper.ValueChangeToSI((Range.YLenght / 10 * i+tempoffset ) / VScale,out _,out _,1);
  152. }
  153. text.DrawData();
  154. }
  155. }
  156. public override void Resize()
  157. {
  158. base.Resize();
  159. text?.Resize();
  160. }
  161. }
  162. public sealed class LineAxisConfig:BaseProperty
  163. {
  164. public double Start { get; set; }
  165. public double End { get; set; }
  166. }
  167. }