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

Weird behaviour when setting ImGuiStyle::Alpha before ImGui::Begin when docked #7535

Closed
rayment opened this issue Apr 28, 2024 · 2 comments
Closed

Comments

@rayment
Copy link

rayment commented Apr 28, 2024

Version/Branch of Dear ImGui:

Version 1.90.5, Branch: docking

Back-ends:

imgui_impl_sdl2.cpp + imgui_impl_opengl3.cpp

Compiler, OS:

MinGW 11.0 w64 (bundled with CLion)

Full config/build information:

Dear ImGui 1.90.5 (19050)
--------------------------------
sizeof(size_t): 8, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=201703
define: _WIN32
define: _WIN64
define: __MINGW32__
define: __MINGW64__
define: __GNUC__=13
define: IMGUI_HAS_VIEWPORT
define: IMGUI_HAS_DOCK
--------------------------------
io.BackendPlatformName: imgui_impl_sdl2
io.BackendRendererName: imgui_impl_opengl3
io.ConfigFlags: 0x00000041
 NavEnableKeyboard
 DockingEnable
io.ConfigViewportsNoDecoration
io.ConfigInputTextCursorBlink
io.ConfigWindowsResizeFromEdges
io.ConfigMemoryCompactTimer = 60.0
io.BackendFlags: 0x00001C0E
 HasMouseCursors
 HasSetMousePos
 PlatformHasViewports
 HasMouseHoveredViewport
 RendererHasVtxOffset
 RendererHasViewports
--------------------------------
io.Fonts: 1 fonts, Flags: 0x00000000, TexSize: 512,64
io.DisplaySize: 1280.00,720.00
io.DisplayFramebufferScale: 1.00,1.00
--------------------------------
style.WindowPadding: 8.00,8.00
style.WindowBorderSize: 1.00
style.FramePadding: 4.00,3.00
style.FrameRounding: 0.00
style.FrameBorderSize: 0.00
style.ItemSpacing: 8.00,4.00
style.ItemInnerSpacing: 4.00,4.00

Details:

My Issue/Question:

When the value of ImGui::GetStyle().Alpha is changed (fade in/fade out window transitions) before a call to ImGui::Begin(), I expect the next rendered window to be drawn at the specified alpha value. This works correctly as I expect:

clion64_ZKOCoque3h.mp4

However, in the scenario that there is a docked window A and a floating window B, when B is closed and a fade out occurs, the alpha of window A also changes. This only occurs while window A is docked. When undocked, it behaves as expected:

clion64_RE88PY0hDH.mp4

My render logic is as follows:

for every window:
    set ImGui::GetStyle().Alpha to the desired alpha of the window
    render window and calculate the alpha to use on next render

As per above, I am not making the mistake of setting the alpha value once per frame swap - it is set correctly per window.

It looks like the dock is not taking into account the requested alpha when ImGui::Begin() is called on the window and instead draws docked windows at whatever alpha was set directly before the call to ImGui::DockSpaceOverViewport (in the case above, when window B fades out, it's whatever alpha that was set to).

Probably more a question than a report at this stage... is this intended behaviour?

Omar, I'm also aware you posted a comment in a recent docking question:

As always the recurrent problem with docking questions is that people want to manipulate a dock node property which is shared by multiple windows, by definition there is a potential conflict, what is 2 windows which have opposite requests are docked together?

Indeed, my expectation would be problematic when more than once window is docked... Though my question still stands.

Screenshots/Video:

as above

Minimal, Complete and Verifiable Example code:

#define FADE_EPISOLON 0.01f
#define FADE_TIME 2.0f // 2 seconds

float
render_window(float alpha, const char *title, bool close)
{
	ImGui::GetStyle().Alpha = alpha;
	ImGui::Begin(title);

	if (!close)
	{
		// fade in the window
		if (std::abs(1.0f - alpha) > FADE_EPISOLON)
			alpha = std::clamp(alpha + (ImGui::GetIO().DeltaTime / FADE_TIME), 0.0f, 1.0f);
		else
			alpha = 1.0f;
	}
	else
	{
		// fade out the window
		if (alpha > FADE_EPISOLON)
			alpha -= ImGui::GetIO().DeltaTime / FADE_TIME;
		else
			alpha = -1.0f;
	}

	ImGui::End();
	return alpha;
}

void draw()
{
	// NOTE: If I uncomment the following line, a different problem arises: any docked window will
        //       no longer fade in.
	//ImGui::GetStyle().Alpha = 1.0f;
	ImGui::DockSpaceOverViewport(ImGui::GetMainViewport(), ImGuiDockNodeFlags_PassthruCentralNode);

	if (alpha_a >= 0.0f)
		alpha_a = render(alpha_a, "first", false);
	if (alpha_b >= 0.0f)
		alpha_b = render(alpha_b, "second", animate < 0.0f);
	animate -= ImGui::GetIO().DeltaTime; // dirty 4 second pause before we fade out window B
}

int main()
{
	// all of the initialisation code as per the SDL2/OpenGL3 example on GitHub
	while (!done)
	{
		// SDL_PollEvent and ImGui::NewFrame() stuff
		draw();
		// ImGui::Render() and SDL_GL_SwapWindow stuff
	}
	// all of the cleanup code as per the SDL2/OpenGL3 example on GitHub
	return 0;
}
@ocornut
Copy link
Owner

ocornut commented Apr 30, 2024

However, in the scenario that there is a docked window A and a floating window B, when B is closed and a fade out occurs, the alpha of window A also changes. This only occurs while window A is docked. When undocked, it behaves as expected:

You are overriding global Alpha and not restoring it. So it leaks into those other windows and is used by the docking system inside NewFrame().
Use PushStyleVar(ImGuiStyleVar_Alpha, alpha); .... PopStyleVar() instead.

This seems to work:

{
    ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0, 0, 0, 0));
    ImGui::DockSpaceOverViewport(ImGui::GetMainViewport(), ImGuiDockNodeFlags_PassthruCentralNode);
    ImGui::PopStyleColor();

    static float alpha = 0.7f;
    ImGui::SliderFloat("alpha", &alpha, 0.0f, 1.0f);
    ImGui::PushStyleVar(ImGuiStyleVar_Alpha, alpha);
    ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(1, 0, 0, 1));
    ImGui::Begin("Some window");
    ImGui::Text("Hello");
    ImGui::End();
    ImGui::PopStyleColor();
    ImGui::PopStyleVar();
}

Note that the TabItem itself doesn't use the specified alpha, it seems undesirable. The TabBar is owned by the dock node not a single window.

ocornut added a commit that referenced this issue Apr 30, 2024
…dows. Clarify why we don't need to store alpha. (#7535, #2771)

Amend ebbb98d
@rayment
Copy link
Author

rayment commented May 1, 2024

I see, this is much better, thank you.
Your note about the TabItem is reasonable and clears up part of my question, thanks.

Closing as no further questions.

@rayment rayment closed this as completed May 1, 2024
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

2 participants