Как настроить SwapChain1 для 2D-рендеринга в SharpDX? - PullRequest
0 голосов
/ 02 февраля 2020

Итак, я использовал SharpDX, обертку C# DirectX для программирования в Direct3D11 и Direct2D, чтобы рисовать в окне RenderForm в моей программе. Однако информация SwapChain.Present гласит, что я должен вместо этого использовать SwapChain1.Present1, и я не могу понять, как изменить свой код для работы с SwapChain1. Метод CreateWithSwapChain в Device и даже Device1 работает только с обычным SwapChain, и я не знаю, как еще просто настроить его.

Это используемые пространства имен.

using SharpDX.Direct2D1;
using SharpDX.Direct3D;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using SharpDX.Windows;
using Device = SharpDX.Direct3D11.Device;
using Factory = SharpDX.Direct2D1.Factory;
using Resource = SharpDX.Direct3D11.Resource;

И этот код я использую для настройки RenderTarget.

SwapChainDescription desc = new SwapChainDescription() {
                BufferCount = 1,
                ModeDescription = new ModeDescription(
               DXWindow.GetWindow().ClientSize.Width,
               DXWindow.GetWindow().ClientSize.Height,
               new Rational(60, 1),
               Format.R8G8B8A8_UNorm),
                IsWindowed = true,
                OutputHandle = DXWindow.GetWindow().Handle,
                SampleDescription = new SampleDescription(1, 0),
                SwapEffect = SwapEffect.Discard,
                Usage = Usage.RenderTargetOutput
            };
            Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.BgraSupport, new SharpDX.Direct3D.FeatureLevel[] { SharpDX.Direct3D.FeatureLevel.Level_10_0 }, desc, out Device device, out swapchain);
            Texture2D backbuffer = Resource.FromSwapChain<Texture2D>(swapchain, 0);
            RenderTargetView renderview = new RenderTargetView(device, backbuffer);
            renderView = new RenderTarget(new Factory(), backbuffer.QueryInterface<Surface>(), new RenderTargetProperties(new PixelFormat(Format.Unknown, SharpDX.Direct2D1.AlphaMode.Premultiplied)));
            RenderLoop.Run(DXWindow.GetWindow(), CoreLoop);

DXWindow.GetWindow() get возвращает RenderForm и CoreLoop - рендер l oop, где я звоню Draw и Present. Как я могу использовать SwapChain1 вместо SwapChain в этом?

1 Ответ

0 голосов
/ 04 февраля 2020

Я разместил свой код, который работает для Swapchain2. При необходимости вы можете поменять интерфейс запроса с SwapChain1. Я включил код для Windows форм и инициализации UWP. Я не уверен, что вы здесь делаете. Таким образом, #define позволяет вам менять местами, хотя я не проделал большую работу над UWP, и он может быть поврежден с тех пор, как я в последний раз коснулся его.

// Функция Create ()

DXGI.Device1 dxgiDevice1_ = _d3dDevice.QueryInterface<DXGI.Device1>();
DXGI.Adapter dxgiAdapter_ = dxgiDevice1_.Adapter;
DXGI.Factory2 dxgiFactory2_ = dxgiAdapter_.GetParent<DXGI.Factory2>();

ReleaseAllDeviceContexts(true);

if (_swapChain != null)
{
    _swapChain.Dispose();
}

if (_swapChainBuffer != null)
{
    _swapChainBuffer.Dispose();
}

if (_parentSwapchain != null)
{
    _parentSwapchain.Dispose();
}

#if !WINDOWS_UWP
DXGI.SwapChainDescription1 swapChainDescription_ = new DXGI.SwapChainDescription1()
{
    AlphaMode = DXGI.AlphaMode.Ignore,
    Width = _modeDescription.Width,
    Height = _modeDescription.Height,
    Format = DXGI.Format.R8G8B8A8_UNorm,
    Scaling = DXGI.Scaling.None,
    BufferCount = _swapChainBufferCount,
    SwapEffect = SharpDX.DXGI.SwapEffect.FlipDiscard,

    Flags = SharpDX.DXGI.SwapChainFlags.AllowModeSwitch,
    Usage = DXGI.Usage.BackBuffer | DXGI.Usage.RenderTargetOutput,
    SampleDescription = new DXGI.SampleDescription() { Count = 1, Quality = 0 },
    Stereo = false,
};

