Browse Source

Direct3DInterop fixes

pull/1861/head
Benedikt Schroeder 8 years ago
parent
commit
024e0da1da
  1. 276
      samples/interop/Direct3DInteropSample/MainWindow.cs
  2. 14
      src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs
  3. 29
      src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DBitmapImpl.cs
  4. 5
      src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DRenderTargetBitmapImpl.cs
  5. 5
      src/Windows/Avalonia.Direct2D1/Media/Imaging/WriteableWicBitmapImpl.cs

276
samples/interop/Direct3DInteropSample/MainWindow.cs

@ -1,81 +1,83 @@
using System; // Copyright (c) The Avalonia Project. All rights reserved.
using System.Collections.Generic; // Licensed under the MIT license. See licence.md file in the project root for full license information.
using System.Linq;
using System.Text; using System;
using System.Threading.Tasks;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Direct2D1;
using Avalonia.Direct2D1.Media; using Avalonia.Direct2D1.Media;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Rendering; using Avalonia.Rendering;
using SharpDX; using SharpDX;
using SharpDX.D3DCompiler; using SharpDX.D3DCompiler;
using SharpDX.Direct2D1; using SharpDX.Direct2D1;
using SharpDX.Direct3D; using SharpDX.Direct3D;
using SharpDX.Direct3D11; using SharpDX.Direct3D11;
using SharpDX.DXGI; using SharpDX.DXGI;
using SharpDX.WIC;
using SharpDX.Mathematics;
using AlphaMode = SharpDX.Direct2D1.AlphaMode; using AlphaMode = SharpDX.Direct2D1.AlphaMode;
using Buffer = SharpDX.Direct3D11.Buffer; using Buffer = SharpDX.Direct3D11.Buffer;
using DeviceContext = SharpDX.Direct3D11.DeviceContext; using DeviceContext = SharpDX.Direct2D1.DeviceContext;
using Factory1 = SharpDX.DXGI.Factory1; using Factory2 = SharpDX.DXGI.Factory2;
using InputElement = SharpDX.Direct3D11.InputElement; using InputElement = SharpDX.Direct3D11.InputElement;
using Matrix = SharpDX.Matrix; using Matrix = SharpDX.Matrix;
using PixelFormat = SharpDX.Direct2D1.PixelFormat; using PixelFormat = SharpDX.Direct2D1.PixelFormat;
using Resource = SharpDX.Direct3D11.Resource;
namespace Direct3DInteropSample namespace Direct3DInteropSample
{ {
class MainWindow : Window public class MainWindow : Window
{ {
private SharpDX.Direct3D11.Device _d3dDevice; Texture2D _backBuffer;
private SharpDX.DXGI.Device _dxgiDevice; RenderTargetView _renderView;
Texture2D backBuffer = null; Texture2D _depthBuffer;
RenderTargetView renderView = null; DepthStencilView _depthView;
Texture2D depthBuffer = null;
DepthStencilView depthView = null;
private readonly SwapChain _swapChain; private readonly SwapChain _swapChain;
private SwapChainDescription _desc; private SwapChainDescription1 _desc;
private Matrix _proj = Matrix.Identity; private Matrix _proj = Matrix.Identity;
private Matrix _view; private readonly Matrix _view;
private Buffer _contantBuffer; private Buffer _contantBuffer;
private SharpDX.Direct2D1.Device _d2dDevice; private DeviceContext _deviceContext;
private SharpDX.Direct2D1.DeviceContext _d2dContext; private readonly MainWindowViewModel _model;
private RenderTarget _d2dRenderTarget;
private MainWindowViewModel _model;
public MainWindow() public MainWindow()
{ {
_dxgiDevice = AvaloniaLocator.Current.GetService<SharpDX.DXGI.Device>();
_d3dDevice = _dxgiDevice.QueryInterface<SharpDX.Direct3D11.Device>();
_d2dDevice = AvaloniaLocator.Current.GetService<SharpDX.Direct2D1.Device>();
DataContext = _model = new MainWindowViewModel(); DataContext = _model = new MainWindowViewModel();
_desc = new SwapChainDescription()
_desc = new SwapChainDescription1()
{ {
BufferCount = 1, BufferCount = 1,
ModeDescription = Width = (int)ClientSize.Width,
new ModeDescription((int)ClientSize.Width, (int)ClientSize.Height, Height = (int)ClientSize.Height,
new Rational(60, 1), Format.R8G8B8A8_UNorm), Format = Format.R8G8B8A8_UNorm,
IsWindowed = true,
OutputHandle = PlatformImpl?.Handle.Handle ?? IntPtr.Zero,
SampleDescription = new SampleDescription(1, 0), SampleDescription = new SampleDescription(1, 0),
SwapEffect = SwapEffect.Discard, SwapEffect = SwapEffect.Discard,
Usage = Usage.RenderTargetOutput Usage = Usage.RenderTargetOutput
}; };
_swapChain = new SwapChain(new Factory1(), _d3dDevice, _desc); using (var factory = Direct2D1Platform.DxgiDevice.Adapter.GetParent<Factory2>())
{
_swapChain = new SwapChain1(factory, Direct2D1Platform.DxgiDevice, PlatformImpl?.Handle.Handle ?? IntPtr.Zero, ref _desc);
}
_d2dContext = new SharpDX.Direct2D1.DeviceContext(_d2dDevice, DeviceContextOptions.None) _deviceContext = new DeviceContext(Direct2D1Platform.Direct2D1Device, DeviceContextOptions.None)
{ {
DotsPerInch = new Size2F(96, 96) DotsPerInch = new Size2F(96, 96)
}; };
CreateMesh(); CreateMesh();
_view = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 0), Vector3.UnitY); _view = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 0), Vector3.UnitY);
this.GetObservable(ClientSizeProperty).Subscribe(Resize); this.GetObservable(ClientSizeProperty).Subscribe(Resize);
Resize(ClientSize); Resize(ClientSize);
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
Background = Avalonia.Media.Brushes.Transparent; Background = Avalonia.Media.Brushes.Transparent;
} }
@ -83,29 +85,32 @@ namespace Direct3DInteropSample
protected override void HandlePaint(Rect rect) protected override void HandlePaint(Rect rect)
{ {
var viewProj = Matrix.Multiply(_view, _proj); var viewProj = Matrix.Multiply(_view, _proj);
var context = _d3dDevice.ImmediateContext; var context = Direct2D1Platform.Direct3D11Device.ImmediateContext;
// Clear views // Clear views
context.ClearDepthStencilView(depthView, DepthStencilClearFlags.Depth, 1.0f, 0); context.ClearDepthStencilView(_depthView, DepthStencilClearFlags.Depth, 1.0f, 0);
context.ClearRenderTargetView(renderView, Color.White); context.ClearRenderTargetView(_renderView, Color.White);
// Update WorldViewProj Matrix // Update WorldViewProj Matrix
var worldViewProj = Matrix.RotationX((float) _model.RotationX) * Matrix.RotationY((float) _model.RotationY) * var worldViewProj = Matrix.RotationX((float)_model.RotationX) * Matrix.RotationY((float)_model.RotationY)
Matrix.RotationZ((float) _model.RotationZ) * Matrix.RotationZ((float)_model.RotationZ)
* Matrix.Scaling((float) _model.Zoom) * viewProj; * Matrix.Scaling((float)_model.Zoom)
* viewProj;
worldViewProj.Transpose(); worldViewProj.Transpose();
context.UpdateSubresource(ref worldViewProj, _contantBuffer); context.UpdateSubresource(ref worldViewProj, _contantBuffer);
// Draw the cube // Draw the cube
context.Draw(36, 0); context.Draw(36, 0);
base.HandlePaint(rect); base.HandlePaint(rect);
// Present! // Present!
_swapChain.Present(0, PresentFlags.None); _swapChain.Present(0, PresentFlags.None);
} }
private void CreateMesh()
void CreateMesh()
{ {
var device = _d3dDevice; var device = Direct2D1Platform.Direct3D11Device;
// Compile Vertex and Pixel shaders // Compile Vertex and Pixel shaders
var vertexShaderByteCode = ShaderBytecode.CompileFromFile("MiniCube.fx", "VS", "vs_4_0"); var vertexShaderByteCode = ShaderBytecode.CompileFromFile("MiniCube.fx", "VS", "vs_4_0");
var vertexShader = new VertexShader(device, vertexShaderByteCode); var vertexShader = new VertexShader(device, vertexShaderByteCode);
@ -114,63 +119,72 @@ namespace Direct3DInteropSample
var pixelShader = new PixelShader(device, pixelShaderByteCode); var pixelShader = new PixelShader(device, pixelShaderByteCode);
var signature = ShaderSignature.GetInputSignature(vertexShaderByteCode); var signature = ShaderSignature.GetInputSignature(vertexShaderByteCode);
var inputElements = new[]
{
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 16, 0)
};
// Layout from VertexShader input signature // Layout from VertexShader input signature
var layout = new InputLayout(device, signature, new[] var layout = new InputLayout(
{ device,
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0), signature,
new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 16, 0) inputElements);
});
// Instantiate Vertex buiffer from vertex data // Instantiate Vertex buiffer from vertex data
var vertices = Buffer.Create(device, BindFlags.VertexBuffer, new[] var vertices = Buffer.Create(
{ device,
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), // Front BindFlags.VertexBuffer,
new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), new[]
new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), {
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), // Front
new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), // BACK new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), // BACK
new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), // Top new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), // Top
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
new Vector4(-1.0f,-1.0f, -1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f), // Bottom new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
new Vector4( 1.0f,-1.0f, 1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f), new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
new Vector4(-1.0f,-1.0f, 1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
new Vector4(-1.0f,-1.0f, -1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f), new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f), // Bottom
new Vector4( 1.0f,-1.0f, -1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f), new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
new Vector4( 1.0f,-1.0f, 1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f), new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f), // Left new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f), new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f), new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f), // Left
new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f), new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f), new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f), // Right new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f), new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f), new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f), // Right
new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f), new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f), new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
}); new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
});
// Create Constant Buffer // Create Constant Buffer
_contantBuffer = new Buffer(device, Utilities.SizeOf<Matrix>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0); _contantBuffer = new Buffer(device, Utilities.SizeOf<Matrix>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
var context = _d3dDevice.ImmediateContext; var context = Direct2D1Platform.Direct3D11Device.ImmediateContext;
// Prepare All the stages // Prepare All the stages
context.InputAssembler.InputLayout = layout; context.InputAssembler.InputLayout = layout;
@ -181,63 +195,73 @@ namespace Direct3DInteropSample
context.PixelShader.Set(pixelShader); context.PixelShader.Set(pixelShader);
} }
void Resize(Size size) private void Resize(Size size)
{ {
Utilities.Dispose(ref _d2dRenderTarget); Utilities.Dispose(ref _deviceContext);
Utilities.Dispose(ref backBuffer); Utilities.Dispose(ref _backBuffer);
Utilities.Dispose(ref renderView); Utilities.Dispose(ref _renderView);
Utilities.Dispose(ref depthBuffer); Utilities.Dispose(ref _depthBuffer);
Utilities.Dispose(ref depthView); Utilities.Dispose(ref _depthView);
var context = _d3dDevice.ImmediateContext; var context = Direct2D1Platform.Direct3D11Device.ImmediateContext;
// Resize the backbuffer // Resize the backbuffer
_swapChain.ResizeBuffers(_desc.BufferCount, (int)size.Width, (int)size.Height, Format.Unknown, SwapChainFlags.None); _swapChain.ResizeBuffers(0, 0, 0, Format.Unknown, SwapChainFlags.None);
// Get the backbuffer from the swapchain // Get the backbuffer from the swapchain
backBuffer = Texture2D.FromSwapChain<Texture2D>(_swapChain, 0); _backBuffer = Resource.FromSwapChain<Texture2D>(_swapChain, 0);
// Renderview on the backbuffer // Renderview on the backbuffer
renderView = new RenderTargetView(_d3dDevice, backBuffer); _renderView = new RenderTargetView(Direct2D1Platform.Direct3D11Device, _backBuffer);
// Create the depth buffer // Create the depth buffer
depthBuffer = new Texture2D(_d3dDevice, new Texture2DDescription() _depthBuffer = new Texture2D(
{ Direct2D1Platform.Direct3D11Device,
Format = Format.D32_Float_S8X24_UInt, new Texture2DDescription()
ArraySize = 1, {
MipLevels = 1, Format = Format.D32_Float_S8X24_UInt,
Width = (int)size.Width, ArraySize = 1,
Height = (int)size.Height, MipLevels = 1,
SampleDescription = new SampleDescription(1, 0), Width = (int)size.Width,
Usage = ResourceUsage.Default, Height = (int)size.Height,
BindFlags = BindFlags.DepthStencil, SampleDescription = new SampleDescription(1, 0),
CpuAccessFlags = CpuAccessFlags.None, Usage = ResourceUsage.Default,
OptionFlags = ResourceOptionFlags.None BindFlags = BindFlags.DepthStencil,
}); CpuAccessFlags = CpuAccessFlags.None,
OptionFlags = ResourceOptionFlags.None
});
// Create the depth buffer view // Create the depth buffer view
depthView = new DepthStencilView(_d3dDevice, depthBuffer); _depthView = new DepthStencilView(Direct2D1Platform.Direct3D11Device, _depthBuffer);
// Setup targets and viewport for rendering // Setup targets and viewport for rendering
context.Rasterizer.SetViewport(new Viewport(0, 0, (int)size.Width, (int)size.Height, 0.0f, 1.0f)); context.Rasterizer.SetViewport(new Viewport(0, 0, (int)size.Width, (int)size.Height, 0.0f, 1.0f));
context.OutputMerger.SetTargets(depthView, renderView); context.OutputMerger.SetTargets(_depthView, _renderView);
// Setup new projection matrix with correct aspect ratio // Setup new projection matrix with correct aspect ratio
_proj = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, (float)(size.Width / size.Height), 0.1f, 100.0f); _proj = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, (float)(size.Width / size.Height), 0.1f, 100.0f);
using (var dxgiBackBuffer = _swapChain.GetBackBuffer<Surface>(0)) using (var dxgiBackBuffer = _swapChain.GetBackBuffer<Surface>(0))
{ {
_d2dRenderTarget = new RenderTarget(AvaloniaLocator.Current.GetService<SharpDX.Direct2D1.Factory>() var renderTarget = new SharpDX.Direct2D1.RenderTarget(
, dxgiBackBuffer, new RenderTargetProperties Direct2D1Platform.Direct2D1Factory,
dxgiBackBuffer,
new RenderTargetProperties
{ {
DpiX = 96, DpiX = 96,
DpiY = 96, DpiY = 96,
Type = RenderTargetType.Default, Type = RenderTargetType.Default,
PixelFormat = new PixelFormat(Format.Unknown, AlphaMode.Premultiplied) PixelFormat = new PixelFormat(
Format.Unknown,
AlphaMode.Premultiplied)
}); });
}
_deviceContext = renderTarget.QueryInterface<DeviceContext>();
renderTarget.Dispose();
}
} }
class D3DRenderTarget: IRenderTarget private class D3DRenderTarget : IRenderTarget
{ {
private readonly MainWindow _window; private readonly MainWindow _window;
@ -245,16 +269,14 @@ namespace Direct3DInteropSample
{ {
_window = window; _window = window;
} }
public void Dispose() public void Dispose()
{ {
} }
public IDrawingContextImpl CreateDrawingContext(IVisualBrushRenderer visualBrushRenderer) public IDrawingContextImpl CreateDrawingContext(IVisualBrushRenderer visualBrushRenderer)
{ {
return new DrawingContextImpl(visualBrushRenderer, null, _window._d2dRenderTarget, return new DrawingContextImpl(visualBrushRenderer, null, _window._deviceContext);
AvaloniaLocator.Current.GetService<SharpDX.DirectWrite.Factory>(),
AvaloniaLocator.Current.GetService<ImagingFactory>());
} }
} }

