SharpDX 2D 的 DirectX 2d WinForm 设置

Posted

技术标签:

【中文标题】SharpDX 2D 的 DirectX 2d WinForm 设置【英文标题】:DirectX 2d WinForm Setup for SharpDX 2D 【发布时间】:2021-10-29 17:33:30 【问题描述】:

我对 DirectX 很陌生,我一直在尝试学习本教程,但它并没有真正解释这些对象是什么,我希望将来能够将它与 WinForms 或 WPF 一起使用,但我不知道如何设置用于 2d 绘图的设备。有人介意告诉我你是这样做的吗?我尝试了这个,但是当设置变量 d2dTarget 时,我得到了一个 sharpdx 异常。

using System.Threading.Tasks;
using System.Windows.Forms;
using System.ComponentModel;
using SharpDX;
using SharpDX.DXGI;
using SharpDX.Direct3D;
using SharpDX.Direct3D11;
using SharpDX.Direct2D1;

namespace SharpDX_Tester

    public partial class Form1 : Form
    
        SharpDX.Direct3D11.Device device;
        SharpDX.Direct3D11.DeviceContext1 d3dContext;
        SharpDX.Direct2D1.DeviceContext d2dContext;
        RenderTargetView targetView;
        SwapChain swapChain;
        Texture2D target;

        Bitmap1 d2dTarget;

        public Form1()
        
            InitializeComponent();


            SharpDX.Direct3D11.Device defaultDevice = new SharpDX.Direct3D11.Device(DriverType.Hardware, DeviceCreationFlags.Debug | DeviceCreationFlags.BgraSupport);

            device = defaultDevice.QueryInterface<SharpDX.Direct3D11.Device1>();
            
            d3dContext = device.ImmediateContext.QueryInterface<SharpDX.Direct3D11.DeviceContext1>();

            SharpDX.DXGI.Device2 dxgiDevice2 = device.QueryInterface<SharpDX.DXGI.Device2>();
            SharpDX.DXGI.Adapter dxgiAdapter = dxgiDevice2.Adapter;
            SharpDX.DXGI.Factory2 dxgiFactory2 = dxgiAdapter.GetParent<SharpDX.DXGI.Factory2>();
            SharpDX.Direct2D1.Device d2dDevice = new SharpDX.Direct2D1.Device(dxgiDevice2);
            d2dContext = new SharpDX.Direct2D1.DeviceContext(d2dDevice, SharpDX.Direct2D1.DeviceContextOptions.None);

            var scd = new SwapChainDescription()
            
                BufferCount = 1,
                Flags = SwapChainFlags.None,
                IsWindowed = true, //WINDOWS
                ModeDescription = new ModeDescription(panel1.ClientSize.Width, panel1.ClientSize.Height, new Rational(60, 1), Format.R8G8B8A8_UNorm),
                OutputHandle = panel1.Handle/*<-Impotant*/,
                SampleDescription = new SampleDescription(1, 0),
                SwapEffect = SwapEffect.Discard,
                Usage = Usage.RenderTargetOutput
            ;
            SharpDX.Direct3D11.Device.CreateWithSwapChain(SharpDX.Direct3D.DriverType.Hardware, DeviceCreationFlags.Debug, scd, out device, out swapChain);

            BitmapProperties1 properties = new BitmapProperties1(new PixelFormat(SharpDX.DXGI.Format.B8G8R8A8_UNorm, SharpDX.Direct2D1.AlphaMode.Premultiplied));
            Surface backBuffer = swapChain.GetBackBuffer<Surface>(0);
            d2dTarget = new Bitmap1(d2dContext, backBuffer, properties);

            /* IGNORE THIS
            target = Texture2D.FromSwapChain<Texture2D>(sc, 0);
            targetView = new RenderTargetView(device, target);
            device.ImmediateContext.OutputMerger.SetRenderTargets(targetView);
            */
        
    
    ```

【问题讨论】:

对不起,我忘了发布这个我试图遵循的教程在这里english.r2d2rigo.es/2012/07/04/… 【参考方案1】:

如果您不了解/不了解 DirectX、DXGI、Direct2D,就无法真正使用 SharpDX。您还谈到“未来”,但 SharpDX 两年后不再活跃https://github.com/sharpdx/SharpDX。

你的代码有两个问题:

您重新创建一个设备(带有交换链)并使用第一个设备的 D2D 设备上下文 创建位图时不需要指定属性,它们是底层 DXGI 表面的隐含属性

这是一个应该可以工作的代码:

// create D3D device & (DXGI) swap chain
var scd = new SwapChainDescription()

    BufferCount = 1,
    Flags = SwapChainFlags.None,
    IsWindowed = true,
    ModeDescription = new ModeDescription(panel1.ClientSize.Width, panel1.ClientSize.Height, new Rational(60, 1), Format.R8G8B8A8_UNorm),
    OutputHandle = panel1.Handle, // make sure this is not IntPtr.Zero
    SampleDescription = new SampleDescription(1, 0),
    SwapEffect = SwapEffect.Discard,
    Usage = Usage.RenderTargetOutput
;

SharpDX.Direct3D11.Device.CreateWithSwapChain(
    DriverType.Hardware,
    DeviceCreationFlags.Debug | DeviceCreationFlags.BgraSupport,
    scd,
    out device,
    out swapChain);

// get swap chain backbuffer
var backBuffer = swapChain.GetBackBuffer<Surface>(0);

// create DXGI & D2D devices context
var dxgiDevice = device.QueryInterface<SharpDX.DXGI.Device2>();
var d2dDevice = new SharpDX.Direct2D1.Device(dxgiDevice);
d2dContext = new SharpDX.Direct2D1.DeviceContext(
    d2dDevice,
    DeviceContextOptions.None);

// create target
d2dTarget = new Bitmap1(d2dContext, backBuffer);

【讨论】:

thx 有机会我会在今天晚些时候尝试一下,是的,我一直在尝试从 C++ 教程中学习 DirectX,但我不知道为什么,但我就是无法理解任何对象和东西我在 direct2d 上真的找不到任何东西。我并不是真的想进入游戏开发领域,但我想要比 GDI+ 更快的东西 SharpDX 有点难以掌握,因为即使您知道 C/C++ 对象,您也无法将那里的数千个标准和官方 C/C++ 示例与 SharpDX 代码进行比较。这就是我创建这个“DirectN”包github.com/smourier/DirectN 的原因,其中.NET 代码与本机代码非常相似。 哦,很有趣,但我想我会坚持使用 SharpDX。我对 DirectX 11 不是很感兴趣,学习大多数教程中最难的部分就是弄清楚如何将东西实际放到表单上,因为我尝试将 DirectX 与 WinForms 一起使用。

以上是关于SharpDX 2D 的 DirectX 2d WinForm 设置的主要内容,如果未能解决你的问题,请参考以下文章

频繁更新 Texture2D 会导致进程崩溃 (UpdateSubresource)

SharpDX/SolidColorBrush 构造函数与 DeviceContext?

DirectX11--深入理解与使用2D纹理资源

使用 Direct 3D (C++) 的 DIrectX 11 2D 游戏引擎

C++ DirectX - 对 2D 网格进行纹理化

DirectX11--深入理解与使用2D纹理资源