Настройка WinForm DirectX 2d для SharpDX 2D

#c# #winforms #directx #sharpdx

Вопрос:

Я довольно новичок в DirectX, и я пытался следовать этому руководству, но оно на самом деле не объясняет, что такое какие-либо из этих объектов, и я хочу иметь возможность использовать это с WinForms или WPF в будущем, но я понятия не имею, как настроить устройства для 2d-рисования. кто — нибудь не против показать мне, как именно вы это делаете ? Я попытался это сделать, но я просто получаю исключение sharpdx, когда задается переменная d2dTarget.

 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);
            */
        }
    }
    ```
 

Комментарии:

1. извините, я забыл опубликовать это, учебник, которому я пытаюсь следовать, находится здесь english.r2d2rigo.es/2012/07/04/…

Ответ №1:

Вы действительно не можете использовать SharpDX, если вы не знаете / не понимаете DirectX, DXGI, Direct2D. Также вы говорите о «будущем», но SharpDX больше не активен с 2 лет https://github.com/sharpdx/SharpDX.

В вашем коде есть две проблемы:

  • вы воссоздаете устройство (с цепочкой подкачки) и используете контекст устройства D2D с первого устройства
  • вам не нужно указывать свойства при создании растрового изображения, они неявно зависят от базовой поверхности DXGI

Это код, который должен работать:

 // create D3D device amp; (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 amp; 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);
 

Комментарии:

1. Я попробую это позже сегодня , как только у меня будет возможность, и да, я пытался выучить DirectX с помощью репетиторов C , но я не понимаю, почему, но я просто не могу понять ни один из объектов и прочего, и я действительно ничего не могу найти в direct2d . Я на самом деле не пытаюсь заниматься разработкой игр, но я хочу что-то более быстрое, чем GDI

2. SharpDX несколько сложно понять, потому что вы не можете сравнить тысячи стандартных и официальных образцов C/C с кодом SharpDX, даже если вы знаете объекты C/C . Вот почему я создал этот пакет » DirectN» github.com/smourier/DirectN где .NET-код очень похож на собственный.

3. охо, интересно , но я думаю, что буду придерживаться SharpDX . Мне не очень интересен DirectX 11, и самая сложная часть выполнения большинства учебных пособий заключалась в том, чтобы просто выяснить, как на самом деле поместить данные в форму, так как я пытаюсь использовать DirectX с WinForms.