I'm writing a Unity plugin which uses WPF for UI , Plugin runs in same process of Unity and has direct access to unity's memory.

Unity Code :

    render_rt_desc = new RenderTextureDescriptor(300, 300, RenderTextureFormat.BGRA32);
    render_rt = new RenderTexture(render_rt_desc);
    rendering_camera.targetTexture = render_rt;
    render_pointer = t2d_format.GetNativeTexturePtr();

    if (WPFWindow.IsWindowValid)

Now in my wpf app I get the texture pointer and properties are right, it has B8G8R8A8_Typeless format with ShaderResource and RenderTarget bind flags and I write it to file and it's fine.

To show it in WPF I need this texture be OptionFlags.Shared So i tried to copy it like this (using https://github.com/Marlamin/SharpDX.WPF ) :

    Device wpfdevice = new Device(SharpDX.Direct3D.DriverType.Hardware,DeviceCreationFlags.BgraSupport);

    Texture2D dx11t2D = CppObject.FromPointer<Texture2D>(Dx11Textureptr); /// pointer from unity

    Texture2DDescription texture2DDescription = dx11t2D.Description;
    texture2DDescription.OptionFlags = ResourceOptionFlags.Shared;
    texture2DDescription.BindFlags = BindFlags.ShaderResource | BindFlags.RenderTarget;
    texture2DDescription.Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm;

    Texture2D sharedt2d = new Texture2D(wpfdevice, texture2DDescription); 

    Device d3d11device = dx11t2D.QueryInterface<DeviceChild>().Device;
    d3d11device.ImmediateContext.CopyResource(dx11t2D, sharedt2d);

    DXImageSource dXImageSource = new DXImageSource();
                dx_output.Source = dXImageSource;

Result is black but it throws no error using SharpDX.WPF.

I found new wpf directx 11 D3DImage from Microsoft can be find here : https://github.com/microsoft/WPFDXInterop

WPF Global Objects :

        IntPtr _resourcePointer;
        SharpDX.Direct3D11.Device _device;
        SwapChain _swapChain;
        RenderTargetView _renderTargetView;

WPF Startup Code :

                var _swapChainDescription = new SwapChainDescription();
                _swapChainDescription.OutputHandle = new WindowInteropHelper(this).Handle;
                _swapChainDescription.BufferCount = 1;
                _swapChainDescription.Flags = SwapChainFlags.AllowModeSwitch;
                _swapChainDescription.IsWindowed = true;
                _swapChainDescription.ModeDescription = new ModeDescription(0, 0, new Rational(60, 1), Format.B8G8R8A8_UNorm);
                _swapChainDescription.SampleDescription = new SampleDescription(1, 0);
                _swapChainDescription.SwapEffect = SwapEffect.Discard;
                _swapChainDescription.Usage = Usage.RenderTargetOutput | Usage.Shared;

                var flags = DeviceCreationFlags.BgraSupport;
                    flags, _swapChainDescription, out _device, out _swapChain);

                InteropImage.SetPixelSize(300, 300);

                InteropImage.WindowOwner = new WindowInteropHelper(this).Handle;
                InteropImage.OnRender = this.xRENDER;

                dx_output.Source = InteropImage;

DoRender Function Code :

 void DoRender(IntPtr resourcePointer)
            if (_resourcePointer != resourcePointer)
                if (_resourcePointer != IntPtr.Zero)
                    _renderTargetView = null;

                _resourcePointer = resourcePointer;
                var texture = _renderTargetView.ResourceAs<SharpDX.Direct3D11.Texture2D>();
                if (texture.Description.Width != (int)this.ActualWidth || texture.Description.Height != (int)this.ActualHeight)
                    _renderTargetView = null;

            if (_renderTargetView == null)
                SharpDX.DXGI.Resource dxgiResource;
                using (var r = new SharpDX.ComObject(resourcePointer))
                    dxgiResource = r.QueryInterface<SharpDX.DXGI.Resource>();

                var directx11Texture = _device.OpenSharedResource<Texture2D>(dxgiResource.SharedHandle);
                _renderTargetView = new RenderTargetView(_device, directx11Texture);

            _device.ImmediateContext.Rasterizer.SetViewport(0, 0, (float)this.ActualWidth, (float)this.ActualHeight, 0.0f, 1.0f);
            _device.ImmediateContext.ClearRenderTargetView(_renderTargetView, new SharpDX.Color4(0.7f, 0.5f, 0.2f, 1.0f));

This code works fine but I have no idea how can I use my unity render texture to place in DoRender function without any copying or extra steps.

Performance is very important to me, I don't want to leave extra memory blocks or footprints.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.