using System.Numerics;
using System.Runtime.InteropServices;
using Vortice.D3DCompiler;
using Vortice.Direct3D;
using Vortice.Direct3D11;
using Vortice.DXGI;
using XFEEDToolBox.Core.Rendering;
namespace XFEEDToolBox.Rendering;
internal sealed partial class GalaxyGraphics
{
private ID3D11PixelShader zonesPs=null!;
private ID3D11Buffer zonesConstants=null!;
private ID3D11Texture2D? zoneIdTexture,zoneBoundaryTexture;
private ID3D11ShaderResourceView? zoneIds,zoneBoundaries;
private Task<GalaxyZoneRaster>? zoneRasterTask;
internal bool ShowGalacticZonesPlane {get;set;}
internal bool GalacticZonesPlaneReady=>zoneIds is not null&&zoneBoundaries is not null;
internal bool GalacticZonesPlaneDrawn {get;private set;}
private void InitializeGalacticZones(string shader)
{
zonesPs=device.CreatePixelShader(Compiler.CompileFromFile(shader,"PSGalacticZones","ps_5_0").Span);
zonesConstants=device.CreateBuffer(48,BindFlags.ConstantBuffer);
}
private bool PrepareGalacticZones()
{
if(GalacticZonesPlaneReady)return true;
if(zoneRasterTask is null)
{
zoneRasterTask=Task.Run(()=>GalaxyZoneRaster.Create(GalaxyOriginalZones.Reference));
_=zoneRasterTask.ContinueWith(task=>App.MainWindow.DispatcherQueue.TryEnqueue(()=>
{
if(disposed)return;
if(task.IsFaulted)App.Runtime.Log("银河区域",task.Exception!.GetBaseException().Message);
ResourcesChanged?.Invoke();
}),TaskScheduler.Default);
return false;
}
if(!zoneRasterTask.IsCompletedSuccessfully)return false;
var raster=zoneRasterTask.Result;var pins=new GCHandle[raster.BoundaryMips.Length+1];
try
{
pins[0]=GCHandle.Alloc(raster.Ids,GCHandleType.Pinned);
zoneIdTexture=device.CreateTexture2D(new Texture2DDescription{Width=(uint)raster.Map.Width,Height=(uint)raster.Map.Height,MipLevels=1,ArraySize=1,
Format=Format.R8_UInt,SampleDescription=new(1,0),Usage=ResourceUsage.Immutable,BindFlags=BindFlags.ShaderResource},
[new SubresourceData(pins[0].AddrOfPinnedObject(),(uint)raster.Map.Width,0)]);
var mipData=new SubresourceData[raster.BoundaryMips.Length];
for(var index=0;index<mipData.Length;index++)
{
var mip=raster.BoundaryMips[index];pins[index+1]=GCHandle.Alloc(mip.Pixels,GCHandleType.Pinned);
mipData[index]=new(pins[index+1].AddrOfPinnedObject(),(uint)mip.Width,0);
}
zoneBoundaryTexture=device.CreateTexture2D(new Texture2DDescription{Width=(uint)raster.Map.Width,Height=(uint)raster.Map.Height,
MipLevels=(uint)mipData.Length,ArraySize=1,Format=Format.R8_UNorm,SampleDescription=new(1,0),Usage=ResourceUsage.Immutable,BindFlags=BindFlags.ShaderResource},mipData);
zoneIds=device.CreateShaderResourceView(zoneIdTexture);zoneBoundaries=device.CreateShaderResourceView(zoneBoundaryTexture);
var map=raster.Map;
var data=new GalacticZoneCamera(new(map.ScaleX/4096f,map.ScaleZ/4096f,(float)map.OriginX,(float)map.OriginZ),
new(map.Width,map.Height,0,0),new(.14f,1.05f,0,0));
context.UpdateSubresource(in data,zonesConstants);zoneRasterTask=null;return true;
}
finally{foreach(var pin in pins)if(pin.IsAllocated)pin.Free();}
}
private void DrawGalacticZones()
{
GalacticZonesPlaneDrawn=false;
if(!ShowGalacticZonesPlane||!PrepareGalacticZones())return;
// Y=0 is this tool's geographic annotation plane. Original raster and
// transforms are proven; the original GZM GPU material is not restored.
// Only its boundaries are shown, before stars and navigation overlays.
context.IASetInputLayout(null);context.IASetPrimitiveTopology(PrimitiveTopology.TriangleList);
context.VSSetShader(skyVs);context.PSSetShader(zonesPs);context.PSSetConstantBuffer(2,zonesConstants);
context.PSSetShaderResource(5,zoneIds!);context.PSSetShaderResource(6,zoneBoundaries!);context.PSSetSampler(0,sampler);
context.Draw(3,0);context.PSSetShaderResource(5,null!);context.PSSetShaderResource(6,null!);
DrawCalls++;GalacticZonesPlaneDrawn=true;
}
private void DisposeGalacticZones()
{
zoneIds?.Dispose();zoneBoundaries?.Dispose();zoneIdTexture?.Dispose();zoneBoundaryTexture?.Dispose();
zonesPs.Dispose();zonesConstants.Dispose();zoneRasterTask=null;
}
[StructLayout(LayoutKind.Sequential)] private readonly record struct GalacticZoneCamera(Vector4 Transform,Vector4 Dimensions,Vector4 Settings);
}
using System.Numerics;
using System.Runtime.InteropServices;
using Vortice.D3DCompiler;
using Vortice.Direct3D;
using Vortice.Direct3D11;
using Vortice.DXGI;
using XFEEDToolBox.Core.Rendering;
namespace XFEEDToolBox.Rendering;
internal sealed partial class GalaxyGraphics
{
private ID3D11PixelShader zonesPs=null!;
private ID3D11Buffer zonesConstants=null!;
private ID3D11Texture2D? zoneIdTexture,zoneBoundaryTexture;
private ID3D11ShaderResourceView? zoneIds,zoneBoundaries;
private Task<GalaxyZoneRaster>? zoneRasterTask;
internal bool ShowGalacticZonesPlane {get;set;}
internal bool GalacticZonesPlaneReady=>zoneIds is not null&&zoneBoundaries is not null;
internal bool GalacticZonesPlaneDrawn {get;private set;}
private void InitializeGalacticZones(string shader)
{
zonesPs=device.CreatePixelShader(Compiler.CompileFromFile(shader,"PSGalacticZones","ps_5_0").Span);
zonesConstants=device.CreateBuffer(48,BindFlags.ConstantBuffer);
}
private bool PrepareGalacticZones()
{
if(GalacticZonesPlaneReady)return true;
if(zoneRasterTask is null)
{
zoneRasterTask=Task.Run(()=>GalaxyZoneRaster.Create(GalaxyOriginalZones.Reference));
_=zoneRasterTask.ContinueWith(task=>App.MainWindow.DispatcherQueue.TryEnqueue(()=>
{
if(disposed)return;
if(task.IsFaulted)App.Runtime.Log("银河区域",task.Exception!.GetBaseException().Message);
ResourcesChanged?.Invoke();
}),TaskScheduler.Default);
return false;
}
if(!zoneRasterTask.IsCompletedSuccessfully)return false;
var raster=zoneRasterTask.Result;var pins=new GCHandle[raster.BoundaryMips.Length+1];
try
{
pins[0]=GCHandle.Alloc(raster.Ids,GCHandleType.Pinned);
zoneIdTexture=device.CreateTexture2D(new Texture2DDescription{Width=(uint)raster.Map.Width,Height=(uint)raster.Map.Height,MipLevels=1,ArraySize=1,
Format=Format.R8_UInt,SampleDescription=new(1,0),Usage=ResourceUsage.Immutable,BindFlags=BindFlags.ShaderResource},
[new SubresourceData(pins[0].AddrOfPinnedObject(),(uint)raster.Map.Width,0)]);
var mipData=new SubresourceData[raster.BoundaryMips.Length];
for(var index=0;index<mipData.Length;index++)
{
var mip=raster.BoundaryMips[index];pins[index+1]=GCHandle.Alloc(mip.Pixels,GCHandleType.Pinned);
mipData[index]=new(pins[index+1].AddrOfPinnedObject(),(uint)mip.Width,0);
}
zoneBoundaryTexture=device.CreateTexture2D(new Texture2DDescription{Width=(uint)raster.Map.Width,Height=(uint)raster.Map.Height,
MipLevels=(uint)mipData.Length,ArraySize=1,Format=Format.R8_UNorm,SampleDescription=new(1,0),Usage=ResourceUsage.Immutable,BindFlags=BindFlags.ShaderResource},mipData);
zoneIds=device.CreateShaderResourceView(zoneIdTexture);zoneBoundaries=device.CreateShaderResourceView(zoneBoundaryTexture);
var map=raster.Map;
var data=new GalacticZoneCamera(new(map.ScaleX/4096f,map.ScaleZ/4096f,(float)map.OriginX,(float)map.OriginZ),
new(map.Width,map.Height,0,0),new(.14f,1.05f,0,0));
context.UpdateSubresource(in data,zonesConstants);zoneRasterTask=null;return true;
}
finally{foreach(var pin in pins)if(pin.IsAllocated)pin.Free();}
}
private void DrawGalacticZones()
{
GalacticZonesPlaneDrawn=false;
if(!ShowGalacticZonesPlane||!PrepareGalacticZones())return;
// Y=0 is this tool's geographic annotation plane. Original raster and
// transforms are proven; the original GZM GPU material is not restored.
// Only its boundaries are shown, before stars and navigation overlays.
context.IASetInputLayout(null);context.IASetPrimitiveTopology(PrimitiveTopology.TriangleList);
context.VSSetShader(skyVs);context.PSSetShader(zonesPs);context.PSSetConstantBuffer(2,zonesConstants);
context.PSSetShaderResource(5,zoneIds!);context.PSSetShaderResource(6,zoneBoundaries!);context.PSSetSampler(0,sampler);
context.Draw(3,0);context.PSSetShaderResource(5,null!);context.PSSetShaderResource(6,null!);
DrawCalls++;GalacticZonesPlaneDrawn=true;
}
private void DisposeGalacticZones()
{
zoneIds?.Dispose();zoneBoundaries?.Dispose();zoneIdTexture?.Dispose();zoneBoundaryTexture?.Dispose();
zonesPs.Dispose();zonesConstants.Dispose();zoneRasterTask=null;
}
[StructLayout(LayoutKind.Sequential)] private readonly record struct GalacticZoneCamera(Vector4 Transform,Vector4 Dimensions,Vector4 Settings);
}