14
src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs

@ -29,6 +29,8 @@ namespace Avalonia.Direct2D1
{ {
private static readonly Direct2D1Platform s_instance = new Direct2D1Platform(); private static readonly Direct2D1Platform s_instance = new Direct2D1Platform();
public static SharpDX.Direct3D11.Device Direct3D11Device { get; private set; }
public static SharpDX.Direct2D1.Factory1 Direct2D1Factory { get; private set; } public static SharpDX.Direct2D1.Factory1 Direct2D1Factory { get; private set; }
public static SharpDX.Direct2D1.Device1 Direct2D1Device { get; private set; } public static SharpDX.Direct2D1.Device1 Direct2D1Device { get; private set; }
@ -88,14 +90,12 @@ namespace Avalonia.Direct2D1
SharpDX.Direct3D.FeatureLevel.Level_9_1, SharpDX.Direct3D.FeatureLevel.Level_9_1,
}; };
using (var d3dDevice = new SharpDX.Direct3D11.Device( Direct3D11Device = new SharpDX.Direct3D11.Device(
SharpDX.Direct3D.DriverType.Hardware, SharpDX.Direct3D.DriverType.Hardware,
SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport | SharpDX.Direct3D11.DeviceCreationFlags.BgraSupport | SharpDX.Direct3D11.DeviceCreationFlags.VideoSupport,
SharpDX.Direct3D11.DeviceCreationFlags.VideoSupport, featureLevels);
featureLevels))
{ DxgiDevice = Direct3D11Device.QueryInterface<SharpDX.DXGI.Device1>();
DxgiDevice = d3dDevice.QueryInterface<SharpDX.DXGI.Device1>();
}
using (var device = new SharpDX.Direct2D1.Device(Direct2D1Factory, DxgiDevice)) using (var device = new SharpDX.Direct2D1.Device(Direct2D1Factory, DxgiDevice))
{ {

29
src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DBitmapImpl.cs

@ -1,19 +1,20 @@
using System; using System;
using System.IO; using System.IO;
using SharpDX.Direct2D1; using SharpDX.Direct2D1;
using ImageParameters = SharpDX.WIC.ImageParameters;
using ImagingFactory2 = SharpDX.WIC.ImagingFactory2;
using PngBitmapEncoder = SharpDX.WIC.PngBitmapEncoder;
using WICFactory = SharpDX.WIC.ImagingFactory;
namespace Avalonia.Direct2D1.Media namespace Avalonia.Direct2D1.Media
{ {
using SharpDX.WIC;
using Bitmap = SharpDX.Direct2D1.Bitmap;
using PixelFormat = SharpDX.Direct2D1.PixelFormat;
/// <summary> /// <summary>
/// A Direct2D Bitmap implementation that uses a GPU memory bitmap as its image. /// A Direct2D Bitmap implementation that uses a GPU memory bitmap as its image.
/// </summary> /// </summary>
public class D2DBitmapImpl : BitmapImpl public class D2DBitmapImpl : BitmapImpl
{ {
private Bitmap _direct2DBitmap; private readonly Bitmap _direct2DBitmap;
/// <summary> /// <summary>
/// Initialize a new instance of the <see cref="BitmapImpl"/> class /// Initialize a new instance of the <see cref="BitmapImpl"/> class
@ -29,7 +30,7 @@ namespace Avalonia.Direct2D1.Media
{ {
_direct2DBitmap = d2DBitmap ?? throw new ArgumentNullException(nameof(d2DBitmap)); _direct2DBitmap = d2DBitmap ?? throw new ArgumentNullException(nameof(d2DBitmap));
} }
public override int PixelWidth => _direct2DBitmap.PixelSize.Width; public override int PixelWidth => _direct2DBitmap.PixelSize.Width;
public override int PixelHeight => _direct2DBitmap.PixelSize.Height; public override int PixelHeight => _direct2DBitmap.PixelSize.Height;
@ -47,18 +48,12 @@ namespace Avalonia.Direct2D1.Media
public override void Save(Stream stream) public override void Save(Stream stream)
{ {
using (var encoder = new PngBitmapEncoder(Direct2D1Platform.ImagingFactory, stream)) using (var encoder = new PngBitmapEncoder(Direct2D1Platform.ImagingFactory, stream))
using (var frameEncode = new SharpDX.WIC.BitmapFrameEncode(encoder)) using (var frame = new BitmapFrameEncode(encoder))
//ToDo: Not supported under Windows 7! using (var bitmapSource = _direct2DBitmap.QueryInterface<BitmapSource>())
using (var imageEncoder = new SharpDX.WIC.ImageEncoder((ImagingFactory2)Direct2D1Platform.ImagingFactory, null))
{ {
var parameters = new ImageParameters( frame.Initialize();
new PixelFormat(SharpDX.DXGI.Format.R8G8B8A8_UNorm, AlphaMode.Premultiplied), frame.WriteSource(bitmapSource);
_direct2DBitmap.DotsPerInch.Width, frame.Commit();
_direct2DBitmap.DotsPerInch.Height,
0, 0, PixelWidth, PixelHeight);
imageEncoder.WriteFrame(_direct2DBitmap, frameEncode, parameters);
frameEncode.Commit();
encoder.Commit(); encoder.Commit();
} }
} }

5
src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DRenderTargetBitmapImpl.cs

@ -1,4 +1,7 @@
using Avalonia.Platform; // Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Avalonia.Platform;
using Avalonia.Rendering; using Avalonia.Rendering;
using SharpDX; using SharpDX;
using SharpDX.Direct2D1; using SharpDX.Direct2D1;

5
src/Windows/Avalonia.Direct2D1/Media/Imaging/WriteableWicBitmapImpl.cs

@ -1,4 +1,7 @@
using System; // Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using Avalonia.Platform; using Avalonia.Platform;
using SharpDX.WIC; using SharpDX.WIC;
using PixelFormat = Avalonia.Platform.PixelFormat; using PixelFormat = Avalonia.Platform.PixelFormat;

Loading…
Cancel
Save