XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Numerics;
using System.Runtime.InteropServices;
using Vortice.D3DCompiler;
using Vortice.Direct3D;
using Vortice.Direct3D11;
using Vortice.DXGI;
using XFEEDToolBox.Core.Galaxy;
using XFEEDToolBox.Core.Rendering;

namespace XFEEDToolBox.Rendering;

internal sealed partial class GalaxyGraphics
{
    private ID3D11VertexShader powerActivityRingVs=null!;
    private ID3D11PixelShader powerActivityRingPs=null!;
    private ID3D11InputLayout powerActivityRingLayout=null!;
    private ID3D11Buffer powerActivityRingInstance=null!,powerActivityRingConstants=null!;
    private ID3D11BlendState powerActivityRingBlend=null!;
    private GalaxyOriginalPowerActivityRing? powerActivityRing;
    private float? powerActivityRingEmissive;
    private bool powerActivityRingDefaultKnown;
    private bool powerActivityRingInvalidSource;
    internal int PreparedPowerActivityRings=>powerActivityRing is null?0:1;
    internal int SubmittedPowerActivityRings {get;private set;}
    internal bool PowerActivityRingSourceUnknown=>powerActivityRing is not null&&(powerActivityRingInvalidSource||powerActivityRingEmissive is null&&!OriginalExposureReady);
    internal bool PowerActivityRingSourceDefaultKnown=>powerActivityRing is not null&&(powerActivityRingDefaultKnown||
        !powerActivityRingInvalidSource&&powerActivityRingEmissive is null&&OriginalExposureState==GalaxyOriginalExposureState.DefaultCreated);
    internal bool PowerActivityRingUsesToolManualExposure=>powerActivityRing is not null&&!powerActivityRingInvalidSource&&powerActivityRingEmissive is null&&OriginalExposureIsToolManual;
    internal bool OriginalPowerActivityRingGeometryRestored=>true;
    internal bool OriginalPowerActivityRingFullRestored=>false;

