Проблема в тому, що не вдається отримати ‘IntPtr’ або щось подібне з ‘SwapChainPanel’ в UWP. Спробую розглянути різні підходи та їх реалізацію.
Перший підхід полягає в ініціалізації DirectX 11 безпосередньо з використанням ‘SwapChainPanel’ із ‘SharpDX’ binding set.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
public static void Initialize(SwapChainPanel panel) { FeatureLevel[] featureLevels = [ FeatureLevel.Level_11_1, FeatureLevel.Level_11_0 ]; SwapChainDescription swapChainDescription = new() { BufferCount = 1, ModeDescription = new((int)panel.ActualWidth, (int)panel.ActualHeight, new Rational(60, 1), Format.R8G8B8A8_UNorm), Usage = Usage.RenderTargetOutput, SampleDescription = new SampleDescription(1, 0), IsWindowed = true, SwapEffect = SwapEffect.Discard, Flags = SwapChainFlags.AllowModeSwitch }; SharpDX.Direct3D11.Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.BgraSupport, featureLevels, swapChainDescription, out device, out swapChain); using (var dxgiDevice2 = device.QueryInterface<SharpDX.DXGI.Device2>()) { using Adapter dxgiAdapter = dxgiDevice2.Adapter; using Factory2 dxgiFactory2 = dxgiAdapter.GetParent<Factory2>(); SwapChain swapChain1 = new(dxgiFactory2, device, swapChainDescription); panel.Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { panel.SwapChain = swapChain1.QueryInterface<ISwapChainPanelNative>(); //<-- Помилка тут }).AsTask().Wait(); } using (var backBuffer = swapChain.GetBackBuffer<Texture2D>(0)) { renderTargetView = new RenderTargetView(device, backBuffer); } device.ImmediateContext.OutputMerger.SetRenderTargets(renderTargetView); device.ImmediateContext.Rasterizer.SetViewport(new Viewport(0, 0, (int)panel.ActualWidth, (int)panel.ActualHeight)); } |
Як можна помітити, під час використання ‘SwapChainPanel’, виникає помилка відсутності можливості отримати ‘IntPtr’ з панелі.
Наступний підхід передбачає спробу отримання віконного дескриптору.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
private static IntPtr GetInteropWindowHandle(this SwapChainPanel panel) { IInspectable interop = (IInspectable)panel; object interopObj = Marshal.GetObjectForIUnknown(interop.NativePointer); //<-- Помилка тут IntPtr windowHandle = IntPtr.Zero; if (interopObj is PropertySet propertySet) { if (propertySet.TryGetValue("SwapChainInteropHandle", out object value)) windowHandle = (IntPtr)value; } return windowHandle; } |
Після отримання віконного дескриптору, його можна використати для ініціалізації ‘SwapChainDescription’.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
SwapChainDescription swapChainDescription = new() { BufferCount = 1, ModeDescription = new((int)panel.ActualWidth, (int)panel.ActualHeight, new Rational(60, 1), Format.R8G8B8A8_UNorm), Usage = Usage.RenderTargetOutput, OutputHandle = panel.GetInteropWindowHandle(), SampleDescription = new SampleDescription(1, 0), IsWindowed = true, SwapEffect = SwapEffect.Discard, Flags = SwapChainFlags.AllowModeSwitch }; |
Це дозволяє успішно ініціалізувати DirectX 11 з використанням ‘SwapChainPanel’ в UWP.
Незважаючи на намагання скористатися різними джерелами інформації, такими як ChatGPT 4, форуми SharpDX та Microsoft Learn, вирішення цієї проблеми залишається викликом.