wgpu: overlay labels + HUD text (QPainter rasterise, content-cached)

Ports GL OverlayRenderer's setOverlayLabels + setHudText to wgpu.
Each unique string is rasterised via QPainter into a QImage (dark-grey
rounded background + white antialiased text) and uploaded as an RGBA8
texture; the cache is keyed by content + font size so identical
strings across frames are texture-free. Per-frame work is projection,
vertex assembly, and one draw per visible label.

Drawn last in the frame on the resolved surface so labels sit on top
of every other overlay (no depth-test). HUD uses pt 11 at top-left
matching GL; world-anchored labels use pt 9 centred at the projected
screen position.

WebGPU has no QOpenGLPaintDevice equivalent — the GL backend's two-
stage GL-rect + QPainter pass becomes one textured quad per item here.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Dion Moult
2026-05-31 08:40:54 +10:00
parent 716dba2244
commit 3ac7a79b7a
4 changed files with 475 additions and 0 deletions
+15
View File
@@ -2849,6 +2849,17 @@ void WgpuViewportWindow::setOverlayPoints(const std::vector<float>& world_xyz,
if (isExposed()) requestUpdate();
}
void WgpuViewportWindow::setOverlayLabels(
const std::vector<WgpuOverlayRenderer::Label>& labels) {
overlays_.setOverlayLabels(labels);
if (isExposed()) requestUpdate();
}
void WgpuViewportWindow::setHudText(const QString& text) {
overlays_.setHudText(text);
if (isExposed()) requestUpdate();
}
// Project a world point to LOGICAL pixel coords (Qt's mouse-event units).
// Returns false if behind the camera.
static bool projectWorldToLogicalScreen(const QMatrix4x4& vp,
@@ -3993,6 +4004,10 @@ void WgpuViewportWindow::render() {
box_select_current_pos_,
box_select_active_);
// Labels + HUD text. Drawn last so they stack on top of every other
// overlay (no depth test, alpha-blended on the resolved surface).
overlays_.encodeLabels(enc, view, overlay_frame);
// ---- HiZ: resolve MSAA depth → small single-sample → ping-pong slot
int hiz_submitted_slot = -1;
if (hiz_enabled_) {