    // No guessed unity exposure in production. A source-space probe may pass
    // an explicitly labelled synthetic scalar; unknown runtime input hides it.
    internal void SetOriginalPowerActivityRing(GalaxyOriginalPowerActivityRing? ring,float? emissiveRescaling,bool originalDefaultBoundKnown=false)
    {
        powerActivityRing=ring is{} value&&GalaxyOriginalPowerActivityRingGeometry.IsValid(value)?value:null;
        // The flag means the original six-texel zero resource is actually
        // created/bound and ready in this view. Static bytes alone are not a
        // runtime readiness signal. Explicit invalid inputs remain unknown.
        powerActivityRingDefaultKnown=originalDefaultBoundKnown&&emissiveRescaling is null;
        powerActivityRingEmissive=powerActivityRingDefaultKnown?0:emissiveRescaling is{} scalar&&float.IsFinite(scalar)&&scalar>=0?scalar:null;
        powerActivityRingInvalidSource=emissiveRescaling is{} supplied&&(!float.IsFinite(supplied)||supplied<0);
        SubmittedPowerActivityRings=0;
    }
    private void InitializeOriginalPowerActivityRing(string shader)
    {
        if(Marshal.SizeOf<GalaxyOriginalPowerActivityRing>()!=64)throw new InvalidDataException("原活动范围实例格式无效。");
        var path=Path.Combine(Path.GetDirectoryName(shader)!,"GalaxyPowerActivityRing.hlsl");
        var vs=Compiler.CompileFromFile(path,"VSOriginalPowerActivityRing","vs_5_0");powerActivityRingVs=device.CreateVertexShader(vs.Span);
        powerActivityRingPs=device.CreatePixelShader(Compiler.CompileFromFile(path,"PSOriginalPowerActivityRing","ps_5_0").Span);
        powerActivityRingLayout=device.CreateInputLayout([
            new InputElementDescription("POSITION",0,Format.R32G32B32A32_Float,0,0,InputClassification.PerInstanceData,1),
            new InputElementDescription("UAXISINNER",0,Format.R32G32B32A32_Float,16,0,InputClassification.PerInstanceData,1),
            new InputElementDescription("VAXISOUTER",0,Format.R32G32B32A32_Float,32,0,InputClassification.PerInstanceData,1),
            new InputElementDescription("USERDATA",0,Format.R32G32B32A32_Float,48,0,InputClassification.PerInstanceData,1)],vs.Span);
        powerActivityRingInstance=device.CreateBuffer(64,BindFlags.VertexBuffer,ResourceUsage.Dynamic,CpuAccessFlags.Write);
        powerActivityRingConstants=device.CreateBuffer(96,BindFlags.ConstantBuffer);
        // Actual FocusRing kind5 effect bytecode:One/InverseSourceAlpha/Add.
        // Original range record's source alpha0 makes the RGB additive.
        powerActivityRingBlend=device.CreateBlendState(new BlendDescription(Blend.One,Blend.InverseSourceAlpha));
    }
    private void DrawOriginalPowerActivityRing(GalaxyCamera camera,float hdrWrite)
    {
        SubmittedPowerActivityRings=0;
        if(powerActivityRing is not{} ring||powerActivityRingInvalidSource)return;
        var useTexture=powerActivityRingEmissive is null&&OriginalExposureReady;
        if(powerActivityRingEmissive is null&&!useTexture)return;
        var emissive=powerActivityRingEmissive??OriginalManualExposureResult?.Type2EmissiveRescaling??0;
        if(emissive==0&&ring.Colour.W==0)return;
        if(!float.IsFinite(hdrWrite)||hdrWrite<=0)return;
        var eye=camera.Eye;var right=camera.Right;var up=camera.Up;var forward=camera.Forward;
        var frame=new PowerActivityRingCamera(new((float)eye.X,(float)eye.Y,(float)eye.Z,(float)camera.FocalLength),
            new((float)right.X,(float)right.Y,(float)right.Z,(float)camera.Width),new((float)up.X,(float)up.Y,(float)up.Z,(float)camera.Height),
            new((float)forward.X,(float)forward.Y,(float)forward.Z,(float)camera.Near),
            new(GalaxyOriginalPowerActivityRingGeometry.QuadCount,GalaxyOriginalPowerActivityRingGeometry.RadialFeather,GalaxyOriginalPowerActivityRingGeometry.SegmentFeather,GalaxyOriginalPowerActivityRingGeometry.SolidRatio),
            new(GalaxyOriginalPowerActivityRingGeometry.SegmentCount,emissive,hdrWrite,useTexture?1:0));
        Upload<GalaxyOriginalPowerActivityRing>(powerActivityRingInstance,new[]{ring});context.UpdateSubresource(in frame,powerActivityRingConstants);
        context.VSSetConstantBuffer(11,powerActivityRingConstants);context.PSSetConstantBuffer(11,powerActivityRingConstants);
        context.IASetInputLayout(powerActivityRingLayout);context.IASetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
        context.IASetVertexBuffer(0,powerActivityRingInstance,64);context.VSSetShader(powerActivityRingVs);context.PSSetShader(powerActivityRingPs);
        context.PSSetShaderResource(20,useTexture?originalExposureView!:null!);
        context.OMSetBlendState(powerActivityRingBlend);context.DrawInstanced(GalaxyOriginalPowerActivityRingGeometry.VertexCount,1,0,0);
        context.PSSetShaderResource(20,null!);
        DrawCalls++;SubmittedPowerActivityRings=1;
    }
    private void DisposeOriginalPowerActivityRing()
    {
        powerActivityRingVs.Dispose();powerActivityRingPs.Dispose();powerActivityRingLayout.Dispose();
        powerActivityRingInstance.Dispose();powerActivityRingConstants.Dispose();powerActivityRingBlend.Dispose();
    }
    [StructLayout(LayoutKind.Sequential)]
    private readonly record struct PowerActivityRingCamera(Vector4 EyeFocal,Vector4 RightWidth,Vector4 UpHeight,Vector4 ForwardNear,Vector4 Material,Vector4 Output);
}