Add uUseTexture==2 (RGBA modulate) branch to ui_text.frag so dat sprites can be drawn through the existing 2D batcher without touching the font path. TextRenderer gains _spriteBufs (per-GL-handle List<float>), DrawSprite(), and a Flush block that issues one draw call per distinct texture with uUseTexture=2. Also adds DepthMask(false) in the state-save block (restored to true after) to prevent the transparent-quad pass from writing depth and corrupting the 3D scene if the UI is flushed mid-frame. TextureCache gains GetOrUpload(surfaceId, out width, out height) — caches pixel dimensions alongside the GL handle so UI 9-slice geometry can compute slice UVs from the source image size without a second decode. UiRenderContext gains a DrawSprite forwarder that applies the current 2D translate stack, matching the DrawRect / DrawRectOutline pattern. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
67 lines
2.4 KiB
C#
67 lines
2.4 KiB
C#
using System.Numerics;
|
|
using AcDream.App.Rendering;
|
|
|
|
namespace AcDream.App.UI;
|
|
|
|
/// <summary>
|
|
/// Per-frame drawing context passed through the <see cref="UiElement"/>
|
|
/// tree. Wraps a <see cref="TextRenderer"/> (our 2D sprite batcher) and a
|
|
/// transform stack so elements can draw in local coordinates.
|
|
///
|
|
/// Retail equivalent: the implicit context <c>FUN_005da8f0</c> walks with
|
|
/// when iterating the UI tree. Our version is explicit so it plugs
|
|
/// cleanly into Silk.NET.
|
|
/// </summary>
|
|
public sealed class UiRenderContext
|
|
{
|
|
public TextRenderer TextRenderer { get; }
|
|
public BitmapFont? DefaultFont { get; set; }
|
|
public Vector2 ScreenSize { get; }
|
|
|
|
// Transform stack — simple 2D translate (no rotation/scale for UI).
|
|
private readonly System.Collections.Generic.List<Vector2> _stack = new();
|
|
private Vector2 _current;
|
|
|
|
public UiRenderContext(TextRenderer tr, Vector2 screenSize, BitmapFont? defaultFont = null)
|
|
{
|
|
TextRenderer = tr;
|
|
ScreenSize = screenSize;
|
|
DefaultFont = defaultFont;
|
|
}
|
|
|
|
/// <summary>Push a relative translate. Must be paired with <see cref="PopTransform"/>.</summary>
|
|
public void PushTransform(float dx, float dy)
|
|
{
|
|
_stack.Add(_current);
|
|
_current += new Vector2(dx, dy);
|
|
}
|
|
|
|
public void PopTransform()
|
|
{
|
|
if (_stack.Count == 0) return;
|
|
_current = _stack[^1];
|
|
_stack.RemoveAt(_stack.Count - 1);
|
|
}
|
|
|
|
public Vector2 CurrentOrigin => _current;
|
|
|
|
// ── Pass-through draw helpers (add current translate) ──────────────
|
|
|
|
public void DrawRect(float x, float y, float w, float h, Vector4 color)
|
|
=> TextRenderer.DrawRect(_current.X + x, _current.Y + y, w, h, color);
|
|
|
|
public void DrawRectOutline(float x, float y, float w, float h, Vector4 color, float thickness = 1f)
|
|
=> TextRenderer.DrawRectOutline(_current.X + x, _current.Y + y, w, h, color, thickness);
|
|
|
|
public void DrawSprite(uint texture, float x, float y, float w, float h,
|
|
float u0, float v0, float u1, float v1, Vector4 tint)
|
|
=> TextRenderer.DrawSprite(texture,
|
|
_current.X + x, _current.Y + y, w, h, u0, v0, u1, v1, tint);
|
|
|
|
public void DrawString(string text, float x, float y, Vector4 color, BitmapFont? font = null)
|
|
{
|
|
var f = font ?? DefaultFont;
|
|
if (f is null) return;
|
|
TextRenderer.DrawString(f, text, _current.X + x, _current.Y + y, color);
|
|
}
|
|
}
|