123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 |
- using FontStashSharp.Interfaces;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using Vulkan;
- using System.Runtime.CompilerServices;
- using System.Numerics;
- using System.Drawing;
- namespace Veldrid.Common
- {
- internal class StashTextureManger : ITexture2DManager
- {
- Texture lastTexure;
- private GraphicsDevice _Graphics;
- public StashTextureManger(GraphicsDevice graphics)
- {
- _Graphics = graphics;
- }
- public Veldrid.Texture CreateTexture(int width, int height)
- {
- if (lastTexure == null || lastTexure.Width != width || lastTexure.Height != height)
- {
- lastTexure?.Dispose();
- lastTexure = _Graphics.ResourceFactory.CreateTexture(new TextureDescription((uint)width, (uint)height, 1, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Sampled, TextureType.Texture2D, TextureSampleCount.Count1));
- }
- return lastTexure;
- }
- public Size GetTextureSize(Veldrid.Texture texture)
- {
- var t = (Texture)texture;
- return new Size((Int32)t.Width, (Int32)t.Height);
- }
- public void SetTextureData(Veldrid.Texture texture, Rectangle bounds, byte[] data)
- {
- if(texture is Texture t)
- {
- _Graphics.UpdateTexture(t, data, (UInt32)bounds.X, (UInt32)bounds.Y, 0, (UInt32)bounds.Width, (UInt32)bounds.Height, 1, 0, 0);
- }
- }
- }
-
- internal class StashRenderer : IFontStashRenderer2,IDisposable
- {
- GraphicsDevice graphicsDevice;
- private const int MAX_SPRITES = 256;
- private const int MAX_VERTICES = MAX_SPRITES * 4;
- private const int MAX_INDICES = MAX_SPRITES * 6;
- private VertexPositionColorTexture[] _vertexData = new VertexPositionColorTexture[MAX_VERTICES];
- private Shader[] shaders;
- private CommandList _commandList;
- private DeviceBuffer _vertexBuffer;
- private DeviceBuffer _backColorBuffer;
- private DeviceBuffer _indexBuffer;
- private DeviceBuffer _matrixBuffer;
- private ResourceLayout _matrixLayout;
- private ResourceLayout _backColotLayout;
- private ResourceSet _matrixSet;
- private ResourceSet _backColorSet;
- private ResourceLayout _textureLayout;
- private ResourceSet _textureSet;
- private Pipeline _pipeline;
- private Pipeline _backColorPipline;
- private System.Numerics.Matrix4x4 Matrix { get; set; }
- private ushort[] _indexData;
- private Veldrid.Texture _lastTexture;
- private int _vertexIndex = 0;
- public StashRenderer(GraphicsDevice device,CommandList commandList, Shader[] textshader, Shader[] backColorshader,BlendStateDescription textBlend, BlendStateDescription backblendState)
- {
- graphicsDevice = device;
- _commandList = commandList;
- Matrix = System.Numerics.Matrix4x4.CreateOrthographicOffCenter(0, 1024, 1024, 0, 0, -1);
- _indexData = GenerateIndexArray();
- _vertexBuffer = graphicsDevice.ResourceFactory.CreateBuffer(new BufferDescription((UInt32)(Unsafe.SizeOf<VertexPositionColorTexture>() * _vertexData.Length), BufferUsage.VertexBuffer));
- _indexBuffer = graphicsDevice.ResourceFactory.CreateBuffer(new BufferDescription((UInt32)(Unsafe.SizeOf<short>() * _indexData.Length), BufferUsage.IndexBuffer));
- shaders = textshader;
- var vertexLayout = new VertexLayoutDescription(
- new VertexElementDescription("a_position", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float3),
- new VertexElementDescription("a_color", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float4),
- new VertexElementDescription("a_texCoords0", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2));
- _matrixBuffer = graphicsDevice.ResourceFactory.CreateBuffer(new BufferDescription((UInt32)(Unsafe.SizeOf<System.Numerics.Matrix4x4>()), BufferUsage.UniformBuffer));
- _matrixLayout = graphicsDevice.ResourceFactory.CreateResourceLayout(new ResourceLayoutDescription(new ResourceLayoutElementDescription("a_MatrixTransform", ResourceKind.UniformBuffer, ShaderStages.Vertex)));
- _matrixSet = graphicsDevice.ResourceFactory.CreateResourceSet(new ResourceSetDescription(_matrixLayout, _matrixBuffer));
- _backColorBuffer = graphicsDevice.ResourceFactory.CreateBuffer(new BufferDescription((uint)Unsafe.SizeOf<RgbaFloat>(), BufferUsage.UniformBuffer));
- _backColotLayout = graphicsDevice.ResourceFactory.CreateResourceLayout(new ResourceLayoutDescription(new ResourceLayoutElementDescription("a_color", ResourceKind.UniformBuffer, ShaderStages.Fragment)));
- _backColorSet = graphicsDevice.ResourceFactory.CreateResourceSet(new ResourceSetDescription(_backColotLayout, _backColorBuffer));
- _textureLayout = graphicsDevice.ResourceFactory.CreateResourceLayout(
- new ResourceLayoutDescription(
- new ResourceLayoutElementDescription("Texture", ResourceKind.TextureReadOnly, ShaderStages.Fragment),
- new ResourceLayoutElementDescription("TextureSampler", ResourceKind.Sampler, ShaderStages.Fragment)
- ));
-
- texture2DManager = new StashTextureManger(graphicsDevice);
- GraphicsPipelineDescription pipelineDescription = new GraphicsPipelineDescription();
- pipelineDescription.BlendState = textBlend;
- pipelineDescription.DepthStencilState = new DepthStencilStateDescription(
- depthTestEnabled: true,
- depthWriteEnabled: true,
- comparisonKind: ComparisonKind.GreaterEqual);
- pipelineDescription.RasterizerState = new RasterizerStateDescription(
- cullMode: FaceCullMode.Back,
- fillMode: PolygonFillMode.Solid,
- frontFace: FrontFace.Clockwise,
- depthClipEnabled: true,
- scissorTestEnabled: false);
- pipelineDescription.PrimitiveTopology = PrimitiveTopology.TriangleList;
- pipelineDescription.ResourceLayouts = new ResourceLayout[] {_matrixLayout,_textureLayout };
- pipelineDescription.ShaderSet = new ShaderSetDescription(
- vertexLayouts: new VertexLayoutDescription[] {vertexLayout },
- shaders: shaders,
- specializations: new[] { new SpecializationConstant(0,graphicsDevice.IsClipSpaceYInverted) });
- pipelineDescription.Outputs = graphicsDevice.SwapchainFramebuffer.OutputDescription;
- _pipeline = graphicsDevice.ResourceFactory.CreateGraphicsPipeline(pipelineDescription);
- _backColorPipline = graphicsDevice.ResourceFactory.CreateGraphicsPipeline(new GraphicsPipelineDescription()
- {
- BlendState = backblendState,
- DepthStencilState = new DepthStencilStateDescription()
- {
- DepthTestEnabled= true,
- DepthWriteEnabled= true,
- DepthComparison = ComparisonKind.LessEqual
- },
- RasterizerState = new RasterizerStateDescription()
- {
- CullMode = FaceCullMode.Back,
- FillMode = PolygonFillMode.Solid,
- FrontFace = FrontFace.Clockwise,
- DepthClipEnabled= true,
- ScissorTestEnabled = false,
- },
- PrimitiveTopology= PrimitiveTopology.TriangleStrip,
- ResourceLayouts = new ResourceLayout[] {_matrixLayout,_backColotLayout },
- ShaderSet = new ShaderSetDescription()
- {
- Shaders = backColorshader,
- Specializations = new[] {new SpecializationConstant(0,graphicsDevice.IsClipSpaceYInverted) },
- VertexLayouts = new VertexLayoutDescription[] { vertexLayout},
- },
- Outputs = graphicsDevice.SwapchainFramebuffer.OutputDescription,
- });
- }
-
- private ushort[] GenerateIndexArray()
- {
- ushort[] result = new ushort[MAX_INDICES];
- for (int i = 0, j = 0; i < MAX_INDICES; i += 6, j += 4)
- {
- result[i] = (ushort)(j);
- result[i + 1] = (ushort)(j + 1);
- result[i + 2] = (ushort)(j + 2);
- result[i + 3] = (ushort)(j + 3);
- result[i + 4] = (ushort)(j + 2);
- result[i + 5] = (ushort)(j + 1);
- }
- return result;
- }
- public RgbaFloat BackColor { get; set; } = RgbaFloat.Clear;
- public void Begin()
- {
- }
- private ITexture2DManager texture2DManager;
- private bool disposedValue;
- internal Texture Texture => _lastTexture;
- ITexture2DManager IFontStashRenderer2.TextureManager => texture2DManager;
- unsafe void IFontStashRenderer2.DrawQuad(Veldrid.Texture texture, ref VertexPositionColorTexture topLeft, ref VertexPositionColorTexture topRight, ref VertexPositionColorTexture bottomLeft, ref VertexPositionColorTexture bottomRight)
- {
- if (_lastTexture != texture)
- {
- FlushBuffer();
- }
- _vertexData[_vertexIndex++] = topLeft;
- _vertexData[_vertexIndex++] = topRight;
- _vertexData[_vertexIndex++] = bottomLeft;
- _vertexData[_vertexIndex++] = bottomRight;
- _lastTexture = texture;
- }
- private unsafe void FlushBuffer()
- {
- if(_vertexIndex ==0|| _lastTexture ==null)
- {
- return;
- }
- if(_textureSet ==null)
- {
- _textureSet = graphicsDevice.ResourceFactory.CreateResourceSet(new ResourceSetDescription(_textureLayout, (Texture)_lastTexture, graphicsDevice.LinearSampler));
- }
- //
- uint count = (UInt32)_vertexIndex * 6 / 4;
- if (BackColor.A > 0)
- {
- _commandList.UpdateBuffer(_backColorBuffer, 0, BackColor);
- var rectdata = _indexData.Take((int)count).Distinct().Select(x => _vertexData[x]);
- RectangleF rec = new RectangleF();
- rec.X = rectdata.Min(x => x.Position.X) - 2;
- rec.Y = rectdata.Min(y => y.Position.Y) - 2;
- rec.Width = rectdata.Max(x => x.Position.X) - rec.X + 2;
- rec.Height = rectdata.Max(y => y.Position.Y) - rec.Y + 2;
- if (BackColorFixedSize.Width > 0 && BackColorFixedSize.Height > 0)
- {
- rec.Width = BackColorFixedSize.Width;
- rec.Height = BackColorFixedSize.Height;
- }
- VertexPositionColorTexture[] temp = new VertexPositionColorTexture[4];
- temp[0].Position = new Vector3(rec.X, rec.Y, _vertexData[0].Position.Z);
- temp[1].Position = new Vector3(rec.X + rec.Width, rec.Y, _vertexData[0].Position.Z);
- temp[2].Position = new Vector3(rec.X, rec.Y + rec.Height, _vertexData[0].Position.Z);
- temp[3].Position = new Vector3(rec.X + rec.Width, rec.Y + rec.Height, _vertexData[0].Position.Z);
- _commandList.UpdateBuffer(_vertexBuffer, 0, temp);
- //_commandList.UpdateBuffer(_indexBuffer, 0, backcolorindex);
- _commandList.SetPipeline(_backColorPipline);
- _commandList.SetVertexBuffer(0, _vertexBuffer);
- //_commandList.SetIndexBuffer(_indexBuffer, IndexFormat.UInt16);
- _commandList.SetGraphicsResourceSet(0, _matrixSet);
- _commandList.SetGraphicsResourceSet(1, _backColorSet);
- _commandList.Draw(4);
- }
- _commandList.UpdateBuffer(_matrixBuffer, 0, Matrix);
- _commandList.UpdateBuffer(_indexBuffer, 0, _indexData);
- _commandList.UpdateBuffer(_vertexBuffer, 0, _vertexData);
- _commandList.SetPipeline(_pipeline);
- _commandList.SetVertexBuffer(0, _vertexBuffer);
- _commandList.SetIndexBuffer(_indexBuffer, IndexFormat.UInt16);
- _commandList.SetGraphicsResourceSet(0, _matrixSet);
- _commandList.SetGraphicsResourceSet(1, _textureSet);
- _commandList.DrawIndexed(count, 1, 0, 0, 0);
- _vertexIndex = 0;
- }
- public SizeF BackColorFixedSize { get; set; } = SizeF.Empty;
- public void End()
- {
- Matrix =Matrix4x4.CreateOrthographicOffCenter(0,graphicsDevice.MainSwapchain.Framebuffer.Width,graphicsDevice.MainSwapchain.Framebuffer.Height,0,0,-1);
- FlushBuffer();
- }
- public void End(Matrix4x4 matrix)
- {
- Matrix= matrix;
- FlushBuffer();
- }
- protected virtual void Dispose(bool disposing)
- {
- if (!disposedValue)
- {
- if (disposing)
- {
- _indexData = new UInt16[0];
- _vertexData = new VertexPositionColorTexture[0];
- //foreach (var val in shaders) val?.Dispose();
- _vertexBuffer?.Dispose();
- _indexBuffer?.Dispose();
- (_lastTexture as Texture)?.Dispose();
- _matrixBuffer?.Dispose();
- _matrixSet?.Dispose();
- _pipeline?.Dispose();
- _textureLayout?.Dispose();
- _textureSet?.Dispose();
- _backColorBuffer?.Dispose();
- _backColorPipline?.Dispose();
- _backColorSet?.Dispose();
- _backColotLayout?.Dispose();
- // TODO: 释放托管状态(托管对象)
- }
- // TODO: 释放未托管的资源(未托管的对象)并重写终结器
- // TODO: 将大型字段设置为 null
- disposedValue = true;
- }
- }
- // // TODO: 仅当“Dispose(bool disposing)”拥有用于释放未托管资源的代码时才替代终结器
- // ~StashRenderer()
- // {
- // // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
- // Dispose(disposing: false);
- // }
- public void Dispose()
- {
- // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
- Dispose(disposing: true);
- GC.SuppressFinalize(this);
- }
- }
- }
|