From adf4cccd4a3eec1c1b5ec5979d0eca85a53baca0 Mon Sep 17 00:00:00 2001 From: bicarus <202771338+bicarus-dev@users.noreply.github.com> Date: Sun, 16 Aug 2026 04:24:14 -0700 Subject: [PATCH] overlay: fix subscreen overlay rendering for popn (#869) ## Link to GitHub Issue or related Pull Request, if one exists n/a ## Description of change For popn HC, some transparency effects, like the one for touch feedback, rendered incorrectly; this is due to how alpha channel is handled for subscreen overlay drawing on top of ImGui. ## Testing Tested popn and iidx. --- src/spice2x/overlay/windows/generic_sub.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/spice2x/overlay/windows/generic_sub.cpp b/src/spice2x/overlay/windows/generic_sub.cpp index 1147d8f..7a94df1 100644 --- a/src/spice2x/overlay/windows/generic_sub.cpp +++ b/src/spice2x/overlay/windows/generic_sub.cpp @@ -25,6 +25,15 @@ namespace overlay::windows { const ImVec4 YELLOW(1.f, 1.f, 0.f, 1.f); const ImVec4 WHITE(1.f, 1.f, 1.f, 1.f); + // a subscreen is an already-composited backbuffer, so its alpha bits are not + // meaningful for display. Use AddImage's diffuse alpha (opaque by default) + // instead of the texture alpha while preserving ImGui's normal blend state. + static void ignore_texture_alpha(const ImDrawList *, const ImDrawCmd *command) { + auto device = static_cast(command->UserCallbackData); + device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); + } + GenericSubScreen::GenericSubScreen(SpiceOverlay *overlay) : Window(overlay), device(overlay->get_device()) { this->remove_window_padding = true; // ImGuiWindowFlags_NoBackground is needed as the background is drawn on top of the subscreen image @@ -239,10 +248,13 @@ namespace overlay::windows { auto draw_list = this->draws_window ? ImGui::GetWindowDrawList() : ImGui::GetBackgroundDrawList(); + draw_list->AddCallback(ignore_texture_alpha, this->device); draw_list->AddImage( reinterpret_cast(this->texture), overlay_content_top_left, bottom_right); + // following ImGui draws should resume normal texture-alpha modulation + draw_list->AddCallback(ImGui::GetPlatformIO().DrawCallback_ResetRenderState); if (this->draws_window) { // draw an invisible button so that it swallows mouse input