/// <summary> /// Initializes a new instance of the <see cref="DeviceContext3"/> class using an existing <see cref="Device3"/>. /// </summary> /// <param name="device">The device.</param> /// <param name="options">The options to be applied to the created device context.</param> /// <remarks> /// The new device context will not have a selected target bitmap. The caller must create and select a bitmap as the target surface of the context. /// </remarks> /// <unmanaged>HRESULT ID2D1Device3::CreateDeviceContext([In] D2D1_DEVICE_CONTEXT_OPTIONS options,[Out] ID2D1DeviceContext3** deviceContext3)</unmanaged> public DeviceContext3(Device3 device, DeviceContextOptions options) : base(IntPtr.Zero) { device.CreateDeviceContext(options, this); }
public void Run() { #region setup resources var mainForm = new RenderForm(); var scDescription = new SwapChainDescription() { BufferCount = 1, ModeDescription = new ModeDescription( 0, 0, new Rational(60, 1), Format.R8G8B8A8_UNorm), IsWindowed = true, OutputHandle = mainForm.Handle, SampleDescription = new SampleDescription(1, 0), SwapEffect = SwapEffect.Discard, Usage = Usage.RenderTargetOutput }; //DeviceCreationFlags.Debug flag below will show debug layer messages in your output window. //Need proper version of windows sdk for it to work, otherwise it will throw an exception. //You also need to right click your project->properties->debug (on the left panel)-> check "enable native code debugging" // Create Device and SwapChain _d3d11.Device.CreateWithSwapChain( DriverType.Hardware, DeviceCreationFlags.BgraSupport | DeviceCreationFlags.Debug, new[] { _d3d.FeatureLevel.Level_12_1 }, scDescription, out d3d11Device, out swapChain); // Ignore all windows events dxgiFactory = swapChain.GetParent <_dxgi.Factory1>(); dxgiFactory.MakeWindowAssociation(mainForm.Handle, WindowAssociationFlags.IgnoreAll); d2dFactory = new _d2d.Factory(); d2dFactory4 = d2dFactory.QueryInterface <_d2d.Factory4>(); dxgiDevice = d3d11Device.QueryInterface <_dxgi.Device>(); d2dDevice3 = new _d2d.Device3(d2dFactory4, dxgiDevice); d2dDeviceContext3 = new _d2d.DeviceContext3(d2dDevice3, DeviceContextOptions.None); #endregion #region create drawing input sourceImage = createD2DBitmap(@"yourFile.png", d2dDeviceContext3); spriteBatch = new SpriteBatch(d2dDeviceContext3); var destinationRects = new RawRectangleF[1]; destinationRects[0] = new RectangleF(100, 50, sourceImage.Size.Width, sourceImage.Size.Height); var sourceRects = new RawRectangle[1]; sourceRects[0] = new RectangleF(0, 0, sourceImage.Size.Width, sourceImage.Size.Height); #endregion #region mainLoop RenderLoop.Run(mainForm, () => { if (d2dTarget != null) { d2dTarget.Dispose(); d2dTarget = null; } using (var backBuffer = Texture2D.FromSwapChain <Texture2D>(swapChain, 0)) { using (var surface = backBuffer.QueryInterface <Surface>()) { var bmpProperties = new BitmapProperties1( new PixelFormat(Format.R8G8B8A8_UNorm, _d2d.AlphaMode.Premultiplied), dpiX: 96, dpiY: 96, bitmapOptions: BitmapOptions.Target | BitmapOptions.CannotDraw); d2dTarget = new Bitmap1( d2dDeviceContext3, surface, bmpProperties); d2dDeviceContext3.Target = d2dTarget; } } //the key missing piece: cannot use per primitive antialiasing with spritebatch d2dDeviceContext3.AntialiasMode = AntialiasMode.Aliased; d2dDeviceContext3.BeginDraw(); spriteBatch.Clear(); spriteBatch.AddSprites( 1, destinationRects, sourceRects, null, null, destinationRectanglesStride: 0, //0 stride because there is only 1 element sourceRectanglesStride: 0, colorsStride: 0, transformsStride: 0); d2dDeviceContext3.DrawSpriteBatch( spriteBatch: spriteBatch, startIndex: 0, spriteCount: 1, bitmap: sourceImage, interpolationMode: BitmapInterpolationMode.Linear, spriteOptions: SpriteOptions.ClampToSourceRectangle); d2dDeviceContext3.EndDraw(); //first param set to 1 would indicate waitVerticalBlanking swapChain.Present(0, PresentFlags.None); }); #endregion }