当前位置:网站首页>WPF 使用封装的 SharpDx 控件
WPF 使用封装的 SharpDx 控件
2022-08-04 18:38:00 【林德熙】
上一篇告诉大家如何在 WPF 使用 SharpDx ,看起来代码比较复杂,所以本文告诉大家如何使用我封装的控件。
本文是一个系列,希望大家从第一篇开始看
- WPF 使用 Direct2D1 画图入门
- WPF 使用 Direct2D1 画图 绘制基本图形
- WPF 使用 SharpDX
- WPF 使用 SharpDX 在 D3DImage 显示
- WPF 使用封装的 SharpDx 控件
在WPF 使用 SharpDX 在 D3DImage 显示我告诉大家如何在 WPF 使用,但是代码都是写在一个 MainPage ,所以下面我把代码封装一下,放在一个类。
我的代码可以复制一下放在自己的工程使用,现在我还不想做 Nuget 因为这个类还有性能问题。
使用这个类作为 Image 的 Source 会占用 3% 的 CPU ,而且这个类没有注释,关于这个类是如何写的请看WPF 使用 SharpDX 在 D3DImage 显示 。
我会把这个类的代码放在文章最后,方便大家复制。
下面来告诉大家如何使用这个类。
首先复制代码,放在一个文件
写一个类继承 SharpDxImage ,这里我随意写一个类叫 SsgnnnaTkmlo ,这个类可以重写 OnRender ,也就是在绘制需要显示什么。
public class SsgnnnaTkmlo : SharpDxImage
{
/// <inheritdoc />
protected override void OnRender(RenderTarget renderTarget)
{
//随便画一个矩形。下面的代码就是清空屏幕,参数 null 为透明,可以给其他的颜色。如何绘制请看文章。
renderTarget.Clear(null);
var brush = new SharpDX.Direct2D1.SolidColorBrush(renderTarget, new RawColor4(1, 0, 0, 1));
var kvudjuzjsHlqiv = ran.Next((int) 100 - 10);
var dfulTokpj = ran.Next((int) 100 - 10);
renderTarget.DrawRectangle(
new RawRectangleF(kvudjuzjsHlqiv, dfulTokpj, kvudjuzjsHlqiv + 10, dfulTokpj + 10), brush, 1);
}
private Random ran = new Random();
}需要告诉大家的是,传入 RenderTarget 的绘制和之前其他代码的绘制是一样,关于 SharpDx 的绘制我会在另一篇博客告诉大家。
然后打开 xaml 写入下面代码
<Image x:Name="DcwtTmmwvcr">
<Image.Source>
<local:SsgnnnaTkmlo x:Name="DrmKroh"></local:SsgnnnaTkmlo>
</Image.Source>
</Image>当然,因为只是简单的例子,大家也可以写在后台代码。
在 xaml.cs 写下面代码,在 Load 绑定
DcwtTmmwvcr.Loaded += (s, e) =>
{
DrmKroh.CreateAndBindTargets((int) ActualWidth, (int) ActualHeight);
};注意需要使用图片控件的 Load 事件,不然拿到的图片会模糊。
现在可以尝试运行一下,就可以看到一个随机出现的矩形。
下面就是封装类的代码。
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
using SharpDX.Direct3D;
namespace WPFSharpDx
{
public abstract class SharpDxImage : D3DImage
{
public void CreateAndBindTargets(int actualWidth, int actualHeight)
{
var width = Math.Max(actualWidth, 100);
var height = Math.Max(actualHeight, 100);
var renderDesc = new SharpDX.Direct3D11.Texture2DDescription
{
BindFlags = SharpDX.Direct3D11.BindFlags.RenderTarget | SharpDX.Direct3D11.BindFlags.ShaderResource,
Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm,
Width = width,
Height = height,
MipLevels = 1,
SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
Usage = SharpDX.Direct3D11.ResourceUsage.Default,
OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.Shared,
CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None,
ArraySize = 1
};
var device = new SharpDX.Direct3D11.Device(DriverType.Hardware,
SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport);
var renderTarget = new SharpDX.Direct3D11.Texture2D(device, renderDesc);
var surface = renderTarget.QueryInterface<SharpDX.DXGI.Surface>();
var d2DFactory = new SharpDX.Direct2D1.Factory();
var renderTargetProperties =
new SharpDX.Direct2D1.RenderTargetProperties(
new SharpDX.Direct2D1.PixelFormat(SharpDX.DXGI.Format.Unknown,
SharpDX.Direct2D1.AlphaMode.Premultiplied));
_d2DRenderTarget = new SharpDX.Direct2D1.RenderTarget(d2DFactory, surface, renderTargetProperties);
SetRenderTarget(renderTarget);
device.ImmediateContext.Rasterizer.SetViewport(0, 0, width, height);
CompositionTarget.Rendering += CompositionTarget_Rendering;
}
protected abstract void OnRender(SharpDX.Direct2D1.RenderTarget renderTarget);
private SharpDX.Direct3D9.Texture _renderTarget;
private SharpDX.Direct2D1.RenderTarget _d2DRenderTarget;
private void CompositionTarget_Rendering(object sender, EventArgs e)
{
Rendering();
}
private void Rendering()
{
_d2DRenderTarget.BeginDraw();
OnRender(_d2DRenderTarget);
_d2DRenderTarget.EndDraw();
Lock();
AddDirtyRect(new Int32Rect(0, 0, PixelWidth, PixelHeight));
Unlock();
}
private void SetRenderTarget(SharpDX.Direct3D11.Texture2D target)
{
var format = TranslateFormat(target);
var handle = GetSharedHandle(target);
var presentParams = GetPresentParameters();
var createFlags = SharpDX.Direct3D9.CreateFlags.HardwareVertexProcessing |
SharpDX.Direct3D9.CreateFlags.Multithreaded |
SharpDX.Direct3D9.CreateFlags.FpuPreserve;
var d3DContext = new SharpDX.Direct3D9.Direct3DEx();
var d3DDevice = new SharpDX.Direct3D9.DeviceEx(d3DContext, 0, SharpDX.Direct3D9.DeviceType.Hardware,
IntPtr.Zero, createFlags,
presentParams);
_renderTarget = new SharpDX.Direct3D9.Texture(d3DDevice, target.Description.Width,
target.Description.Height, 1,
SharpDX.Direct3D9.Usage.RenderTarget, format, SharpDX.Direct3D9.Pool.Default, ref handle);
using (var surface = _renderTarget.GetSurfaceLevel(0))
{
Lock();
SetBackBuffer(D3DResourceType.IDirect3DSurface9, surface.NativePointer);
Unlock();
}
}
private static SharpDX.Direct3D9.PresentParameters GetPresentParameters()
{
var presentParams = new SharpDX.Direct3D9.PresentParameters();
presentParams.Windowed = true;
presentParams.SwapEffect = SharpDX.Direct3D9.SwapEffect.Discard;
presentParams.DeviceWindowHandle = NativeMethods.GetDesktopWindow();
presentParams.PresentationInterval = SharpDX.Direct3D9.PresentInterval.Default;
return presentParams;
}
private IntPtr GetSharedHandle(SharpDX.Direct3D11.Texture2D texture)
{
using (var resource = texture.QueryInterface<SharpDX.DXGI.Resource>())
{
return resource.SharedHandle;
}
}
private static SharpDX.Direct3D9.Format TranslateFormat(SharpDX.Direct3D11.Texture2D texture)
{
switch (texture.Description.Format)
{
case SharpDX.DXGI.Format.R10G10B10A2_UNorm:
return SharpDX.Direct3D9.Format.A2B10G10R10;
case SharpDX.DXGI.Format.R16G16B16A16_Float:
return SharpDX.Direct3D9.Format.A16B16G16R16F;
case SharpDX.DXGI.Format.B8G8R8A8_UNorm:
return SharpDX.Direct3D9.Format.A8R8G8B8;
default:
return SharpDX.Direct3D9.Format.Unknown;
}
}
private static class NativeMethods
{
[DllImport("user32.dll", SetLastError = false)]
public static extern IntPtr GetDesktopWindow();
}
}
}边栏推荐
- 在线生成接口文档
- A group of friends asked for help, but the needs that were not solved in a week were solved in 3 minutes?
- 当项目中自动格式化插件Prettier和ESLint冲突报错时如何解决
- 测试/开发程序员男都秃头?女都满脸痘痘?过好我们“短暂“的一生......
- 测试工程师如何突破职业瓶颈?
- 数仓相关,总结
- DHCP&OSPF combined experimental demonstration (Huawei routing and switching equipment configuration)
- flink-cdc支持并行读取一张mysql表的binlog不?
- 2019年海淀区青少年程序设计挑战活动小学组复赛试题详细答案
- FE01_OneHot-Scala应用
猜你喜欢

