diff --git a/samples/interop/Direct3DInteropSample/MainWindow.cs b/samples/interop/Direct3DInteropSample/MainWindow.cs index 19c31a3af1..1ac4b44a74 100644 --- a/samples/interop/Direct3DInteropSample/MainWindow.cs +++ b/samples/interop/Direct3DInteropSample/MainWindow.cs @@ -1,81 +1,83 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +// 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; using Avalonia.Controls; +using Avalonia.Direct2D1; using Avalonia.Direct2D1.Media; using Avalonia.Markup.Xaml; using Avalonia.Platform; using Avalonia.Rendering; + using SharpDX; using SharpDX.D3DCompiler; using SharpDX.Direct2D1; using SharpDX.Direct3D; using SharpDX.Direct3D11; using SharpDX.DXGI; -using SharpDX.WIC; -using SharpDX.Mathematics; + using AlphaMode = SharpDX.Direct2D1.AlphaMode; using Buffer = SharpDX.Direct3D11.Buffer; -using DeviceContext = SharpDX.Direct3D11.DeviceContext; -using Factory1 = SharpDX.DXGI.Factory1; +using DeviceContext = SharpDX.Direct2D1.DeviceContext; +using Factory2 = SharpDX.DXGI.Factory2; using InputElement = SharpDX.Direct3D11.InputElement; using Matrix = SharpDX.Matrix; using PixelFormat = SharpDX.Direct2D1.PixelFormat; +using Resource = SharpDX.Direct3D11.Resource; namespace Direct3DInteropSample { - class MainWindow : Window + public class MainWindow : Window { - private SharpDX.Direct3D11.Device _d3dDevice; - private SharpDX.DXGI.Device _dxgiDevice; - Texture2D backBuffer = null; - RenderTargetView renderView = null; - Texture2D depthBuffer = null; - DepthStencilView depthView = null; + Texture2D _backBuffer; + RenderTargetView _renderView; + Texture2D _depthBuffer; + DepthStencilView _depthView; private readonly SwapChain _swapChain; - private SwapChainDescription _desc; + private SwapChainDescription1 _desc; private Matrix _proj = Matrix.Identity; - private Matrix _view; + private readonly Matrix _view; private Buffer _contantBuffer; - private SharpDX.Direct2D1.Device _d2dDevice; - private SharpDX.Direct2D1.DeviceContext _d2dContext; - private RenderTarget _d2dRenderTarget; - private MainWindowViewModel _model; + private DeviceContext _deviceContext; + private readonly MainWindowViewModel _model; public MainWindow() { - _dxgiDevice = AvaloniaLocator.Current.GetService(); - _d3dDevice = _dxgiDevice.QueryInterface(); - _d2dDevice = AvaloniaLocator.Current.GetService(); DataContext = _model = new MainWindowViewModel(); - _desc = new SwapChainDescription() + + _desc = new SwapChainDescription1() { BufferCount = 1, - ModeDescription = - new ModeDescription((int)ClientSize.Width, (int)ClientSize.Height, - new Rational(60, 1), Format.R8G8B8A8_UNorm), - IsWindowed = true, - OutputHandle = PlatformImpl?.Handle.Handle ?? IntPtr.Zero, + Width = (int)ClientSize.Width, + Height = (int)ClientSize.Height, + Format = Format.R8G8B8A8_UNorm, SampleDescription = new SampleDescription(1, 0), SwapEffect = SwapEffect.Discard, Usage = Usage.RenderTargetOutput }; - _swapChain = new SwapChain(new Factory1(), _d3dDevice, _desc); + using (var factory = Direct2D1Platform.DxgiDevice.Adapter.GetParent()) + { + _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) }; CreateMesh(); + _view = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 0), Vector3.UnitY); + this.GetObservable(ClientSizeProperty).Subscribe(Resize); + Resize(ClientSize); + AvaloniaXamlLoader.Load(this); + Background = Avalonia.Media.Brushes.Transparent; } @@ -83,29 +85,32 @@ namespace Direct3DInteropSample protected override void HandlePaint(Rect rect) { var viewProj = Matrix.Multiply(_view, _proj); - var context = _d3dDevice.ImmediateContext; + var context = Direct2D1Platform.Direct3D11Device.ImmediateContext; + // Clear views - context.ClearDepthStencilView(depthView, DepthStencilClearFlags.Depth, 1.0f, 0); - context.ClearRenderTargetView(renderView, Color.White); + context.ClearDepthStencilView(_depthView, DepthStencilClearFlags.Depth, 1.0f, 0); + context.ClearRenderTargetView(_renderView, Color.White); // Update WorldViewProj Matrix - var worldViewProj = Matrix.RotationX((float) _model.RotationX) * Matrix.RotationY((float) _model.RotationY) * - Matrix.RotationZ((float) _model.RotationZ) - * Matrix.Scaling((float) _model.Zoom) * viewProj; + var worldViewProj = Matrix.RotationX((float)_model.RotationX) * Matrix.RotationY((float)_model.RotationY) + * Matrix.RotationZ((float)_model.RotationZ) + * Matrix.Scaling((float)_model.Zoom) + * viewProj; worldViewProj.Transpose(); context.UpdateSubresource(ref worldViewProj, _contantBuffer); // Draw the cube context.Draw(36, 0); base.HandlePaint(rect); + // Present! _swapChain.Present(0, PresentFlags.None); } - - void CreateMesh() + private void CreateMesh() { - var device = _d3dDevice; + var device = Direct2D1Platform.Direct3D11Device; + // Compile Vertex and Pixel shaders var vertexShaderByteCode = ShaderBytecode.CompileFromFile("MiniCube.fx", "VS", "vs_4_0"); var vertexShader = new VertexShader(device, vertexShaderByteCode); @@ -114,63 +119,72 @@ namespace Direct3DInteropSample var pixelShader = new PixelShader(device, pixelShaderByteCode); 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 - var layout = new InputLayout(device, signature, new[] - { - new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0), - new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 16, 0) - }); - - // Instantiate Vertex buiffer from vertex data - var vertices = Buffer.Create(device, BindFlags.VertexBuffer, new[] - { - 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(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, 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(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, 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(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), - }); + var layout = new InputLayout( + device, + signature, + inputElements); + + // Instantiate Vertex buffer from vertex data + var vertices = Buffer.Create( + device, + BindFlags.VertexBuffer, + new[] + { + 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(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, 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(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, 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(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 _contantBuffer = new Buffer(device, Utilities.SizeOf(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0); - var context = _d3dDevice.ImmediateContext; + var context = Direct2D1Platform.Direct3D11Device.ImmediateContext; // Prepare All the stages context.InputAssembler.InputLayout = layout; @@ -181,63 +195,73 @@ namespace Direct3DInteropSample context.PixelShader.Set(pixelShader); } - void Resize(Size size) + private void Resize(Size size) { - Utilities.Dispose(ref _d2dRenderTarget); - Utilities.Dispose(ref backBuffer); - Utilities.Dispose(ref renderView); - Utilities.Dispose(ref depthBuffer); - Utilities.Dispose(ref depthView); - var context = _d3dDevice.ImmediateContext; + Utilities.Dispose(ref _deviceContext); + Utilities.Dispose(ref _backBuffer); + Utilities.Dispose(ref _renderView); + Utilities.Dispose(ref _depthBuffer); + Utilities.Dispose(ref _depthView); + var context = Direct2D1Platform.Direct3D11Device.ImmediateContext; + // 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 - backBuffer = Texture2D.FromSwapChain(_swapChain, 0); + _backBuffer = Resource.FromSwapChain(_swapChain, 0); // Renderview on the backbuffer - renderView = new RenderTargetView(_d3dDevice, backBuffer); + _renderView = new RenderTargetView(Direct2D1Platform.Direct3D11Device, _backBuffer); // Create the depth buffer - depthBuffer = new Texture2D(_d3dDevice, new Texture2DDescription() - { - Format = Format.D32_Float_S8X24_UInt, - ArraySize = 1, - MipLevels = 1, - Width = (int)size.Width, - Height = (int)size.Height, - SampleDescription = new SampleDescription(1, 0), - Usage = ResourceUsage.Default, - BindFlags = BindFlags.DepthStencil, - CpuAccessFlags = CpuAccessFlags.None, - OptionFlags = ResourceOptionFlags.None - }); + _depthBuffer = new Texture2D( + Direct2D1Platform.Direct3D11Device, + new Texture2DDescription() + { + Format = Format.D32_Float_S8X24_UInt, + ArraySize = 1, + MipLevels = 1, + Width = (int)size.Width, + Height = (int)size.Height, + SampleDescription = new SampleDescription(1, 0), + Usage = ResourceUsage.Default, + BindFlags = BindFlags.DepthStencil, + CpuAccessFlags = CpuAccessFlags.None, + OptionFlags = ResourceOptionFlags.None + }); // Create the depth buffer view - depthView = new DepthStencilView(_d3dDevice, depthBuffer); + _depthView = new DepthStencilView(Direct2D1Platform.Direct3D11Device, _depthBuffer); // Setup targets and viewport for rendering 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 _proj = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, (float)(size.Width / size.Height), 0.1f, 100.0f); using (var dxgiBackBuffer = _swapChain.GetBackBuffer(0)) { - _d2dRenderTarget = new RenderTarget(AvaloniaLocator.Current.GetService() - , dxgiBackBuffer, new RenderTargetProperties + var renderTarget = new SharpDX.Direct2D1.RenderTarget( + Direct2D1Platform.Direct2D1Factory, + dxgiBackBuffer, + new RenderTargetProperties { DpiX = 96, DpiY = 96, Type = RenderTargetType.Default, - PixelFormat = new PixelFormat(Format.Unknown, AlphaMode.Premultiplied) + PixelFormat = new PixelFormat( + Format.Unknown, + AlphaMode.Premultiplied) }); - } + _deviceContext = renderTarget.QueryInterface(); + + renderTarget.Dispose(); + } } - class D3DRenderTarget: IRenderTarget + private class D3DRenderTarget : IRenderTarget { private readonly MainWindow _window; @@ -245,16 +269,14 @@ namespace Direct3DInteropSample { _window = window; } + public void Dispose() { - } public IDrawingContextImpl CreateDrawingContext(IVisualBrushRenderer visualBrushRenderer) { - return new DrawingContextImpl(visualBrushRenderer, null, _window._d2dRenderTarget, - AvaloniaLocator.Current.GetService(), - AvaloniaLocator.Current.GetService()); + return new DrawingContextImpl(visualBrushRenderer, null, _window._deviceContext); } } diff --git a/src/Avalonia.Controls/Border.cs b/src/Avalonia.Controls/Border.cs index c4bc121a27..cd5d3952e7 100644 --- a/src/Avalonia.Controls/Border.cs +++ b/src/Avalonia.Controls/Border.cs @@ -43,8 +43,8 @@ namespace Avalonia.Controls /// static Border() { - AffectsRender(BorderThicknessProperty, CornerRadiusProperty); - AffectsMeasure(BorderThicknessProperty); + AffectsRender(BorderThicknessProperty, CornerRadiusProperty); + AffectsMeasure(BorderThicknessProperty); BrushAffectsRender(BackgroundProperty, BorderBrushProperty); } diff --git a/src/Avalonia.Controls/Button.cs b/src/Avalonia.Controls/Button.cs index fa69d72d67..24b2af7996 100644 --- a/src/Avalonia.Controls/Button.cs +++ b/src/Avalonia.Controls/Button.cs @@ -80,7 +80,7 @@ namespace Avalonia.Controls FocusableProperty.OverrideDefaultValue(typeof(Button), true); CommandProperty.Changed.Subscribe(CommandChanged); IsDefaultProperty.Changed.Subscribe(IsDefaultChanged); - PseudoClass(IsPressedProperty, ":pressed"); + PseudoClass