_parentSwapchain1 = new DXGI.SwapChain1(dxgiFactory2_, _d3dDevice, _parentContainer.WindowHandle, ref swapChainDescription_, new DXGI.SwapChainFullScreenDescription()
{
    RefreshRate = _modeDescription.RefreshRate,
    Scaling = SharpDX.DXGI.DisplayModeScaling.Unspecified,
    Windowed = isFullscreen == false,
    ScanlineOrdering = DXGI.DisplayModeScanlineOrder.Unspecified,
}
);

_swapChain = _parentSwapchain.QueryInterface<DXGI.SwapChain2>();
#else
DXGI.SwapChainDescription1 swapChainDescription = new DXGI.SwapChainDescription1()
{
    AlphaMode = DXGI.AlphaMode.Ignore,
    Width = _modeDescription.Width,
    Height = _modeDescription.Height,
    Format = DXGI.Format.R8G8B8A8_UNorm,
    Scaling = DXGI.Scaling.Stretch,
    BufferCount = _swapChainBufferCount,
    SwapEffect = SharpDX.DXGI.SwapEffect.FlipDiscard,

    Flags = SharpDX.DXGI.SwapChainFlags.AllowModeSwitch | DXGI.SwapChainFlags.AllowTearing,


    Usage = DXGI.Usage.BackBuffer | DXGI.Usage.RenderTargetOutput,
    SampleDescription = new DXGI.SampleDescription() { Count = 1, Quality = 0 },
    Stereo = false,
};

ComObject obj = new ComObject(_parentContainer.WindowHandle);

 _parentSwapchain1 = new DXGI.SwapChain1(dxgiFactory3, _device, ref swapChainDescription, null);

_swapChain2 = _parentSwapchain1.QueryInterface<DXGI.SwapChain2>();

using (DXGI.ISwapChainPanelNative nativeObject = ComObject.As<DXGI.ISwapChainPanelNative>(_parentContainer.WindowHandle))
{
    // Set its swap chain.
    nativeObject.SwapChain = _swapChain2;
}
#endif

_swapChainBuffer = D3D11.Texture2D.FromSwapChain<D3D11.Texture2D>(_swapChain, 0);

dxgiDevice1_.Dispose();
dxgiAdapter_.Dispose();
dxgiFactory2_.Dispose();

Изменение размера буфера также включено сюда для справки. Не обращайте внимания на некоторый пользовательский код, хотя он полностью встроен в мою игру, поэтому некоторые из них не имеют смысла.

           public void ResizeBuffers(bool isFullscreen)
        {
            try
            {
                if (_swapChainBuffer != null)
                {
                    //      if (_parentSwapchain1.IsFullScreen != isFullscreen)
                    {
                        ReleaseAllDeviceContexts(true);

                        SharpDX.Utilities.Dispose(ref _swapChain2);
                        SharpDX.Utilities.Dispose(ref _swapChainBuffer);

#if !WINDOWS_UWP
                        _parentSwapchain1.IsFullScreen = isFullscreen;

                        _parentSwapchain1.ResizeBuffers(0, _modeDescription.Width, _modeDescription.Height, DXGI.Format.Unknown, SharpDX.DXGI.SwapChainFlags.AllowModeSwitch);
                        if (isFullscreen)
                        {
                            _parentSwapchain1.ResizeTarget(ref _modeDescription);
                        }
#else
                        _parentSwapchain1.ResizeBuffers(0, _modeDescription.Width, _modeDescription.Height, DXGI.Format.Unknown, DXGI.SwapChainFlags.AllowTearing);
#endif

                        _swapChain2 = _parentSwapchain1.QueryInterface<DXGI.SwapChain2>();

                        _swapChainBuffer = D3D11.Texture2D.FromSwapChain<D3D11.Texture2D>(_swapChain2, 0);
                    }
                    _renderViewport = new Viewport(0, 0, _modeDescription.Width, _modeDescription.Height);
                    _d3dDevice.ImmediateContext1.Rasterizer.SetViewport(_renderViewport);
                }

            }
            catch (Exception ex)
            {
                ErrorHandler.DoErrorHandling(ex, ErrorHandler.GetCurrentMethod(ex));
            }

        }
...