BaseVeldridRender.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Diagnostics;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Numerics;
  8. using System.Reflection;
  9. using System.Runtime.CompilerServices;
  10. using System.Runtime.InteropServices;
  11. using System.Text;
  12. using System.Threading.Tasks;
  13. namespace Veldrid.Common
  14. {
  15. [StructLayout(LayoutKind.Sequential, Pack = 1)]
  16. public struct Padding
  17. {
  18. public float Left;
  19. public float Top;
  20. public float Right;
  21. public float Bottom;
  22. public Padding(float left = 0, float top = 0, float right = 0, float bottom = 0)
  23. {
  24. Left = left;
  25. Top = top;
  26. Right = right;
  27. Bottom = bottom;
  28. }
  29. public Padding(float all = 0) : this(all, all, all, all)
  30. {
  31. }
  32. public static Padding Zero { get; } = new Padding();
  33. public static UInt32 Size { get; } = (uint)Unsafe.SizeOf<Padding>();
  34. }
  35. public abstract class BaseVeldridRender
  36. {
  37. internal Matrix4x4 OrthographicMatrix { get; private set; }
  38. private Matrix4x4 _ymirror = new Matrix4x4(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
  39. internal Matrix4x4 GetLineMatrix(float h = 1, float v = 1,float hoffset=0,float voffset=0)
  40. {
  41. float windowwidth = MainSwapchainBuffer.Width;
  42. float windowheight = MainSwapchainBuffer.Height;
  43. float width = windowwidth - (Margin.Left + Margin.Right);
  44. float height = windowheight - (Margin.Top + Margin.Bottom);
  45. float hscale = width / Range.XLenght * h;
  46. float vscale = height / Range.YLenght * v;
  47. var tran = Matrix4x4.CreateTranslation(0, -1 + (height / windowheight - 1), 0);
  48. return Matrix4x4.CreateScale(hscale, vscale, 1, new Vector3(-1, 1, 0)) * tran * Matrix4x4.CreateTranslation(Margin.Left * 2 / windowwidth, Margin.Top * 2 / windowheight, 0) * (!GraphicsDevice.IsClipSpaceYInverted ? _ymirror : Matrix4x4.Identity)*Matrix4x4.CreateTranslation(hoffset, voffset, 0);
  49. }
  50. public virtual void Resize()
  51. {
  52. OrthographicMatrix = GetProjMatrix();
  53. }
  54. public LineRange Range { get; } = new LineRange(0, 10000, -5000, 5000);
  55. public SizeF ContentSize => new SizeF(MainSwapchainBuffer.Width - Margin.Left - Margin.Right, MainSwapchainBuffer.Height - Margin.Top - Margin.Bottom);
  56. private protected Matrix4x4 GetProjMatrix()
  57. {
  58. return Matrix4x4.CreateOrthographicOffCenter(0, MainSwapchainBuffer.Width, MainSwapchainBuffer.Height, 0, 0, -1);
  59. }
  60. protected Object _Locker = new Object();
  61. public Boolean IsDisposed { get; protected set; } = false;
  62. protected CommandList CommandList { get; }
  63. private ShaderManger ShaderManger { get; }
  64. protected Framebuffer MainSwapchainBuffer => GraphicsDevice.MainSwapchain.Framebuffer;
  65. public Boolean WindowSizeState { get; set; } = true;
  66. private Dictionary<string, bool> propertyChangedDictionary = new Dictionary<string, bool>();
  67. internal GraphicsDevice GraphicsDevice { get; }
  68. internal Vector2 WindowSize => new Vector2(GraphicsDevice.MainSwapchain.Framebuffer.Width, GraphicsDevice.MainSwapchain.Framebuffer.Height);
  69. private protected ResourceFactory ResourceFactory => GraphicsDevice.ResourceFactory;
  70. private bool TryGetPropertyState(string propertyName)
  71. {
  72. if (String.IsNullOrEmpty(propertyName))
  73. {
  74. return false;
  75. }
  76. if (propertyChangedDictionary.TryGetValue(propertyName, out var result))
  77. {
  78. return result;
  79. }
  80. propertyChangedDictionary[propertyName] = false;
  81. return false;
  82. }
  83. public RectangleF Rectangle => new RectangleF(Margin.Left, Margin.Top, ContentSize.Width, ContentSize.Height);
  84. public virtual bool Contains(PointF point)
  85. {
  86. if (!Visibily) return false;
  87. RectangleF rectangle = new RectangleF(Local, new SizeF(VirtualSize.X, VirtualSize.Y));
  88. return rectangle.Contains(point);
  89. }
  90. public Padding Margin { get; set; }
  91. public virtual PointF Local
  92. {
  93. get;
  94. set;
  95. }
  96. public virtual System.Numerics.Vector2 VirtualSize { get; }
  97. internal protected Boolean this[params string[] propertyNames]
  98. {
  99. get
  100. {
  101. if (propertyNames == null || propertyNames.Length == 0)
  102. {
  103. return false;
  104. }
  105. if (propertyNames.Length == 1)
  106. {
  107. return TryGetPropertyState(propertyNames[0]);
  108. }
  109. return propertyNames.Select(x => TryGetPropertyState(x)).Any(x => x);
  110. }
  111. set
  112. {
  113. if (propertyNames == null || propertyNames.Length == 0)
  114. {
  115. return;
  116. }
  117. foreach (var name in propertyNames.Where(x => !string.IsNullOrEmpty(x)))
  118. {
  119. propertyChangedDictionary[name] = value;
  120. }
  121. }
  122. }
  123. public BaseVeldridRender(VeldridContent control)
  124. {
  125. GraphicsDevice = control.GraphicsManger.Device;
  126. CommandList = control.GraphicsManger.CommandList;
  127. ShaderManger = control.GraphicsManger.ShaderManger;
  128. Resize();
  129. }
  130. protected void Set<T>(ref T field, T value, [CallerMemberName] string propertyName = "")
  131. {
  132. if (object.Equals(field, value))
  133. {
  134. return;
  135. }
  136. field = value;
  137. this[propertyName] = true;
  138. Update(propertyName, value);
  139. }
  140. internal virtual void CreateResources()
  141. {
  142. IsDisposed = false;
  143. }
  144. internal virtual void PreDraw()
  145. {
  146. }
  147. internal void Draw()
  148. {
  149. lock (_Locker)
  150. {
  151. if (Visibily && !IsDisposed)
  152. {
  153. PreDraw();
  154. DrawData();
  155. PosDraw();
  156. }
  157. }
  158. }
  159. internal virtual void DrawData()
  160. {
  161. }
  162. internal virtual void PosDraw()
  163. {
  164. }
  165. internal virtual void DisposeResources()
  166. {
  167. IsDisposed = true;
  168. }
  169. internal virtual void Update(string propertyName, object value)
  170. {
  171. }
  172. private protected DeviceBuffer CreateVertexBuffer<T>(T[] value) where T : unmanaged
  173. {
  174. var buffer = GraphicsDevice.ResourceFactory.CreateBuffer(new BufferDescription((uint)(value.LongLength * Unsafe.SizeOf<T>()), BufferUsage.VertexBuffer));
  175. GraphicsDevice.UpdateBuffer(buffer, 0, value);
  176. return buffer;
  177. }
  178. private protected DeviceBuffer CreateIndexBuffer(ushort[] index)
  179. {
  180. var buffer = ResourceFactory.CreateBuffer(new BufferDescription((uint)(index.LongLength * Unsafe.SizeOf<ushort>()), BufferUsage.IndexBuffer));
  181. GraphicsDevice.UpdateBuffer(buffer, 0, index);
  182. return buffer;
  183. }
  184. private protected DeviceBuffer CreateIndexBuffer(uint[] index)
  185. {
  186. var buffer = ResourceFactory.CreateBuffer(new BufferDescription((uint)(index.LongLength * Unsafe.SizeOf<uint>()), BufferUsage.IndexBuffer));
  187. GraphicsDevice.UpdateBuffer(buffer, 0, index);
  188. return buffer;
  189. }
  190. private protected Shader[] CreateShader(string name)
  191. {
  192. return ShaderManger.GetShaders(name);
  193. }
  194. private protected Shader GetLocalFileShader(string path, string entrypoint = "main", ShaderStages stages = ShaderStages.Vertex) => ShaderManger.GetLocalFileShader(path, entrypoint, stages);
  195. private protected Shader GetOtherShader(string name, ShaderStages stages = ShaderStages.Geometry, string entrypoints = "main")
  196. {
  197. return ShaderManger.GetOtherShader(name, stages, entrypoints);
  198. }
  199. private protected Pipeline CreatePipLine(PrimitiveTopology primitiveTopology,
  200. ResourceLayout layout,
  201. VertexLayoutDescription vertexLayout,
  202. Shader[] shaders,
  203. BlendStateDescription? blend = null,
  204. bool depthTestEnabled = true,
  205. OutputDescription? outputDescription = null,
  206. FrontFace frontFace = FrontFace.Clockwise)
  207. {
  208. return CreatePipLine(primitiveTopology, new ResourceLayout[] { layout }, new VertexLayoutDescription[] { vertexLayout }, shaders, blend, depthTestEnabled, outputDescription, frontFace);
  209. }
  210. private protected Pipeline CreatePipLine(PrimitiveTopology primitiveTopology,
  211. ResourceLayout[] layouts,
  212. VertexLayoutDescription[] vertexLayouts,
  213. Shader[] shaders,
  214. BlendStateDescription? blend = null,
  215. bool depthTestEnabled = true,
  216. OutputDescription? outputDescription = null,
  217. FrontFace frontFace = FrontFace.Clockwise)
  218. {
  219. GraphicsPipelineDescription pipelineDescription = new GraphicsPipelineDescription();
  220. pipelineDescription.BlendState = blend ?? BlendStateDescription.SingleAlphaBlend;
  221. pipelineDescription.DepthStencilState = new DepthStencilStateDescription(
  222. depthTestEnabled: depthTestEnabled,
  223. depthWriteEnabled: true,
  224. comparisonKind: ComparisonKind.LessEqual);
  225. pipelineDescription.RasterizerState = new RasterizerStateDescription(
  226. cullMode: FaceCullMode.Back,
  227. fillMode: PolygonFillMode.Solid,
  228. frontFace: frontFace,
  229. depthClipEnabled: true,
  230. scissorTestEnabled: false);
  231. pipelineDescription.PrimitiveTopology = primitiveTopology;
  232. pipelineDescription.ResourceLayouts = layouts;
  233. pipelineDescription.Outputs = outputDescription ?? GraphicsDevice.SwapchainFramebuffer.OutputDescription;
  234. pipelineDescription.ShaderSet = new ShaderSetDescription(
  235. vertexLayouts: vertexLayouts,
  236. shaders: shaders,
  237. specializations: new[] { new SpecializationConstant(0, GraphicsDevice.IsClipSpaceYInverted) });
  238. return ResourceFactory.CreateGraphicsPipeline(pipelineDescription);
  239. }
  240. public bool Visibily { get; set; } = true;
  241. }
  242. }