[SharpDX] Creating a Direct2D render Target from a swapchain

Started by
8 comments, last by Stefan Fischlschweiger 9 years, 2 months ago

I've been trying to create a direct2d render target from a swapchain. I have tried to mimic the solution from this thread: http://www.gamedev.net/topic/639578-d2d-d3d11-help-me-to-make-them-work-together/, but it does not work. I get an invalid argument error, and I've eliminated all the other possibilities except the surface I've given it. I am currently using Surface1.FromSwapChain to get my surface for my render target but that does not work. I've tried many ways of getting the surface but nothing seems to work. If anyone can point me in a direction it would be very useful.

Thanks very much,

Curin

Advertisement

I'm using this code to crate the render Target, and it works for me:


private void CreateD2DTarget()
        {
            var properties = new BitmapProperties1(new PixelFormat(Format.B8G8R8A8_UNorm, SharpDX.Direct2D1.AlphaMode.Premultiplied),
                96, 96, BitmapOptions.Target | BitmapOptions.CannotDraw);

            var d2Dtarget = new Bitmap1(_d2DContext, SwapChain.GetBackBuffer<Surface>(0), properties);
            _d2DContext.Target = d2Dtarget;
        }

After creating the D2D context with this code:


private void CreateD2DRender()
        {
            // Query for the adapter and more advanced DXGI objects.
            var dxgiDevice2 = _d3DDevice.QueryInterface<SharpDX.DXGI.Device>();

            // Get the default Direct2D device and create a context.
            var d2DDevice = new SharpDX.Direct2D1.Device(dxgiDevice2);
            _d2DContext = new SharpDX.Direct2D1.DeviceContext(d2DDevice, DeviceContextOptions.None);

            _d2DContext.PrimitiveBlend = PrimitiveBlend.SourceOver;

            CreateD2DTarget();
        }

I used this article from Washu to finally get Direct2D to play nicely with a Direct3D swap chain. If you want to use both Direct2D and Direct3D rendering at the same time, you'll want to use this approach.

Eric Richards

SlimDX tutorials - http://www.richardssoftware.net/

Twitter - @EricRichards22

Since he's using SharpDX, the tutorials here would be even more appropriate: http://english.r2d2rigo.es/sharpdx-tutorials/

I appreciate all your help, but I still have a problem with your solution Lordadmiral Drake.The line


var d2DDevice = new SharpDX.Direct2D1.Device(dxgiDevice2);

produces the error Additional information: HRESULT: [0x80070057], Module: [General], ApiCode: [E_INVALIDARG/Invalid Arguments], Message: The parameter is incorrect.

I'm not sure why either.

Here is my code


[STAThread]
        static void Main()
        {
            RenderForm form = new RenderForm("TEST APP");
            Factory fact = new Factory();
            Device dev = new Device(fact.Adapters[0]);
            SwapChain chain = new SwapChain(fact, dev, new SwapChainDescription()
                {
                    BufferCount = 1,
                    Flags = SwapChainFlags.AllowModeSwitch,
                    IsWindowed = true,
                    ModeDescription = new ModeDescription(800, 600, new Rational(1, 60), Format.B8G8R8A8_UNorm),
                    OutputHandle = form.Handle,
                    SampleDescription = new SampleDescription(1, 0),
                    SwapEffect = SwapEffect.Discard,
                    Usage = Usage.RenderTargetOutput
                });

            Texture2D backbuffer = Texture2D.FromSwapChain<Texture2D>(chain, 0);
            RenderTargetView rtv = new RenderTargetView(dev, backbuffer);
            SharpDX.Direct3D11.DeviceContext context = dev.ImmediateContext;

            Surface surf = chain.GetBackBuffer<Surface>(0);
            Factory2 fact2 = new Factory2(FactoryType.SingleThreaded, DebugLevel.Information);
            // Query for the adapter and more advanced DXGI objects.
            var dxgiDevice2 = dev.QueryInterface<SharpDX.DXGI.Device>();

            // Get the default Direct2D device and create a context.
            var d2DDevice = new SharpDX.Direct2D1.Device(dxgiDevice2);
            var _d2DContext = new SharpDX.Direct2D1.DeviceContext(d2DDevice, DeviceContextOptions.None);

            _d2DContext.PrimitiveBlend = PrimitiveBlend.SourceOver;

            var properties = new BitmapProperties1(new PixelFormat(Format.B8G8R8A8_UNorm, SharpDX.Direct2D1.AlphaMode.Premultiplied),
                96, 96, BitmapOptions.Target | BitmapOptions.CannotDraw);

            var _targ = new Bitmap1(_d2DContext, chain.GetBackBuffer<Surface>(0), properties);
            _d2DContext.Target = _targ;

        }

Also what version are you using I'm using 3.0.0 and the DirectX11_2-signed-net40

Thanks Again,

Curin

I'm using 2.6.3 DirectX11_2-net40

Okay I attempted it using 2.6.3 DirectX11_2-net40 and I got the same error

The only problem with the dxgidevice is that the output FrameStatistics, GammaControl, and Gammacontrol Capabilities are throwing exceptions. The outputs are in the adapter

Only other thing I can think of right now is that you are creating your D3D Device differently than I.

I don't even use Adapter, in fact I pull the Factory from the Swapchain after Device and Swapchain creation

Here's what I do:


// Description for our swap chain settings.
            var description = new SwapChainDescription
            {
                ModeDescription = new ModeDescription(RenderWindow.Width, RenderWindow.Height, new Rational(60, 1), Format.B8G8R8A8_UNorm),
                // No multisampling.
                SampleDescription = new SampleDescription(1, 0),
                // Use the swap chain as a render target.
                Usage = Usage.RenderTargetOutput,
                
                IsWindowed = true,
                Flags = SwapChainFlags.AllowModeSwitch,
                OutputHandle = RenderWindow.Handle,
                // Enable double buffering to prevent flickering.
                BufferCount = 1,
                // Flip between both buffers.
                SwapEffect = SwapEffect.Discard,
            };

            // Generate a swap chain for our window based on the specified description.
            Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.Debug | DeviceCreationFlags.BgraSupport, 
                description, out _d3DDevice, out SwapChain);
            _d3DContext = _d3DDevice.ImmediateContext.QueryInterface<SharpDX.Direct3D11.DeviceContext>();

okay found out my issue. I wan't using Brgasupport creationflag. Thanks so much for your help Drake

No problem, getting D2D working was a pain in the ass for me too ^^

This topic is closed to new replies.

Advertisement