Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to set docked window color transparent #5634

Open
tksuoran opened this issue Sep 2, 2022 · 12 comments
Open

Unable to set docked window color transparent #5634

tksuoran opened this issue Sep 2, 2022 · 12 comments

Comments

@tksuoran
Copy link

tksuoran commented Sep 2, 2022

Version/Branch of Dear ImGui:

Version: 1.89 WIP
Branch: docking

Back-end/Renderer/Compiler/OS

Back-ends: custom/erhe
Operating System: Windows 10

My Issue/Question:

It appears that ImGui::PushStyleColor(ImGuiCol_WindowBg) is ignored if window is docker.

Background:

  • I have set my desktop wallpaper to checkerboard
  • I have enabled window transparency (glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE);)
  • My goal is to have transparency in one ImGui window, specifically, a viewport window that shows 3D scene. Everything else should be opaque. To achieve this, I have opaque default ImGuiCol_WindowBg color for most windows, and I push transparent black (0, 0, 0, 0) for the viewport window
  • 🟢 The effect works correctly when scene viewport window is not docked
  • 🔴 The effect does not work when the scene viewport window is docked

Screenshots

🟢 Not docked, rendering as expected:
not_docked

🔴 Docked, pushed ImGuiCol_WindowBg appears to be ignored
docked

@ocornut
Copy link
Owner

ocornut commented Sep 2, 2022

Also see #2700 and #2766
Can you try using (255,255,255,0) and confirm if it is that Alpha is ignored in that situation?

It's confusing what part of your issue are related to Docking and which part are related to Viewports. Mentioning glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); suggest the later.
Do you have the same issue if you disable multi-viewports?

@tksuoran
Copy link
Author

tksuoran commented Sep 2, 2022

(255,255,255,0) - or should it be (1,1,1,0) - I tried both - all result exactly the same.
How should I disable multi-viewports? I am not using multi-viewports (as far as I know).

@ocornut
Copy link
Owner

ocornut commented Sep 2, 2022

By not enabling ImGuiConfigFlags_ViewportsEnable. You can clear it in Demo->Configuration.

@tksuoran tksuoran changed the title Pushing ImGuiCol_WindowBg before Begin() is ignored if window is docked Unable to set docked window color transparent Sep 2, 2022
@tksuoran
Copy link
Author

tksuoran commented Sep 2, 2022

I don't enable ImGuiConfigFlags_ViewportsEnable. The only bit I set in io.ConfigFlags is ImGuiConfigFlags_NavNoCaptureKeyboard.

This may already be covered by the issues you pointed to - thanks, I will check them in more detail. Meanwhile, I did make the following observation, comparing ImGui draw commands with RenderDoc:

  1. When the ImGui viewport is fully covered by docked ImGui Windows, the whole ImGui viewport is covered with a rectangle, filling it with opaque color (likely the style default WindowBg color), before any ImGui windows are rendered
  2. When the ImGui viewport is not fully covered by docked ImGui Windows, this covering of whole ImGui viewport does not happen, and individual windows are rendered directly to the framebuffer

In the case 1) this covering of the whole viewport appears to be the root cause why I cannot achieve the effect of having one window transparent if all windows are docked.

In other words: The operation of pushing transparent window background color to transparent black works fine. The issue is that by the time the window is rendered with opaque background color, ImGui viewport is already filled with opaque color.

@tksuoran
Copy link
Author

tksuoran commented Sep 2, 2022

I made a several edits to my previous comment, but I let it be now, promise.

One further info: I am using ImGui::DockSpaceOverViewport(nullptr, ImGuiDockNodeFlags_PassthruCentralNode);

Related: #3924

@tksuoran
Copy link
Author

tksuoran commented Sep 2, 2022

In ImGui::DockNodeUpdate() I commented out the code in section // Draw whole dockspace background if ImGuiDockNodeFlags_PassthruCentralNode if set. (typo there? 'is set' perhaps) and with that change I can achieve the effect I was looking for.

Why why would we need to draw the background there? That feels backwards how I understand 'passthru'.

@ocornut
Copy link
Owner

ocornut commented Sep 2, 2022

Why why would we need to draw the background there? That feels backwards how I understand 'passthru'.

Notice it is calling RenderRectFilledWithHole(). Central node is passthrough, other node still have their background.
EDIT Use Metrics/Debugger->Docking to make sure you have a Central Node. If you created dockspace programmatically without the _DockSpace flag you may not have a Central Node.

@tksuoran
Copy link
Author

tksuoran commented Sep 2, 2022

How is the central node related to the ImGui windows I have docked?

I have one or more of these scene viewport windows, and all of them should be rendered without any extra background. User may dock and undock them anywhere.

@ocornut
Copy link
Owner

ocornut commented Sep 2, 2022

(Sorry no time to look at this carefully now but will eventually!)

@CharFractal
Copy link

(Sorry no time to look at this carefully now but will eventually!)

Hello @ocornut , i want to work on this

@tvoeroes
Copy link

FYI I'm using this simple change to achieve transparent background: transparency.patch

@Ishisoft
Copy link

Ishisoft commented Sep 2, 2024

Inspired by the patch by @tvoeroes above, I'm using this similar change to allow just one of my windows to remain transparent while docked. If the window has the NoBackground flag it'll remain transparent while docked, while other windows keep their background. I'm not all that familiar with imgui code and the intricacies of rendering docked windows but it works for my purposes at least, and may be useful for someone. "&& (host_window->Flags & ImGuiWindowFlags_NoBackground) == 0" is the new bit.

// Draw whole dockspace background if ImGuiDockNodeFlags_PassthruCentralNode if set.
// We need to draw a background at the root level if requested by ImGuiDockNodeFlags_PassthruCentralNode, but we will only know the correct pos/size
// _after_ processing the resizing splitters. So we are using the DrawList channel splitting facility to submit drawing primitives out of order!
const bool render_dockspace_bg = node->IsRootNode() && host_window && (node_flags & ImGuiDockNodeFlags_PassthruCentralNode) != 0 && (host_window->Flags & ImGuiWindowFlags_NoBackground) == 0;
if (render_dockspace_bg && node->IsVisible)
{

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants