From fba3114d4fff78d9c2b17fbd4ccbeda29f9318ab Mon Sep 17 00:00:00 2001 From: Luke Street Date: Mon, 13 Apr 2026 14:00:32 -0600 Subject: [PATCH] bloom2: Ensure draws/copies are pixel aligned --- src/m_Do/m_Do_graphic.cpp | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/m_Do/m_Do_graphic.cpp b/src/m_Do/m_Do_graphic.cpp index 144ebd5873..bb6746e977 100644 --- a/src/m_Do/m_Do_graphic.cpp +++ b/src/m_Do/m_Do_graphic.cpp @@ -1311,6 +1311,12 @@ void mDoGph_gInf_c::bloom_c::draw2() { BlurPass0, BlurPassN = BlurPass0 + MaxDivNum, MaxTexNum, }; + struct bloom_rect { + u16 x; + u16 y; + u16 w; + u16 h; + }; scissor_class divPorts[MaxDivNum]; divPorts[0] = {0.0f, 0.0f, 1.0f, 1.0f}; // full-size texture divPorts[1] = {0.0f, 0.0f, 0.5f, 0.5f}; // bloom texture (wide enough, half-tall) @@ -1324,22 +1330,35 @@ void mDoGph_gInf_c::bloom_c::draw2() { port.height = prev.height * 0.5f; } + bloom_rect divRects[MaxDivNum]; + for (int i = 0; i < ARRAY_SIZE(divPorts); i++) { + auto const& port = divPorts[i]; + divRects[i] = { + static_cast(port.x_orig * width), + static_cast(port.y_orig * height), + static_cast(port.width * width), + static_cast(port.height * height), + }; + } + auto divCopySrc = [&](int divNo) { - auto const& port = divPorts[divNo]; - GXSetTexCopySrc(port.x_orig * width, port.y_orig * height, port.width * width, port.height * height); + auto const& rect = divRects[divNo]; + GXSetTexCopySrc(rect.x, rect.y, rect.w, rect.h); }; TGXTexObj tmpTex[MaxTexNum]; auto divCopyTex = [&](uintptr_t texNo, int divNo) -> GXTexObj * { - auto const& port = divPorts[divNo]; - CopyToTexObj(&tmpTex[texNo], texNo, port.width * width, port.height * height); + auto const& rect = divRects[divNo]; + CopyToTexObj(&tmpTex[texNo], texNo, rect.w, rect.h); return &tmpTex[texNo]; }; auto divQuad = [&](int divNo) { - auto const& port = divPorts[divNo]; - f32 x0 = port.x_orig, y0 = port.y_orig; - f32 x1 = x0 + port.width, y1 = y0 + port.height; + auto const& rect = divRects[divNo]; + f32 x0 = rect.x / width; + f32 y0 = rect.y / height; + f32 x1 = (rect.x + rect.w) / width; + f32 y1 = (rect.y + rect.h) / height; GXBegin(GX_QUADS, GX_VTXFMT0, 4); GXPosition3f32(x0, y0, -5); GXTexCoord2s8(0, 0);