ImagesRender.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Linq;
  5. using System.Numerics;
  6. using System.Text;
  7. namespace Veldrid.Common
  8. {
  9. public class ImagesRender : BaseVeldridRender
  10. {
  11. private bool cursorinfochanged = false;
  12. private VeldridSpriteBatch spriteBatch;
  13. private Texture texture;
  14. private Shader[] shaders;
  15. SizeF cursorSize;
  16. SizeF gridSize;
  17. int rowcount;
  18. int colcount;
  19. public ImagesRender(VeldridContent control,BitmapData bitmap, SizeF cursorsize,SizeF gridsize) : base(control)
  20. {
  21. if (bitmap.Width == 0 || bitmap.Height == 0 || bitmap.Data == null || bitmap.Data.Length == 0)
  22. {
  23. throw new Exception($"{nameof(bitmap)}中内容不能为空");
  24. }
  25. if (cursorsize.Width <= 0 || cursorsize.Height <= 0) throw new Exception($"图标尺寸不能为0");
  26. Bitmap = bitmap;
  27. this.cursorSize = cursorsize;
  28. gridSize = gridsize;
  29. shaders = CreateShader("ImageRender");
  30. spriteBatch = new VeldridSpriteBatch(GraphicsDevice, GraphicsDevice.MainSwapchain.Framebuffer.OutputDescription, shaders, GraphicsDevice.Aniso4xSampler);
  31. rowcount = (int)(Bitmap.Width / gridSize.Width);
  32. colcount = (int)(Bitmap.Height / gridSize.Height);
  33. ImageInfos.ItemAddEvent += ImageInfos_ItemAddEvent;
  34. }
  35. internal override void DrawData()
  36. {
  37. if (!Visibily || ImageInfos.All(x=>!x.Visibily)) return;
  38. spriteBatch.DrawBatch(CommandList);
  39. }
  40. internal override void CreateResources()
  41. {
  42. base.CreateResources();
  43. InitTexture();
  44. }
  45. internal override void DisposeResources()
  46. {
  47. spriteBatch?.Dispose();
  48. texture?.Dispose();
  49. ImageInfos?.Dispose();
  50. base.DisposeResources();
  51. }
  52. private void ImageInfos_ItemAddEvent(object sender, ImageInfo e)
  53. {
  54. e.PropertyChanged += (_, args) =>
  55. {
  56. cursorinfochanged = true;
  57. };
  58. }
  59. internal override void PreDraw()
  60. {
  61. base.PreDraw();
  62. if (WindowSizeState || cursorinfochanged)
  63. {
  64. spriteBatch.Begin();
  65. ImageInfos.ToList().OrderBy(x => x.ZIndex).ToList().ForEach(x =>
  66. {
  67. if (!x.Visibily || x.ImageIndex <0 || x.ImageIndex>=rowcount*colcount) return;
  68. var point = GetImagePoint(x.Position,x.VerticalAlignment,x.HorizontalAlignment);
  69. var srcpoint = new PointF(x.ImageIndex % rowcount * gridSize.Width + (gridSize.Width - cursorSize.Width) / 2, x.ImageIndex / rowcount * gridSize.Height + (gridSize.Height - cursorSize.Height) / 2);
  70. spriteBatch.ViewMatrix = Matrix4x4.CreateOrthographic(MainSwapchainBuffer.Width, MainSwapchainBuffer.Height, 0.01f, -100f);
  71. spriteBatch.Draw(texture, point,new RectangleF(srcpoint,cursorSize), Color.Empty, 0,Vector2.Zero,Vector2.One,1);
  72. });
  73. spriteBatch.End();
  74. WindowSizeState = false;
  75. cursorinfochanged = false;
  76. }
  77. }
  78. internal PointF GetImagePoint(Vector2 point,VerticalAlignment vertical,HorizontalAlignment horizontal)
  79. {
  80. float x = point.X + Margin.Left - 0.5f * GraphicsDevice.MainSwapchain.Framebuffer.Width;
  81. float y = (Range.MaxY - point.Y) + Margin.Top - 0.5f * GraphicsDevice.MainSwapchain.Framebuffer.Height;
  82. switch (vertical)
  83. {
  84. case VerticalAlignment.Top:
  85. default:
  86. break;
  87. case VerticalAlignment.Bottom:
  88. y -= cursorSize.Height;
  89. break;
  90. case VerticalAlignment.Center:
  91. y -= cursorSize.Height / 2;
  92. break;
  93. }
  94. switch (horizontal)
  95. {
  96. case HorizontalAlignment.Left:
  97. default:
  98. break;
  99. case HorizontalAlignment.Center:
  100. x -= cursorSize.Width / 2;
  101. break;
  102. case HorizontalAlignment.Right:
  103. x -= cursorSize.Width;
  104. break;
  105. }
  106. return new PointF(x, y);
  107. }
  108. public VeldridCollection<ImageInfo> ImageInfos { get; } = new VeldridCollection<ImageInfo>();
  109. private void InitTexture()
  110. {
  111. if (texture == null)
  112. {
  113. texture = ResourceFactory.CreateTexture(new TextureDescription((uint)Bitmap.Width, (uint)Bitmap.Height, 1, 1, 1, PixelFormat.B8_G8_R8_A8_UNorm_SRgb, TextureUsage.Sampled, TextureType.Texture2D));
  114. }
  115. else if (texture.Height != Bitmap.Height || texture.Width != Bitmap.Width)
  116. {
  117. texture?.Dispose();
  118. texture = ResourceFactory.CreateTexture(new TextureDescription((uint)Bitmap.Width, (uint)Bitmap.Height, 1, 1, 1, PixelFormat.B8_G8_R8_A8_UNorm_SRgb, TextureUsage.Sampled, TextureType.Texture2D));
  119. }
  120. GraphicsDevice.UpdateTexture(texture, Bitmap.Data, 0, 0, 0, texture.Width, texture.Height, 1, 0, 0);
  121. }
  122. public BitmapData Bitmap { get; }
  123. }
  124. public class ImageInfo : BaseProperty
  125. {
  126. private int imageIndex;
  127. private Vector2 position = Vector2.Zero;
  128. private HorizontalAlignment horizontalAlignment = HorizontalAlignment.Left;
  129. private VerticalAlignment verticalAlignment = VerticalAlignment.Center;
  130. private int zIndex;
  131. private bool visibily = true;
  132. public int ImageIndex { get => imageIndex; set => Set(ref imageIndex, value); }
  133. public Vector2 Position { get => position; set => Set(ref position, value); }
  134. public HorizontalAlignment HorizontalAlignment { get => horizontalAlignment; set => Set(ref horizontalAlignment, value); }
  135. public VerticalAlignment VerticalAlignment { get => verticalAlignment; set => Set(ref verticalAlignment, value); }
  136. public Boolean Visibily { get => visibily; set =>Set(ref visibily,value); }
  137. public int ZIndex { get => zIndex; set =>Set(ref zIndex,value); }
  138. }
  139. }