VeldridImageRendering.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. using System.Collections;
  2. using System.Diagnostics;
  3. using System.Drawing;
  4. using System.Numerics;
  5. using System.Reflection;
  6. namespace Veldrid.Common
  7. {
  8. internal class VeldridImageRendering : BaseVeldridRender
  9. {
  10. private VeldridSpriteBatch spriteBatch;
  11. private Texture texture;
  12. private Shader[] shaders;
  13. public VeldridImageRendering(VeldridContent device) : base(device)
  14. {
  15. shaders = CreateShader("ImageRender");
  16. spriteBatch = new VeldridSpriteBatch(GraphicsDevice, GraphicsDevice.MainSwapchain.Framebuffer.OutputDescription, shaders, GraphicsDevice.PointSampler);
  17. }
  18. public BitmapData Bitmap
  19. {
  20. get => bitmap;
  21. set
  22. {
  23. if(bitmap!=value)
  24. {
  25. this[nameof(Bitmap)] = true;
  26. bitmap = value;
  27. if (bitmap.Height != 0 && bitmap.Width != 0)
  28. {
  29. InitTexture();
  30. }
  31. }
  32. }
  33. }
  34. private void InitTexture()
  35. {
  36. if (texture == null)
  37. {
  38. 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));
  39. }
  40. else if (texture.Height != Bitmap.Height || texture.Width != Bitmap.Width)
  41. {
  42. texture?.Dispose();
  43. 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));
  44. }
  45. GraphicsDevice.UpdateTexture(texture, Bitmap.Data, 0, 0, 0, texture.Width, texture.Height, 1, 0, 0);
  46. }
  47. internal override void CreateResources()
  48. {
  49. base.CreateResources();
  50. if (Bitmap.Height != 0 && Bitmap.Width != 0)
  51. {
  52. InitTexture();
  53. }
  54. }
  55. internal override void PreDraw()
  56. {
  57. if (texture == null)
  58. {
  59. return;
  60. }
  61. base.PreDraw();
  62. if (this[nameof(Bitmap), nameof(Range), nameof(Local)] || WindowSizeState)
  63. {
  64. spriteBatch.Begin();
  65. ImagePoint = GetImagePoint(Local);
  66. spriteBatch.ViewMatrix = Matrix4x4.CreateOrthographic(MainSwapchainBuffer.Width, MainSwapchainBuffer.Height, 0.01f, -100f);
  67. spriteBatch.Draw(texture, new RectangleF(ImagePoint, new SizeF(texture.Width, texture.Height)), Color.Empty, 2);
  68. spriteBatch.End();
  69. this[nameof(Bitmap), nameof(Range), nameof(Local)] = false;
  70. WindowSizeState = false;
  71. }
  72. }
  73. public override Vector2 VirtualSize => new Vector2(Bitmap.Width / MainSwapchainBuffer.Width, bitmap.Height / MainSwapchainBuffer.Height );
  74. private PointF local;
  75. private BitmapData bitmap = new BitmapData();
  76. public override PointF Local
  77. {
  78. get => local;
  79. set => Set(ref local, value);
  80. }
  81. public PointF ImagePoint { get; private set; }
  82. private PointF GetImagePoint(PointF point)
  83. {
  84. float x = MainSwapchainBuffer.Width * point.X - 0.5f * GraphicsDevice.MainSwapchain.Framebuffer.Width;
  85. float y = MainSwapchainBuffer.Height * (MainSwapchainBuffer.Height - point.Y) - 0.5f * GraphicsDevice.MainSwapchain.Framebuffer.Height;
  86. switch(VerticalAlignment)
  87. {
  88. case VerticalAlignment.Top:
  89. default:
  90. break;
  91. case VerticalAlignment.Bottom:
  92. y -= bitmap.Height;
  93. break;
  94. case VerticalAlignment.Center:
  95. y-= bitmap.Height/2;
  96. break;
  97. }
  98. switch (HorizontalAlignment)
  99. {
  100. case HorizontalAlignment.Left:
  101. default:
  102. break;
  103. case HorizontalAlignment.Center:
  104. x -= bitmap.Width / 2;
  105. break;
  106. case HorizontalAlignment.Right:
  107. x -= bitmap.Width;
  108. break;
  109. }
  110. return new PointF(x, y);
  111. }
  112. public VerticalAlignment VerticalAlignment { get; set; } = VerticalAlignment.Top;
  113. public HorizontalAlignment HorizontalAlignment { get; set; } = HorizontalAlignment.Left;
  114. internal override void DrawData()
  115. {
  116. if (texture == null) return;
  117. spriteBatch.DrawBatch(CommandList);
  118. }
  119. internal override void DisposeResources()
  120. {
  121. base.DisposeResources();
  122. texture?.Dispose();
  123. spriteBatch?.Dispose();
  124. Bitmap?.Dispose();
  125. }
  126. }
  127. }