158 lines
6.8 KiB
C#
158 lines
6.8 KiB
C#
using Vortice.Direct2D1;
|
|
using Vortice.DirectWrite;
|
|
using Vortice.DXGI;
|
|
using Vortice.Mathematics;
|
|
using DWriteFactory = Vortice.DirectWrite.IDWriteFactory;
|
|
using D2dFactoryType = Vortice.Direct2D1.FactoryType;
|
|
using DwFactoryType = Vortice.DirectWrite.FactoryType;
|
|
|
|
namespace Automata.Ui.Overlay;
|
|
|
|
public sealed class D2dRenderContext : IDisposable
|
|
{
|
|
private readonly nint _hwnd;
|
|
private readonly int _width;
|
|
private readonly int _height;
|
|
|
|
// Factories
|
|
public ID2D1Factory1 D2dFactory { get; }
|
|
public DWriteFactory DWriteFactory { get; }
|
|
|
|
// Render target (recreated on device loss)
|
|
public ID2D1HwndRenderTarget RenderTarget { get; private set; } = null!;
|
|
|
|
// Pre-created brushes
|
|
public ID2D1SolidColorBrush Red { get; private set; } = null!;
|
|
public ID2D1SolidColorBrush Yellow { get; private set; } = null!;
|
|
public ID2D1SolidColorBrush Cyan { get; private set; } = null!;
|
|
public ID2D1SolidColorBrush Green { get; private set; } = null!;
|
|
public ID2D1SolidColorBrush White { get; private set; } = null!;
|
|
public ID2D1SolidColorBrush Gray { get; private set; } = null!;
|
|
public ID2D1SolidColorBrush LifeBrush { get; private set; } = null!;
|
|
public ID2D1SolidColorBrush ManaBrush { get; private set; } = null!;
|
|
public ID2D1SolidColorBrush ShieldBrush { get; private set; } = null!;
|
|
public ID2D1SolidColorBrush BarBgBrush { get; private set; } = null!;
|
|
public ID2D1SolidColorBrush LabelBgBrush { get; private set; } = null!;
|
|
public ID2D1SolidColorBrush DebugTextBrush { get; private set; } = null!;
|
|
public ID2D1SolidColorBrush TimingBrush { get; private set; } = null!;
|
|
public ID2D1SolidColorBrush DebugBgBrush { get; private set; } = null!;
|
|
public ID2D1SolidColorBrush ProfilerBrush { get; private set; } = null!;
|
|
|
|
// Rarity brushes for entity labels
|
|
public ID2D1SolidColorBrush MagicBrush { get; private set; } = null!;
|
|
public ID2D1SolidColorBrush RareBrush { get; private set; } = null!;
|
|
public ID2D1SolidColorBrush UniqueBrush { get; private set; } = null!;
|
|
|
|
// Text formats
|
|
public IDWriteTextFormat LabelFormat { get; } // 12pt — enemy labels
|
|
public IDWriteTextFormat BarValueFormat { get; } // 11pt — bar values
|
|
public IDWriteTextFormat DebugFormat { get; } // 13pt — debug overlay
|
|
|
|
public D2dRenderContext(nint hwnd, int width, int height)
|
|
{
|
|
_hwnd = hwnd;
|
|
_width = width;
|
|
_height = height;
|
|
|
|
D2dFactory = D2D1.D2D1CreateFactory<ID2D1Factory1>(D2dFactoryType.SingleThreaded);
|
|
DWriteFactory = Vortice.DirectWrite.DWrite.DWriteCreateFactory<DWriteFactory>(DwFactoryType.Shared);
|
|
|
|
CreateRenderTarget();
|
|
CreateBrushes();
|
|
|
|
// Text formats (these survive device loss — they're DWrite, not D2D)
|
|
LabelFormat = DWriteFactory.CreateTextFormat("Consolas", 12f);
|
|
BarValueFormat = DWriteFactory.CreateTextFormat("Consolas", 11f);
|
|
DebugFormat = DWriteFactory.CreateTextFormat("Consolas", 13f);
|
|
}
|
|
|
|
private void CreateRenderTarget()
|
|
{
|
|
var rtProps = new RenderTargetProperties
|
|
{
|
|
Type = RenderTargetType.Software,
|
|
PixelFormat = new Vortice.DCommon.PixelFormat(Format.B8G8R8A8_UNorm, Vortice.DCommon.AlphaMode.Premultiplied),
|
|
};
|
|
var hwndProps = new HwndRenderTargetProperties
|
|
{
|
|
Hwnd = _hwnd,
|
|
PixelSize = new SizeI(_width, _height),
|
|
PresentOptions = PresentOptions.Immediately,
|
|
};
|
|
RenderTarget = D2dFactory.CreateHwndRenderTarget(rtProps, hwndProps);
|
|
RenderTarget.TextAntialiasMode = Vortice.Direct2D1.TextAntialiasMode.Grayscale;
|
|
}
|
|
|
|
private void CreateBrushes()
|
|
{
|
|
Red = RenderTarget.CreateSolidColorBrush(new Color4(1f, 0f, 0f, 1f));
|
|
Yellow = RenderTarget.CreateSolidColorBrush(new Color4(1f, 1f, 0f, 1f));
|
|
Cyan = RenderTarget.CreateSolidColorBrush(new Color4(0f, 1f, 1f, 1f));
|
|
Green = RenderTarget.CreateSolidColorBrush(new Color4(0.31f, 1f, 0.31f, 1f)); // 80,255,80
|
|
White = RenderTarget.CreateSolidColorBrush(new Color4(1f, 1f, 1f, 1f));
|
|
Gray = RenderTarget.CreateSolidColorBrush(new Color4(0.5f, 0.5f, 0.5f, 1f));
|
|
LifeBrush = RenderTarget.CreateSolidColorBrush(new Color4(200 / 255f, 40 / 255f, 40 / 255f, 1f));
|
|
ManaBrush = RenderTarget.CreateSolidColorBrush(new Color4(40 / 255f, 80 / 255f, 200 / 255f, 1f));
|
|
ShieldBrush = RenderTarget.CreateSolidColorBrush(new Color4(100 / 255f, 180 / 255f, 220 / 255f, 1f));
|
|
BarBgBrush = RenderTarget.CreateSolidColorBrush(new Color4(20 / 255f, 20 / 255f, 20 / 255f, 140 / 255f));
|
|
LabelBgBrush = RenderTarget.CreateSolidColorBrush(new Color4(0f, 0f, 0f, 160 / 255f));
|
|
DebugTextBrush = RenderTarget.CreateSolidColorBrush(new Color4(80 / 255f, 1f, 80 / 255f, 1f));
|
|
TimingBrush = RenderTarget.CreateSolidColorBrush(new Color4(1f, 200 / 255f, 80 / 255f, 1f));
|
|
DebugBgBrush = RenderTarget.CreateSolidColorBrush(new Color4(0f, 0f, 0f, 160 / 255f));
|
|
ProfilerBrush = RenderTarget.CreateSolidColorBrush(new Color4(180 / 255f, 140 / 255f, 1f, 1f)); // light purple
|
|
MagicBrush = RenderTarget.CreateSolidColorBrush(new Color4(0.4f, 0.53f, 1f, 1f)); // #6688FF
|
|
RareBrush = RenderTarget.CreateSolidColorBrush(new Color4(1f, 0.93f, 0.34f, 1f)); // #FFEE57
|
|
UniqueBrush = RenderTarget.CreateSolidColorBrush(new Color4(1f, 0.55f, 0f, 1f)); // #FF8C00
|
|
}
|
|
|
|
private void DisposeBrushes()
|
|
{
|
|
Red?.Dispose();
|
|
Yellow?.Dispose();
|
|
Cyan?.Dispose();
|
|
Green?.Dispose();
|
|
White?.Dispose();
|
|
Gray?.Dispose();
|
|
LifeBrush?.Dispose();
|
|
ManaBrush?.Dispose();
|
|
ShieldBrush?.Dispose();
|
|
BarBgBrush?.Dispose();
|
|
LabelBgBrush?.Dispose();
|
|
DebugTextBrush?.Dispose();
|
|
TimingBrush?.Dispose();
|
|
DebugBgBrush?.Dispose();
|
|
ProfilerBrush?.Dispose();
|
|
MagicBrush?.Dispose();
|
|
RareBrush?.Dispose();
|
|
UniqueBrush?.Dispose();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Call after EndDraw returns D2DERR_RECREATE_TARGET.
|
|
/// Recreates the render target and all device-dependent resources.
|
|
/// </summary>
|
|
public void RecreateTarget()
|
|
{
|
|
DisposeBrushes();
|
|
RenderTarget?.Dispose();
|
|
CreateRenderTarget();
|
|
CreateBrushes();
|
|
}
|
|
|
|
/// <summary>Create a text layout for measurement + drawing.</summary>
|
|
public IDWriteTextLayout CreateTextLayout(string text, IDWriteTextFormat format, float maxWidth = 4096f, float maxHeight = 4096f)
|
|
{
|
|
return DWriteFactory.CreateTextLayout(text, format, maxWidth, maxHeight);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
DisposeBrushes();
|
|
RenderTarget?.Dispose();
|
|
LabelFormat?.Dispose();
|
|
BarValueFormat?.Dispose();
|
|
DebugFormat?.Dispose();
|
|
DWriteFactory?.Dispose();
|
|
D2dFactory?.Dispose();
|
|
}
|
|
}
|