wpf使用Direct2D绘制曲线
···
Install-Package SharpDX
Install-Package SharpDX.Direct2D1
Install-Package SharpDX.DXGI
Install-Package SharpDX.Direct3D11
···
- <Window x:Class="WpfApp2.MainWindow"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:local="clr-namespace:WpfApp2"
- mc:Ignorable="d"
- Title="MainWindow" Height="450" Width="800">
- <Grid>
- <Image Name="DxImage"/>
- </Grid>
- </Window>
复制代码- using System;
- using System.Windows;
- using System.Windows.Interop;
- using SharpDX;
- using SharpDX.Direct2D1;
- using SharpDX.Direct3D11;
- using SharpDX.DXGI;
- using SharpDX.Mathematics.Interop;
- using Device = SharpDX.Direct3D11.Device;
- using Factory = SharpDX.Direct2D1.Factory;
- using AlphaModeD2D = SharpDX.Direct2D1.AlphaMode;
- using PixelFormat = SharpDX.Direct2D1.PixelFormat;
- using SolidColorBrush = SharpDX.Direct2D1.SolidColorBrush;
- using SharpDX.DirectWrite;
- using System.Windows.Media;
- using TextAlignment = SharpDX.DirectWrite.TextAlignment;
- using FactoryType = SharpDX.Direct2D1.FactoryType;
- using TextAntialiasMode = SharpDX.Direct2D1.TextAntialiasMode;
- using System.Numerics;
- using DashStyle = SharpDX.Direct2D1.DashStyle;
- using PathGeometry = SharpDX.Direct2D1.PathGeometry;
- using static System.Net.Mime.MediaTypeNames;
- using SharpDX.Mathematics.Interop;
- using SharpDX;
- using SharpDX.Direct2D1;
- using SharpDX.Mathematics.Interop;
- using System.Security.Cryptography.Xml;
- using System.Windows.Media.Media3D;
- namespace WpfApp2
- {
- public partial class MainWindow : Window
- {
- private Device device;
- private SwapChain swapChain;
- private RenderTarget renderTarget;
- private Factory factory;
- private SharpDX.DirectWrite.Factory writeFactory;
- private TextFormat textFormat;
- private bool isResizing = false;
- private StrokeStyle strokeStyle;
- public MainWindow()
- {
- InitializeComponent();
- Loaded += OnLoaded;
- Unloaded += OnUnloaded;
- SizeChanged += OnSizeChanged;
- }
- private void OnLoaded(object sender, RoutedEventArgs e)
- {
- InitializeSharpDX();
- CompositionTarget.Rendering += OnRendering;
- }
- private void OnUnloaded(object sender, RoutedEventArgs e)
- {
- CompositionTarget.Rendering -= OnRendering;
- DisposeResources();
- }
- private void InitializeSharpDX()
- {
- factory = new Factory(FactoryType.SingleThreaded);
- writeFactory = new SharpDX.DirectWrite.Factory();
- var swapChainDescription = new SwapChainDescription
- {
- BufferCount = 1,
- ModeDescription = new ModeDescription((int)ActualWidth, (int)ActualHeight, new Rational(60, 1), Format.B8G8R8A8_UNorm),
- IsWindowed = true,
- OutputHandle = new WindowInteropHelper(this).Handle,
- SampleDescription = new SampleDescription(1, 0),
- SwapEffect = SwapEffect.Discard,
- Usage = Usage.RenderTargetOutput
- };
- Device.CreateWithSwapChain(SharpDX.Direct3D.DriverType.Hardware, DeviceCreationFlags.BgraSupport, swapChainDescription, out device, out swapChain);
- UpdateTextFormat();
- CreateRenderTarget();
- CreateStrokeStyle();
- }
- private void UpdateTextFormat()
- {
- textFormat?.Dispose();
- float fontSize = (float)(Math.Min(ActualWidth, ActualHeight) * 0.02);
- textFormat = new TextFormat(writeFactory, "Arial", fontSize)
- {
- TextAlignment = TextAlignment.Center,
- ParagraphAlignment = ParagraphAlignment.Center
- };
- }
- private void CreateRenderTarget()
- {
- using (var surface = swapChain.GetBackBuffer<Surface>(0))
- {
- var properties = new RenderTargetProperties(new PixelFormat(Format.Unknown, AlphaModeD2D.Premultiplied));
- renderTarget = new RenderTarget(factory, surface, properties)
- {
- AntialiasMode = AntialiasMode.PerPrimitive,
- TextAntialiasMode = TextAntialiasMode.Cleartype
- };
- }
- }
- private void CreateStrokeStyle()
- {
- strokeStyle?.Dispose();
- strokeStyle = new StrokeStyle(factory, new StrokeStyleProperties
- {
- DashStyle = DashStyle.Solid,
- LineJoin = LineJoin.Round,
- StartCap = CapStyle.Round,
- EndCap = CapStyle.Round
- });
- }
- private void OnSizeChanged(object sender, SizeChangedEventArgs e)
- {
- if (swapChain != null && !isResizing)
- {
- isResizing = true;
- try
- {
- renderTarget?.Dispose();
- swapChain.ResizeBuffers(1, (int)ActualWidth, (int)ActualHeight, Format.B8G8R8A8_UNorm, SwapChainFlags.None);
- CreateRenderTarget();
- UpdateTextFormat();
- }
- finally
- {
- isResizing = false;
- }
- }
- }
- private void OnRendering(object sender, EventArgs e)
- {
- if (renderTarget == null || isResizing)
- return;
- renderTarget.BeginDraw();
- DrawScene();
- renderTarget.EndDraw();
- swapChain.Present(1, PresentFlags.None);
- }
- private void DrawScene()
- {
- renderTarget.Clear(new RawColor4(1, 1, 1, 1));
- using (var axisBrush = new SolidColorBrush(renderTarget, new RawColor4(0, 0, 0, 1)))
- using (var lineBrush = new SolidColorBrush(renderTarget, new RawColor4(1, 0, 0, 1)))
- using (var textBrush = new SolidColorBrush(renderTarget, new RawColor4(0, 0, 0, 1)))
- {
- float width = (float)renderTarget.Size.Width;
- float height = (float)renderTarget.Size.Height;
- float margin = Math.Min(width, height) * 0.1f;
- float axisLength = Math.Min(width, height) * 0.8f;
- float lineWidth = 1.5f;
- // Draw X-axis
- renderTarget.DrawLine(
- AlignToPixel(new RawVector2(margin, height / 2)),
- AlignToPixel(new RawVector2(width - margin, height / 2)),
- axisBrush, lineWidth, strokeStyle);
- // Draw Y-axis
- renderTarget.DrawLine(
- AlignToPixel(new RawVector2(width / 2, margin)),
- AlignToPixel(new RawVector2(width / 2, height - margin)),
- axisBrush, lineWidth, strokeStyle);
- // Draw X-axis ticks and labels
- for (int i = -4; i <= 4; i++)
- {
- float x = width / 2 + i * axisLength / 8;
- renderTarget.DrawLine(
- AlignToPixel(new RawVector2(x, height / 2 - 5)),
- AlignToPixel(new RawVector2(x, height / 2 + 5)),
- axisBrush, 1.0f, strokeStyle);
- using (var textLayout = new TextLayout(writeFactory, i.ToString(), textFormat, 50, 20))
- {
- renderTarget.DrawTextLayout(new RawVector2(x - 25, height / 2 + 10), textLayout, textBrush);
- }
- }
- // Draw Y-axis ticks and labels
- for (int i = -4; i <= 4; i++)
- {
- float y = height / 2 - i * axisLength / 8;
- renderTarget.DrawLine(
- AlignToPixel(new RawVector2(width / 2 - 5, y)),
- AlignToPixel(new RawVector2(width / 2 + 5, y)),
- axisBrush, 1.0f, strokeStyle);
- using (var textLayout = new TextLayout(writeFactory, i.ToString(), textFormat, 50, 20))
- {
- renderTarget.DrawTextLayout(new RawVector2(width / 2 + 10, y - 10), textLayout, textBrush);
- }
- }
- // Draw a line using geometry for better quality
- var startPoint = AlignToPixel(new RawVector2(margin, margin));
- var endPoint = AlignToPixel(new RawVector2(width - margin, height - margin));
- using (var lineGeometry = new PathGeometry(factory))
- {
- var sink = lineGeometry.Open();
- sink.BeginFigure(startPoint, FigureBegin.Hollow);
- sink.AddLine(endPoint);
- sink.EndFigure(FigureEnd.Open);
- sink.Close();
- // 使用 SharpDX.Matrix3x2.Identity 而不是 System.Numerics.Matrix3x2.Identity
- //var transform = SharpDX.Matrix3x2.Identity;
- var transform = new RawMatrix3x2() { M11 = 1, M22 = 1 };
- using (var transformedGeometry = new TransformedGeometry(factory, lineGeometry, transform))
- {
- renderTarget.DrawGeometry(transformedGeometry, lineBrush, lineWidth, strokeStyle);
- }
- }
- }
- }
- private RawVector2 AlignToPixel(RawVector2 point)
- {
- return new RawVector2(
- (float)Math.Round(point.X) + 0.5f,
- (float)Math.Round(point.Y) + 0.5f
- );
- }
- private void DisposeResources()
- {
- renderTarget?.Dispose();
- swapChain?.Dispose();
- device?.Dispose();
- textFormat?.Dispose();
- writeFactory?.Dispose();
- factory?.Dispose();
- strokeStyle?.Dispose();
- }
- }
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金 |