(ECCV-2022)GaitEdge:超越普通的端到端步态识别,提高实用性

Nintendo won't launch any new hardware until March 2023, report says

LVS负载均衡群集之原理叙述

什么是网站监控,网站监控软件有什么用?

Alibaba Cloud International Edition uses ROS to build WordPress tutorial

After EasyCVR is locally connected to the national standard device to map the public network, the local device cannot play and cascade the solution

测试/开发程序员男都秃头?女都满脸痘痘?过好我们“短暂“的一生......

天呐,七夕我收到9份告白~

limux入门3—磁盘与分区管理

YOLOv7-Pose尝鲜,基于YOLOv7的关键点模型测评
随机推荐
EasyCVR如何通过接口调用设备录像的倍速回放?
C#爬虫之通过Selenium获取浏览器请求响应结果
数仓建模面试
数仓相关,总结
ros2订阅esp32发布的电池电压数据-补充
Iptables防火墙基础知识介绍
基于 eBPF 的 Kubernetes 可观测实践
Scala104 - Built-in datetime functions for Spark.sql
2022 May 1 Mathematical Modeling Question C Explanation
EasyCVR calls the cloud recording API and returns an error and no recording file is generated. What is the reason?
BigDecimal 使用注意!!“别踩坑”
路由技术
CIFAR发布《AI伦理的文化:研讨会报告》【附下载】
Day018 Inheritance
全球电子产品需求放缓:三星越南工厂大幅压缩产能
数据库SqlServer迁移PostgreSql实践
自己经常使用的三种调试:Pycharm、Vscode、pdb调试
在线生成接口文档
How does the intelligent video surveillance platform EasyCVR use the interface to export iframe addresses in batches?
2019年海淀区青少年程序设计挑战活动小学组复赛试题详细答案