2022-04-13 03:06:14 +00:00
|
|
|
using System;
|
2023-12-07 01:33:17 +00:00
|
|
|
using System.Runtime.InteropServices;
|
2022-04-13 03:06:14 +00:00
|
|
|
using WellspringCS;
|
|
|
|
|
|
|
|
namespace MoonWorks.Graphics.Font
|
|
|
|
{
|
2023-12-07 01:33:17 +00:00
|
|
|
public unsafe class TextBatch : IDisposable
|
2022-04-13 03:06:14 +00:00
|
|
|
{
|
2023-12-07 01:33:17 +00:00
|
|
|
public const int MAX_CHARS = 4096;
|
|
|
|
public const int MAX_VERTICES = MAX_CHARS * 4;
|
|
|
|
public const int MAX_INDICES = MAX_CHARS * 6;
|
|
|
|
|
2022-04-13 03:06:14 +00:00
|
|
|
private GraphicsDevice GraphicsDevice { get; }
|
|
|
|
public IntPtr Handle { get; }
|
|
|
|
|
|
|
|
public Buffer VertexBuffer { get; protected set; } = null;
|
|
|
|
public Buffer IndexBuffer { get; protected set; } = null;
|
|
|
|
public uint PrimitiveCount { get; protected set; }
|
|
|
|
|
2023-12-08 06:54:58 +00:00
|
|
|
public Font CurrentFont { get; private set; }
|
2023-12-07 01:33:17 +00:00
|
|
|
|
|
|
|
private byte* StringBytes;
|
|
|
|
private int StringBytesLength;
|
|
|
|
|
|
|
|
private bool IsDisposed;
|
2022-06-30 20:25:52 +00:00
|
|
|
|
2022-04-13 03:06:14 +00:00
|
|
|
public TextBatch(GraphicsDevice graphicsDevice)
|
|
|
|
{
|
|
|
|
GraphicsDevice = graphicsDevice;
|
|
|
|
Handle = Wellspring.Wellspring_CreateTextBatch();
|
2023-12-07 01:33:17 +00:00
|
|
|
|
|
|
|
StringBytesLength = 128;
|
|
|
|
StringBytes = (byte*) NativeMemory.Alloc((nuint) StringBytesLength);
|
|
|
|
|
|
|
|
VertexBuffer = Buffer.Create<Vertex>(GraphicsDevice, BufferUsageFlags.Vertex, MAX_VERTICES);
|
|
|
|
IndexBuffer = Buffer.Create<uint>(GraphicsDevice, BufferUsageFlags.Index, MAX_INDICES);
|
2022-04-13 03:06:14 +00:00
|
|
|
}
|
|
|
|
|
2023-12-07 01:33:17 +00:00
|
|
|
public void Start(Font font)
|
2022-04-13 03:06:14 +00:00
|
|
|
{
|
2023-12-07 01:33:17 +00:00
|
|
|
Wellspring.Wellspring_StartTextBatch(Handle, font.Handle);
|
|
|
|
CurrentFont = font;
|
2022-04-13 03:06:14 +00:00
|
|
|
PrimitiveCount = 0;
|
|
|
|
}
|
|
|
|
|
2023-12-07 01:33:17 +00:00
|
|
|
public unsafe bool Add(
|
2022-04-13 22:10:23 +00:00
|
|
|
string text,
|
2023-12-08 06:54:58 +00:00
|
|
|
int pixelSize,
|
2022-04-13 22:10:23 +00:00
|
|
|
Color color,
|
|
|
|
HorizontalAlignment horizontalAlignment = HorizontalAlignment.Left,
|
|
|
|
VerticalAlignment verticalAlignment = VerticalAlignment.Baseline
|
|
|
|
) {
|
2022-06-30 20:24:51 +00:00
|
|
|
var byteCount = System.Text.Encoding.UTF8.GetByteCount(text);
|
|
|
|
|
2023-12-07 01:33:17 +00:00
|
|
|
if (StringBytesLength < byteCount)
|
2022-06-30 20:24:51 +00:00
|
|
|
{
|
2023-12-07 01:33:17 +00:00
|
|
|
StringBytes = (byte*) NativeMemory.Realloc(StringBytes, (nuint) byteCount);
|
2022-06-30 20:24:51 +00:00
|
|
|
}
|
|
|
|
|
2022-04-13 03:06:14 +00:00
|
|
|
fixed (char* chars = text)
|
|
|
|
{
|
2023-12-07 01:33:17 +00:00
|
|
|
System.Text.Encoding.UTF8.GetBytes(chars, text.Length, StringBytes, byteCount);
|
2022-04-13 03:06:14 +00:00
|
|
|
|
2023-12-10 01:41:08 +00:00
|
|
|
var result = Wellspring.Wellspring_AddToTextBatch(
|
2022-04-13 03:06:14 +00:00
|
|
|
Handle,
|
2023-12-08 06:54:58 +00:00
|
|
|
pixelSize,
|
2022-04-13 03:06:14 +00:00
|
|
|
new Wellspring.Color { R = color.R, G = color.G, B = color.B, A = color.A },
|
2022-04-13 22:10:23 +00:00
|
|
|
(Wellspring.HorizontalAlignment) horizontalAlignment,
|
|
|
|
(Wellspring.VerticalAlignment) verticalAlignment,
|
2023-12-07 01:33:17 +00:00
|
|
|
(IntPtr) StringBytes,
|
2022-04-13 03:06:14 +00:00
|
|
|
(uint) byteCount
|
|
|
|
);
|
|
|
|
|
|
|
|
if (result == 0)
|
|
|
|
{
|
2023-12-07 01:33:17 +00:00
|
|
|
Logger.LogWarn("Could not decode string: " + text);
|
|
|
|
return false;
|
2022-04-13 03:06:14 +00:00
|
|
|
}
|
|
|
|
}
|
2023-12-07 01:33:17 +00:00
|
|
|
|
|
|
|
return true;
|
2022-04-13 03:06:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Call this after you have made all the Draw calls you want.
|
|
|
|
public unsafe void UploadBufferData(CommandBuffer commandBuffer)
|
|
|
|
{
|
|
|
|
Wellspring.Wellspring_GetBufferData(
|
|
|
|
Handle,
|
2022-06-30 20:25:52 +00:00
|
|
|
out uint vertexCount,
|
2022-04-13 03:06:14 +00:00
|
|
|
out IntPtr vertexDataPointer,
|
|
|
|
out uint vertexDataLengthInBytes,
|
|
|
|
out IntPtr indexDataPointer,
|
|
|
|
out uint indexDataLengthInBytes
|
|
|
|
);
|
|
|
|
|
2022-10-25 00:22:24 +00:00
|
|
|
if (vertexDataLengthInBytes > 0 && indexDataLengthInBytes > 0)
|
|
|
|
{
|
|
|
|
commandBuffer.SetBufferData(VertexBuffer, vertexDataPointer, 0, vertexDataLengthInBytes);
|
|
|
|
commandBuffer.SetBufferData(IndexBuffer, indexDataPointer, 0, indexDataLengthInBytes);
|
|
|
|
}
|
2022-06-30 20:25:52 +00:00
|
|
|
|
|
|
|
PrimitiveCount = vertexCount / 2; // FIXME: is this jank?
|
2022-04-13 03:06:14 +00:00
|
|
|
}
|
2023-12-07 01:33:17 +00:00
|
|
|
|
|
|
|
protected virtual void Dispose(bool disposing)
|
|
|
|
{
|
|
|
|
if (!IsDisposed)
|
|
|
|
{
|
|
|
|
if (disposing)
|
|
|
|
{
|
|
|
|
VertexBuffer.Dispose();
|
|
|
|
IndexBuffer.Dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
NativeMemory.Free(StringBytes);
|
2023-12-08 07:50:34 +00:00
|
|
|
Wellspring.Wellspring_DestroyTextBatch(Handle);
|
2023-12-07 01:33:17 +00:00
|
|
|
|
|
|
|
IsDisposed = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
~TextBatch()
|
|
|
|
{
|
|
|
|
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
|
|
|
Dispose(disposing: false);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
{
|
|
|
|
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
|
|
|
Dispose(disposing: true);
|
|
|
|
GC.SuppressFinalize(this);
|
|
|
|
}
|
2022-04-13 03:06:14 +00:00
|
|
|
}
|
|
|
|
}
|