port from perforce
This commit is contained in:
157
intromat/Intromat/Nodes/Textures/DxTextureNodeBase.cs
Normal file
157
intromat/Intromat/Nodes/Textures/DxTextureNodeBase.cs
Normal file
@@ -0,0 +1,157 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Reactive.Linq;
|
||||
using DynamicData;
|
||||
using Intromat.Graphics;
|
||||
using Intromat.Model.Compiler;
|
||||
using Intromat.Nodes.Code;
|
||||
using Intromat.PersistentModel;
|
||||
using Intromat.ViewModels;
|
||||
using Intromat.ViewModels.Editors;
|
||||
using Intromat.ViewModels.Previews;
|
||||
using NodeNetwork.Toolkit.ValueNode;
|
||||
using NodeNetwork.ViewModels;
|
||||
using ReactiveUI;
|
||||
using SharpDX.Direct3D11;
|
||||
using SharpDX.DXGI;
|
||||
using Splat;
|
||||
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;
|
||||
using Device = SharpDX.Direct3D11.Device;
|
||||
|
||||
namespace Intromat.Nodes.Textures
|
||||
{
|
||||
[CategoryOrder("Texture", 0)]
|
||||
public abstract class DxTextureNodeBase : DxNodeBase
|
||||
{
|
||||
protected TextureValue? _output;
|
||||
protected Texture2DDescription _texDesc;
|
||||
protected bool _resourcesCreated;
|
||||
|
||||
protected DxTextureNodeBase()
|
||||
{
|
||||
var textureGroup = new EndpointGroup("Texture");
|
||||
var parentObservable = this.WhenAnyObservable(vm => vm.ParentChanged).Select(parent => (CodeGenNetworkViewModel?)parent);
|
||||
Inputs.Add(Width = new CodeGenInputViewModel<ITypedExpression<int>>(EPortType.None)
|
||||
{
|
||||
Name = "Width",
|
||||
Group = textureGroup,
|
||||
Editor = WidthEditor = new()
|
||||
{
|
||||
ParentValueProvider = parentObservable.Select(parent => parent?.DefaultWidth ?? -1),
|
||||
MinValue = -16,
|
||||
MaxValue = 16,
|
||||
CustomValue = 0,
|
||||
RelativeSource = ERelativeSource.Parent
|
||||
}
|
||||
});
|
||||
Inputs.Add(Height = new CodeGenInputViewModel<ITypedExpression<int>>(EPortType.None)
|
||||
{
|
||||
Name = "Height",
|
||||
Group = textureGroup,
|
||||
Editor = HeightEditor = new()
|
||||
{
|
||||
ParentValueProvider = parentObservable.Select(parent => parent?.DefaultHeight ?? -1),
|
||||
MinValue = -16,
|
||||
MaxValue = 16,
|
||||
CustomValue = 0,
|
||||
RelativeSource = ERelativeSource.Parent
|
||||
}
|
||||
});
|
||||
Outputs.Add(Output = new CodeGenOutputViewModel<TextureValue?>(EPortType.Texture)
|
||||
{
|
||||
Name = "Output",
|
||||
Group = textureGroup
|
||||
});
|
||||
|
||||
var dxHost = Locator.Current.GetService<DxHost>()!;
|
||||
Output.Value = this
|
||||
.WhenAnyObservable(vm => vm.ParentChanged, vm => vm.AnyInputChanged, (parent, _) => parent)
|
||||
.Where(parent => parent != null)
|
||||
.Throttle(TimeSpan.FromMilliseconds(1))
|
||||
.ObserveOn(dxHost.RenderDispatcher)
|
||||
.Do(_ => { UpdateFrame(dxHost.Device, dxHost.Device.ImmediateContext); })
|
||||
.Select(_ => new TextureValue(_output!));
|
||||
|
||||
var dxTexturePreviewViewModel = new DxTexturePreviewViewModel(this, Output.Value);
|
||||
Preview = dxTexturePreviewViewModel;
|
||||
|
||||
_texDesc = new Texture2DDescription
|
||||
{
|
||||
ArraySize = 1,
|
||||
Format = Format.R16G16B16A16_Float,
|
||||
BindFlags = BindFlags.ShaderResource | BindFlags.UnorderedAccess,
|
||||
Usage = ResourceUsage.Default,
|
||||
SampleDescription = new(1, 0)
|
||||
};
|
||||
}
|
||||
|
||||
[MemberNotNull(nameof(_output))]
|
||||
protected bool EnsureBuffers(Device device)
|
||||
{
|
||||
return EnsureTexture(device, ref _output);
|
||||
}
|
||||
|
||||
protected bool EnsureTexture(Device device, [NotNull] ref TextureValue? textureValue)
|
||||
{
|
||||
var width = ((IntLiteralValue)Width.Value).EvaluateDimension();
|
||||
var height = ((IntLiteralValue)Height.Value).EvaluateDimension();
|
||||
if (_texDesc.Width != width || _texDesc.Height != height || textureValue == null)
|
||||
{
|
||||
textureValue?.ShaderResourceView?.Resource?.Dispose();
|
||||
textureValue?.ShaderResourceView?.Dispose();
|
||||
textureValue?.UnorderedAccessView?.Dispose();
|
||||
|
||||
_texDesc.Width = width;
|
||||
_texDesc.Height = height;
|
||||
var texture = new Texture2D(device, _texDesc);
|
||||
|
||||
textureValue ??= new TextureValue();
|
||||
textureValue.Width = width;
|
||||
textureValue.Height = height;
|
||||
textureValue.ShaderResourceView = new ShaderResourceView(device, texture);
|
||||
textureValue.UnorderedAccessView = new UnorderedAccessView(device, texture);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual void UpdateFrame(Device device, DeviceContext deviceContext)
|
||||
{
|
||||
if (!_resourcesCreated)
|
||||
{
|
||||
_resourcesCreated = true;
|
||||
CreateDeviceResources(device);
|
||||
}
|
||||
EnsureBuffers(device);
|
||||
}
|
||||
|
||||
protected virtual void CreateDeviceResources(Device device)
|
||||
{
|
||||
}
|
||||
|
||||
public override void SaveModel(NodeModelBase model)
|
||||
{
|
||||
base.SaveModel(model);
|
||||
var textureModel = (DxTextureModelBase)model;
|
||||
textureModel.Width = WidthEditor.CreateModel();
|
||||
textureModel.Height = HeightEditor.CreateModel();
|
||||
}
|
||||
|
||||
public override void LoadModel(NodeModelBase model)
|
||||
{
|
||||
base.LoadModel(model);
|
||||
var textureModel = (DxTextureModelBase)model;
|
||||
WidthEditor.LoadModel(textureModel.Width);
|
||||
HeightEditor.LoadModel(textureModel.Height);
|
||||
}
|
||||
|
||||
public DimensionEditorViewModel WidthEditor { get; }
|
||||
public ValueNodeInputViewModel<ITypedExpression<int>> Width { get; }
|
||||
|
||||
public DimensionEditorViewModel HeightEditor { get; }
|
||||
public ValueNodeInputViewModel<ITypedExpression<int>> Height { get; }
|
||||
|
||||
public ValueNodeOutputViewModel<TextureValue?> Output { get; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user