D3D11DemoControl.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. using System;
  2. using System.Diagnostics;
  3. using System.Linq;
  4. using System.Numerics;
  5. using System.Threading.Tasks;
  6. using Avalonia;
  7. using Avalonia.Platform;
  8. using Avalonia.Rendering.Composition;
  9. using SharpDX;
  10. using SharpDX.Direct2D1;
  11. using SharpDX.Direct3D11;
  12. using SharpDX.DXGI;
  13. using SharpDX.Mathematics.Interop;
  14. using Buffer = SharpDX.Direct3D11.Buffer;
  15. using DeviceContext = SharpDX.Direct2D1.DeviceContext;
  16. using DxgiFactory1 = SharpDX.DXGI.Factory1;
  17. using Matrix = SharpDX.Matrix;
  18. using D3DDevice = SharpDX.Direct3D11.Device;
  19. using DxgiResource = SharpDX.DXGI.Resource;
  20. using FeatureLevel = SharpDX.Direct3D.FeatureLevel;
  21. using Vector3 = SharpDX.Vector3;
  22. namespace GpuInterop.D3DDemo;
  23. public class D3D11DemoControl : DrawingSurfaceDemoBase
  24. {
  25. private D3DDevice _device;
  26. private D3D11Swapchain _swapchain;
  27. private SharpDX.Direct3D11.DeviceContext _context;
  28. private Matrix _view;
  29. private PixelSize _lastSize;
  30. private Texture2D _depthBuffer;
  31. private DepthStencilView _depthView;
  32. private Matrix _proj;
  33. private Buffer _constantBuffer;
  34. private Stopwatch _st = Stopwatch.StartNew();
  35. protected override (bool success, string info) InitializeGraphicsResources(Compositor compositor,
  36. CompositionDrawingSurface surface, ICompositionGpuInterop interop)
  37. {
  38. if (interop?.SupportedImageHandleTypes.Contains(KnownPlatformGraphicsExternalImageHandleTypes
  39. .D3D11TextureGlobalSharedHandle) != true)
  40. return (false, "DXGI shared handle import is not supported by the current graphics backend");
  41. var factory = new DxgiFactory1();
  42. using var adapter = factory.GetAdapter1(0);
  43. _device = new D3DDevice(adapter, DeviceCreationFlags.None, new[]
  44. {
  45. FeatureLevel.Level_12_1,
  46. FeatureLevel.Level_12_0,
  47. FeatureLevel.Level_11_1,
  48. FeatureLevel.Level_11_0,
  49. FeatureLevel.Level_10_0,
  50. FeatureLevel.Level_9_3,
  51. FeatureLevel.Level_9_2,
  52. FeatureLevel.Level_9_1,
  53. });
  54. _swapchain = new D3D11Swapchain(_device, interop, surface);
  55. _context = _device.ImmediateContext;
  56. _constantBuffer = D3DContent.CreateMesh(_device);
  57. _view = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 0), Vector3.UnitY);
  58. return (true, $"D3D11 ({_device.FeatureLevel}) {adapter.Description1.Description}");
  59. }
  60. protected override void FreeGraphicsResources()
  61. {
  62. _swapchain.DisposeAsync();
  63. _swapchain = null!;
  64. Utilities.Dispose(ref _depthView);
  65. Utilities.Dispose(ref _depthBuffer);
  66. Utilities.Dispose(ref _constantBuffer);
  67. Utilities.Dispose(ref _context);
  68. Utilities.Dispose(ref _device);
  69. }
  70. protected override bool SupportsDisco => true;
  71. protected override void RenderFrame(PixelSize pixelSize)
  72. {
  73. if (pixelSize == default)
  74. return;
  75. if (pixelSize != _lastSize)
  76. Resize(pixelSize);
  77. using (_swapchain.BeginDraw(pixelSize, out var renderView))
  78. {
  79. _device.ImmediateContext.OutputMerger.SetTargets(_depthView, renderView);
  80. var viewProj = Matrix.Multiply(_view, _proj);
  81. var context = _device.ImmediateContext;
  82. var now = _st.Elapsed.TotalSeconds * 5;
  83. var scaleX = (float)(1f + Disco * (Math.Sin(now) + 1) / 6);
  84. var scaleY = (float)(1f + Disco * (Math.Cos(now) + 1) / 8);
  85. var colorOff =(float) (Math.Sin(now) + 1) / 2 * Disco;
  86. // Clear views
  87. context.ClearDepthStencilView(_depthView, DepthStencilClearFlags.Depth, 1.0f, 0);
  88. context.ClearRenderTargetView(renderView,
  89. new RawColor4(1 - colorOff, colorOff, (float)0.5 + colorOff / 2, 1));
  90. var ypr = Matrix4x4.CreateFromYawPitchRoll(Yaw, Pitch, Roll);
  91. // Update WorldViewProj Matrix
  92. var worldViewProj = Matrix.RotationX((float)Yaw) * Matrix.RotationY((float)Pitch)
  93. * Matrix.RotationZ((float)Roll)
  94. * Matrix.Scaling(new Vector3(scaleX, scaleY, 1))
  95. * viewProj;
  96. worldViewProj.Transpose();
  97. context.UpdateSubresource(ref worldViewProj, _constantBuffer);
  98. // Draw the cube
  99. context.Draw(36, 0);
  100. _context.Flush();
  101. }
  102. }
  103. private void Resize(PixelSize size)
  104. {
  105. Utilities.Dispose(ref _depthBuffer);
  106. _depthBuffer = new Texture2D(_device,
  107. new Texture2DDescription()
  108. {
  109. Format = Format.D32_Float_S8X24_UInt,
  110. ArraySize = 1,
  111. MipLevels = 1,
  112. Width = (int)size.Width,
  113. Height = (int)size.Height,
  114. SampleDescription = new SampleDescription(1, 0),
  115. Usage = ResourceUsage.Default,
  116. BindFlags = BindFlags.DepthStencil,
  117. CpuAccessFlags = CpuAccessFlags.None,
  118. OptionFlags = ResourceOptionFlags.None
  119. });
  120. Utilities.Dispose(ref _depthView);
  121. _depthView = new DepthStencilView(_device, _depthBuffer);
  122. // Setup targets and viewport for rendering
  123. _device.ImmediateContext.Rasterizer.SetViewport(new Viewport(0, 0, (int)size.Width, (int)size.Height, 0.0f, 1.0f));
  124. // Setup new projection matrix with correct aspect ratio
  125. _proj = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, (float)(size.Width / size.Height), 0.1f, 100.0f);
  126. }
  127. }