146 lines
3.5 KiB
C#
146 lines
3.5 KiB
C#
using System;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Runtime.InteropServices;
|
|
using Dalamud.Bindings.ImGui;
|
|
using TerraFX.Interop.DirectX;
|
|
|
|
namespace Auspex.Rendering.Direct3D;
|
|
|
|
internal sealed class HighResFontAtlas : IDisposable
|
|
{
|
|
private struct ImFontConfigHead
|
|
{
|
|
public IntPtr FontData;
|
|
|
|
public int FontDataSize;
|
|
|
|
public byte FontDataOwnedByAtlas;
|
|
|
|
private byte _pad1;
|
|
|
|
private byte _pad2;
|
|
|
|
private byte _pad3;
|
|
|
|
public int FontNo;
|
|
|
|
public float SizePixels;
|
|
}
|
|
|
|
private const float HighResFontSize = 64f;
|
|
|
|
private IntPtr _atlas;
|
|
|
|
private unsafe ID3D11Texture2D* _texture;
|
|
|
|
private unsafe ID3D11ShaderResourceView* _srv;
|
|
|
|
public ImFontPtr Font { get; }
|
|
|
|
public unsafe IntPtr TextureSRV => (nint)_srv;
|
|
|
|
public unsafe HighResFontAtlas(FrameRenderContext ctx)
|
|
{
|
|
_atlas = ImFontAtlas_ImFontAtlas();
|
|
try
|
|
{
|
|
IntPtr intPtr = ImFontConfig_ImFontConfig();
|
|
try
|
|
{
|
|
((ImFontConfigHead*)intPtr)->SizePixels = 64f;
|
|
IntPtr intPtr2 = ImFontAtlas_AddFontDefault(_atlas, intPtr);
|
|
Font = Unsafe.As<IntPtr, ImFontPtr>(ref intPtr2);
|
|
}
|
|
finally
|
|
{
|
|
ImFontConfig_destroy(intPtr);
|
|
}
|
|
if (!ImFontAtlas_Build(_atlas))
|
|
{
|
|
throw new InvalidOperationException("Failed to build high-res font atlas");
|
|
}
|
|
byte* pSysMem = default(byte*);
|
|
int num = default(int);
|
|
int height = default(int);
|
|
int num2 = default(int);
|
|
ImFontAtlas_GetTexDataAsRGBA32(_atlas, 0, &pSysMem, &num, &height, &num2);
|
|
D3D11_TEXTURE2D_DESC d3D11_TEXTURE2D_DESC = new D3D11_TEXTURE2D_DESC
|
|
{
|
|
Width = (uint)num,
|
|
Height = (uint)height,
|
|
MipLevels = 1u,
|
|
ArraySize = 1u,
|
|
Format = DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM,
|
|
SampleDesc = new DXGI_SAMPLE_DESC
|
|
{
|
|
Count = 1u,
|
|
Quality = 0u
|
|
},
|
|
Usage = D3D11_USAGE.D3D11_USAGE_DEFAULT,
|
|
BindFlags = 8u
|
|
};
|
|
D3D11_SUBRESOURCE_DATA d3D11_SUBRESOURCE_DATA = new D3D11_SUBRESOURCE_DATA
|
|
{
|
|
pSysMem = pSysMem,
|
|
SysMemPitch = (uint)(num * num2)
|
|
};
|
|
ID3D11Texture2D* texture = default(ID3D11Texture2D*);
|
|
Marshal.ThrowExceptionForHR(ctx.Device->CreateTexture2D(&d3D11_TEXTURE2D_DESC, &d3D11_SUBRESOURCE_DATA, &texture));
|
|
_texture = texture;
|
|
ID3D11ShaderResourceView* srv = default(ID3D11ShaderResourceView*);
|
|
Marshal.ThrowExceptionForHR(ctx.Device->CreateShaderResourceView((ID3D11Resource*)_texture, null, &srv));
|
|
_srv = srv;
|
|
ImFontAtlas_ClearTexData(_atlas);
|
|
}
|
|
catch
|
|
{
|
|
Dispose();
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public unsafe void Dispose()
|
|
{
|
|
if (_srv != null)
|
|
{
|
|
_srv->Release();
|
|
_srv = null;
|
|
}
|
|
if (_texture != null)
|
|
{
|
|
_texture->Release();
|
|
_texture = null;
|
|
}
|
|
if (_atlas != (IntPtr)0)
|
|
{
|
|
ImFontAtlas_destroy(_atlas);
|
|
_atlas = (IntPtr)0;
|
|
}
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
[DllImport("cimgui")]
|
|
private static extern IntPtr ImFontAtlas_ImFontAtlas();
|
|
|
|
[DllImport("cimgui")]
|
|
private static extern void ImFontAtlas_destroy(IntPtr self);
|
|
|
|
[DllImport("cimgui")]
|
|
private static extern IntPtr ImFontAtlas_AddFontDefault(IntPtr self, IntPtr font_cfg);
|
|
|
|
[DllImport("cimgui")]
|
|
[return: MarshalAs(UnmanagedType.U1)]
|
|
private static extern bool ImFontAtlas_Build(IntPtr self);
|
|
|
|
[DllImport("cimgui")]
|
|
private unsafe static extern void ImFontAtlas_GetTexDataAsRGBA32(IntPtr self, int texture_index, byte** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel);
|
|
|
|
[DllImport("cimgui")]
|
|
private static extern void ImFontAtlas_ClearTexData(IntPtr self);
|
|
|
|
[DllImport("cimgui")]
|
|
private static extern IntPtr ImFontConfig_ImFontConfig();
|
|
|
|
[DllImport("cimgui")]
|
|
private static extern void ImFontConfig_destroy(IntPtr self);
|
|
}
|