Text.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. using System.Numerics;
  2. using SixLabors.Fonts;
  3. using Veldrid;
  4. namespace TextRender
  5. {
  6. public class Text : DisposableManager
  7. {
  8. private TextRenderer _renderer;
  9. public Vector2 Position { get; set; }
  10. public float Angle { get; set; } = 270;
  11. public string Content { get; set; }
  12. public int FontSize { get; set; } = 12;
  13. public string FontName { get; set; } = "Arial";
  14. public FontStyle FontStyle { get; set; } = FontStyle.Regular;
  15. public RgbaFloat Color { get; set; } = RgbaFloat.White;
  16. public Font Font { get; protected set; }
  17. private DeviceBuffer vertexBuffer;
  18. private DeviceBuffer indexBuffer;
  19. private ResourceSet textureSet;
  20. private Texture texture;
  21. private TextureView textureView;
  22. private TextCache textCache;
  23. public TextRenderer Renderer => _renderer;
  24. public Text(TextRenderer renderer, string text)
  25. {
  26. Content = text;
  27. _renderer = renderer;
  28. }
  29. public void Initialize()
  30. {
  31. var device = _renderer.Device;
  32. var factory = device.ResourceFactory;
  33. BufferDescription vbDescription = new BufferDescription(
  34. 4 * VertexPositionTextureColor.SizeInBytes,
  35. BufferUsage.VertexBuffer);
  36. vertexBuffer = AddDisposable(factory.CreateBuffer(vbDescription));
  37. BufferDescription ibDescription = new BufferDescription(
  38. 4 * sizeof(ushort),
  39. BufferUsage.IndexBuffer);
  40. indexBuffer = AddDisposable(factory.CreateBuffer(ibDescription));
  41. var Size = new Vector2(100,100);
  42. var topLeft = new Vector2(0, 0);
  43. var topRight = new Vector2(0 + Size.X, 0);
  44. var bottomLeft = new Vector2(0, 0 + Size.Y);
  45. var bottomRight = new Vector2(0 + Size.X, 0 + Size.Y);
  46. VertexPositionTextureColor[] quadVertices =
  47. {
  48. new VertexPositionTextureColor(topLeft, new Vector2(0f, 0f), RgbaFloat.White),
  49. new VertexPositionTextureColor(topRight, new Vector2(1f, 0f), RgbaFloat.White),
  50. new VertexPositionTextureColor(bottomLeft, new Vector2(0f, 1f), RgbaFloat.White),
  51. new VertexPositionTextureColor(bottomRight, new Vector2(1f, 1f), RgbaFloat.White)
  52. };
  53. device.UpdateBuffer(vertexBuffer, 0, quadVertices);
  54. ushort[] quadIndices = { 0, 1, 2, 3 };
  55. device.UpdateBuffer(indexBuffer, 0, quadIndices);
  56. textCache = AddDisposable(new TextCache(device));
  57. Font = SystemFonts.CreateFont(FontName, FontSize, FontStyle);
  58. texture = AddDisposable(textCache.GetTextTexture(Content, Font, Color, Size));
  59. textureView = AddDisposable(device.ResourceFactory.CreateTextureView(texture));
  60. textureSet = AddDisposable(device.ResourceFactory.CreateResourceSet(new ResourceSetDescription(
  61. _renderer.Shader.TextureLayout,
  62. textureView,
  63. device.Aniso4xSampler)));
  64. }
  65. public void Recreate(Vector2 size)
  66. {
  67. Size = size;
  68. var device = _renderer.Device;
  69. if (texture != null)
  70. {
  71. RemoveAndDispose(ref textureView);
  72. RemoveAndDispose(ref texture);
  73. RemoveAndDispose(ref textCache);
  74. }
  75. var topLeft = new Vector2(0, 0);
  76. var topRight = new Vector2(0 + Size.X, 0);
  77. var bottomLeft = new Vector2(0, 0 + Size.Y);
  78. var bottomRight = new Vector2(0 + Size.X, 0 + Size.Y);
  79. VertexPositionTextureColor[] quadVertices =
  80. {
  81. new VertexPositionTextureColor(topLeft, new Vector2(0f, 0f), RgbaFloat.White),
  82. new VertexPositionTextureColor(topRight, new Vector2(1f, 0f), RgbaFloat.White),
  83. new VertexPositionTextureColor(bottomLeft, new Vector2(0f, 1f), RgbaFloat.White),
  84. new VertexPositionTextureColor(bottomRight, new Vector2(1f, 1f), RgbaFloat.White)
  85. };
  86. device.UpdateBuffer(vertexBuffer, 0, quadVertices);
  87. textCache = AddDisposable(new TextCache(device));
  88. Font = SystemFonts.CreateFont(FontName, FontSize, FontStyle);
  89. texture = AddDisposable(textCache.GetTextTexture(Content, Font, Color, size));
  90. textureView = AddDisposable(device.ResourceFactory.CreateTextureView(texture));
  91. textureSet = AddDisposable(device.ResourceFactory.CreateResourceSet(new ResourceSetDescription(
  92. _renderer.Shader.TextureLayout,
  93. textureView,
  94. device.Aniso4xSampler)));
  95. }
  96. Vector2 Size = new Vector2(31, 16);
  97. public void DrawBatched()
  98. {
  99. var cl = _renderer.CommandList;
  100. cl.UpdateBuffer(_renderer.Shader.ProjectionBuffer, 0,
  101. Matrix4x4.CreateOrthographicOffCenter(
  102. 0,
  103. _renderer.Framebuffer.Width,
  104. _renderer.Framebuffer.Height,
  105. 0, 0, 1));
  106. cl.UpdateBuffer(_renderer.Shader.WorldBuffer, 0,Matrix4x4.CreateRotationZ(Angle/180*MathF.PI,new Vector3(Size.X/2,Size.Y/2,0))* Matrix4x4.CreateTranslation(new Vector3(Position, 0)));
  107. cl.SetVertexBuffer(0, vertexBuffer);
  108. cl.SetIndexBuffer(indexBuffer, IndexFormat.UInt16);
  109. cl.SetGraphicsResourceSet(0, _renderer.Shader.ProjViewSet);
  110. cl.SetGraphicsResourceSet(1, textureSet);
  111. cl.DrawIndexed(
  112. indexCount: 4,
  113. instanceCount: 1,
  114. indexStart: 0,
  115. vertexOffset: 0,
  116. instanceStart: 0);
  117. }
  118. /// <summary>
  119. /// Render this text in a single draw call
  120. /// </summary>
  121. public void Draw()
  122. {
  123. _renderer.BeginDraw();
  124. DrawBatched();
  125. _renderer.EndDraw();
  126. }
  127. }
  128. }