csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
5.7 KiB
147 lines
5.7 KiB
using System;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Numerics;
|
|
using System.Threading.Tasks;
|
|
using Avalonia;
|
|
using Avalonia.Platform;
|
|
using Avalonia.Rendering.Composition;
|
|
using SharpDX;
|
|
using SharpDX.Direct2D1;
|
|
using SharpDX.Direct3D11;
|
|
using SharpDX.DXGI;
|
|
using SharpDX.Mathematics.Interop;
|
|
using Buffer = SharpDX.Direct3D11.Buffer;
|
|
using DeviceContext = SharpDX.Direct2D1.DeviceContext;
|
|
using DxgiFactory1 = SharpDX.DXGI.Factory1;
|
|
using Matrix = SharpDX.Matrix;
|
|
using D3DDevice = SharpDX.Direct3D11.Device;
|
|
using DxgiResource = SharpDX.DXGI.Resource;
|
|
using FeatureLevel = SharpDX.Direct3D.FeatureLevel;
|
|
using Vector3 = SharpDX.Vector3;
|
|
|
|
namespace GpuInterop.D3DDemo;
|
|
|
|
public class D3D11DemoControl : DrawingSurfaceDemoBase
|
|
{
|
|
private D3DDevice _device;
|
|
private D3D11Swapchain _swapchain;
|
|
private SharpDX.Direct3D11.DeviceContext _context;
|
|
private Matrix _view;
|
|
private PixelSize _lastSize;
|
|
private Texture2D _depthBuffer;
|
|
private DepthStencilView _depthView;
|
|
private Matrix _proj;
|
|
private Buffer _constantBuffer;
|
|
private Stopwatch _st = Stopwatch.StartNew();
|
|
|
|
protected override (bool success, string info) InitializeGraphicsResources(Compositor compositor,
|
|
CompositionDrawingSurface surface, ICompositionGpuInterop interop)
|
|
{
|
|
if (interop?.SupportedImageHandleTypes.Contains(KnownPlatformGraphicsExternalImageHandleTypes
|
|
.D3D11TextureGlobalSharedHandle) != true)
|
|
return (false, "DXGI shared handle import is not supported by the current graphics backend");
|
|
|
|
var factory = new DxgiFactory1();
|
|
using var adapter = factory.GetAdapter1(0);
|
|
_device = new D3DDevice(adapter, DeviceCreationFlags.None, new[]
|
|
{
|
|
FeatureLevel.Level_12_1,
|
|
FeatureLevel.Level_12_0,
|
|
FeatureLevel.Level_11_1,
|
|
FeatureLevel.Level_11_0,
|
|
FeatureLevel.Level_10_0,
|
|
FeatureLevel.Level_9_3,
|
|
FeatureLevel.Level_9_2,
|
|
FeatureLevel.Level_9_1,
|
|
});
|
|
_swapchain = new D3D11Swapchain(_device, interop, surface);
|
|
_context = _device.ImmediateContext;
|
|
_constantBuffer = D3DContent.CreateMesh(_device);
|
|
_view = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 0), Vector3.UnitY);
|
|
return (true, $"D3D11 ({_device.FeatureLevel}) {adapter.Description1.Description}");
|
|
}
|
|
|
|
protected override void FreeGraphicsResources()
|
|
{
|
|
_swapchain.DisposeAsync();
|
|
_swapchain = null!;
|
|
Utilities.Dispose(ref _depthView);
|
|
Utilities.Dispose(ref _depthBuffer);
|
|
Utilities.Dispose(ref _constantBuffer);
|
|
Utilities.Dispose(ref _context);
|
|
Utilities.Dispose(ref _device);
|
|
}
|
|
|
|
protected override bool SupportsDisco => true;
|
|
|
|
protected override void RenderFrame(PixelSize pixelSize)
|
|
{
|
|
if (pixelSize == default)
|
|
return;
|
|
if (pixelSize != _lastSize)
|
|
Resize(pixelSize);
|
|
using (_swapchain.BeginDraw(pixelSize, out var renderView))
|
|
{
|
|
|
|
_device.ImmediateContext.OutputMerger.SetTargets(_depthView, renderView);
|
|
var viewProj = Matrix.Multiply(_view, _proj);
|
|
var context = _device.ImmediateContext;
|
|
|
|
var now = _st.Elapsed.TotalSeconds * 5;
|
|
var scaleX = (float)(1f + Disco * (Math.Sin(now) + 1) / 6);
|
|
var scaleY = (float)(1f + Disco * (Math.Cos(now) + 1) / 8);
|
|
var colorOff =(float) (Math.Sin(now) + 1) / 2 * Disco;
|
|
|
|
|
|
// Clear views
|
|
context.ClearDepthStencilView(_depthView, DepthStencilClearFlags.Depth, 1.0f, 0);
|
|
context.ClearRenderTargetView(renderView,
|
|
new RawColor4(1 - colorOff, colorOff, (float)0.5 + colorOff / 2, 1));
|
|
|
|
|
|
var ypr = Matrix4x4.CreateFromYawPitchRoll(Yaw, Pitch, Roll);
|
|
// Update WorldViewProj Matrix
|
|
var worldViewProj = Matrix.RotationX((float)Yaw) * Matrix.RotationY((float)Pitch)
|
|
* Matrix.RotationZ((float)Roll)
|
|
* Matrix.Scaling(new Vector3(scaleX, scaleY, 1))
|
|
* viewProj;
|
|
worldViewProj.Transpose();
|
|
context.UpdateSubresource(ref worldViewProj, _constantBuffer);
|
|
|
|
// Draw the cube
|
|
context.Draw(36, 0);
|
|
|
|
|
|
_context.Flush();
|
|
}
|
|
}
|
|
|
|
private void Resize(PixelSize size)
|
|
{
|
|
Utilities.Dispose(ref _depthBuffer);
|
|
_depthBuffer = new Texture2D(_device,
|
|
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
|
|
});
|
|
|
|
Utilities.Dispose(ref _depthView);
|
|
_depthView = new DepthStencilView(_device, _depthBuffer);
|
|
|
|
// Setup targets and viewport for rendering
|
|
_device.ImmediateContext.Rasterizer.SetViewport(new Viewport(0, 0, (int)size.Width, (int)size.Height, 0.0f, 1.0f));
|
|
|
|
// 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);
|
|
}
|
|
}
|
|
|