perf(noise): tile the resident noise texture on GL instead of a copy

Drawing the tiled background noise built a viewport-sized pre-tiled
texture and re-created it whenever the viewport changed, copying the
256x256 noise tile across the whole screen in memory.

- On GL the draw now samples the resident 256x256 tile directly with
  GL_REPEAT, computing UVs from the screen rect over the tile size with
  the phase anchored at the viewport origin. The result is pixel-
  identical to the old pre-tiled texture (same generator, same origin)
  with no per-viewport copy.
- DX11 keeps the pre-tiled viewport-sized texture, since its sampler is
  CLAMP and cannot repeat.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-10-13 22:03:00 -05:00
co-authored by Claude Opus 4.8
parent aa486266c6
commit 3554ba1e2d
+14 -1
View File
@@ -145,6 +145,8 @@ void DrawTiledNoiseRect(ImDrawList* dl, const ImVec2& pMin, const ImVec2& pMax,
if (!dl || (tintColor & IM_COL32_A_MASK) == 0) return;
ImGuiViewport* vp = ImGui::GetMainViewport();
#ifdef DRAGONX_USE_DX11
// DX11 sampler is CLAMP: keep the viewport-sized pre-tiled texture so UVs stay in [0,1].
int vpW = (int)vp->Size.x;
int vpH = (int)vp->Size.y;
if (vpW <= 0 || vpH <= 0) return;
@@ -153,13 +155,24 @@ void DrawTiledNoiseRect(ImDrawList* dl, const ImVec2& pMin, const ImVec2& pMax,
ImTextureID tex = GetTiledNoiseTexture(vpW, vpH, &texW, &texH);
if (!tex || texW <= 0 || texH <= 0) return;
// Compute UVs: map screen-space rect to texture coordinates.
// The tiled texture covers the entire viewport, so UV = screenPos / vpSize.
// Subtract viewport origin for multi-viewport support.
float u0 = (pMin.x - vp->Pos.x) / (float)texW;
float v0 = (pMin.y - vp->Pos.y) / (float)texH;
float u1 = (pMax.x - vp->Pos.x) / (float)texW;
float v1 = (pMax.y - vp->Pos.y) / (float)texH;
#else
// GL: sample the resident 256x256 GL_REPEAT tile; UV phase anchored at the viewport
// origin, identical to the old pre-tiled texture (same LCG, same origin).
int sz = 0;
ImTextureID tex = GetNoiseTexture(&sz);
if (!tex || sz <= 0) return;
float u0 = (pMin.x - vp->Pos.x) / (float)sz;
float v0 = (pMin.y - vp->Pos.y) / (float)sz;
float u1 = (pMax.x - vp->Pos.x) / (float)sz;
float v1 = (pMax.y - vp->Pos.y) / (float)sz;
#endif
dl->AddImage(tex, pMin, pMax, ImVec2(u0, v0), ImVec2(u1, v1), tintColor);
}