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

What are these bleaches on the window? (After upgrading to v1.90.3) #7342

Closed
abumettleq opened this issue Feb 22, 2024 · 13 comments
Closed

What are these bleaches on the window? (After upgrading to v1.90.3) #7342

abumettleq opened this issue Feb 22, 2024 · 13 comments

Comments

@abumettleq
Copy link

abumettleq commented Feb 22, 2024

Version/Branch of Dear ImGui:

Version 1.90.3, Branch: Release (master)

Back-ends:

imgui_impl_dx9.cpp + imgui_impl_win32.cpp

Compiler, OS:

Windows 11, ISO C++ 17 Standard, Platform Toolset VS2022 v143

Full config/build information:

No response

Details:

The windows I used to create were having no issues with background and borders, however, after upgrading the .h/.cpp files of ImGui to v1.90.3 and modify some of the windows code to meet the changes done in the current version, the window started to show some bleaches all around the window, for example, the picture attached below:

AsdaDailyBonus_1

I use my custom function to draw windows in a game I'm developing extension windows to it, as in the code snippets below:

bool ImGui::BeginAsda(const char* name, bool* p_open, ImTextureID user_texture_id, const ImVec2& texture_size, const ImVec4& uv, ImGuiWindowFlags flags)
{
	ImTextureID n_01 = TextureFactory::Instance()->MakeTexture("juidata\\Image\\Texture.btz", "n_01.tex");
	ImTextureID ne_wheeltaget1 = TextureFactory::Instance()->MakeTexture("juidata\\Image\\Texture.btz", "ne_wheeltaget1.tex");
	auto canItDrawAsda = n_01 != NULL && ne_wheeltaget1 != NULL;
	//auto doesCanDrawAsda = false;

	flags |= ImGuiWindowFlags_NoCollapse;
	flags |= ImGuiWindowFlags_NoSavedSettings;

	if (canItDrawAsda)
	{
		flags |= ImGuiWindowFlags_NoTitleBar;
		flags |= ImGuiWindowFlags_NoResize;
		flags |= ImGuiWindowFlags_NoScrollbar;
		flags |= ImGuiWindowFlags_AlwaysAutoResize;
		ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0);
		ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
		ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 20.0f);
		if (ImGui::GetIO().Fonts->Fonts.size() > 5)
			ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[5]);
	}

	ImGui::SetNextWindowPosCenter(ImGuiCond_Appearing);
	auto result = ImGui::Begin(name, p_open, flags);

	if (canItDrawAsda)
		PopClipRect();

	if (canItDrawAsda && result)
	{
		//                      
		auto pos = GetWindowPos(), size = GetWindowSize();

		if (user_texture_id != NULL)
		{
			//              
			AddImage(n_01, ImVec2(512, 512), pos, pos + ImVec2(48, 37), ImVec4(362, 471, 48, 37));
			AddImage(n_01, ImVec2(512, 512), pos + ImVec2(48, 0), pos + ImVec2(size.x - 86, 37), ImVec4(414, 471, 4, 37));
			AddImage(n_01, ImVec2(512, 512), pos + ImVec2(size.x - 86, 0), pos + ImVec2(size.x, 37), ImVec4(422, 471, 86, 37));

			//              
			AddImage(n_01, ImVec2(512, 512), pos + ImVec2(0, 37), pos + ImVec2(20, size.y - 20), ImVec4(456, 439, 20, 4));
			AddImage(n_01, ImVec2(512, 512), pos + ImVec2(20, 37), pos + ImVec2(size.x - 20, size.y - 20), ImVec4(488, 439, 4, 4));
			AddImage(n_01, ImVec2(512, 512), pos + ImVec2(size.x - 20, 37), pos + ImVec2(size.x, size.y - 20), ImVec4(488, 439, 20, 4));

			//              
			AddImage(n_01, ImVec2(512, 512), pos + ImVec2(0, size.y - 20), pos + ImVec2(20, size.y), ImVec4(456, 447, 20, 20));
			AddImage(n_01, ImVec2(512, 512), pos + ImVec2(20, size.y - 20), pos + ImVec2(size.x - 20, size.y), ImVec4(480, 447, 4, 20));
			AddImage(n_01, ImVec2(512, 512), pos + ImVec2(size.x - 20, size.y - 20), pos + ImVec2(size.x, size.y), ImVec4(488, 447, 20, 20));

			//                   
			AddImage(ne_wheeltaget1, ImVec2(256, 256), pos + ImVec2(0, 0), pos + ImVec2(185, 37), ImVec4(100, 218, 156, 37));

			//            
			GetWindowDrawList()->AddImageRounded(user_texture_id, pos + ImVec2(3, 3), pos + ImVec2(37, 37), ImVec2(uv.x, uv.y) / texture_size, ImVec2(uv.x + uv.z, uv.y + uv.w) / texture_size, 0xFFFFFFFF, (37 - 3) / 2);

			//               
			GetWindowDrawList()->AddText(pos + ImVec2(37 + 3, 37 / 2 - CalcTextSize(name).y / 2), 0xFFFFFFFF, name);
		}
		else
		{
			//              
			AddImage(n_01, ImVec2(512, 512), pos, pos + ImVec2(53, 24), ImVec4(373, 341, 53, 24));
			AddImage(n_01, ImVec2(512, 512), pos + ImVec2(53, 0), pos + ImVec2(size.x - 53, 24), ImVec4(430, 341, 5, 24));
			AddImage(n_01, ImVec2(512, 512), pos + ImVec2(size.x - 53, 0), pos + ImVec2(size.x, 24), ImVec4(439, 341, 53, 24));

			//              
			AddImage(n_01, ImVec2(512, 512), pos + ImVec2(0, 24), pos + ImVec2(20, size.y - 20), ImVec4(456, 439, 20, 4));
			AddImage(n_01, ImVec2(512, 512), pos + ImVec2(20, 24), pos + ImVec2(size.x - 20, size.y - 20), ImVec4(488, 439, 4, 4));
			AddImage(n_01, ImVec2(512, 512), pos + ImVec2(size.x - 20, 24), pos + ImVec2(size.x, size.y - 20), ImVec4(488, 439, 20, 4));

			//              
			AddImage(n_01, ImVec2(512, 512), pos + ImVec2(0, size.y - 20), pos + ImVec2(20, size.y), ImVec4(456, 447, 20, 20));
			AddImage(n_01, ImVec2(512, 512), pos + ImVec2(20, size.y - 20), pos + ImVec2(size.x - 20, size.y), ImVec4(480, 447, 4, 20));
			AddImage(n_01, ImVec2(512, 512), pos + ImVec2(size.x - 20, size.y - 20), pos + ImVec2(size.x, size.y), ImVec4(488, 447, 20, 20));

			//               
			auto titleSize = CalcTextSize(name);
			GetWindowDrawList()->AddText(pos + ImVec2(size.x - titleSize.x, 24 - titleSize.y) / 2, 0xFFFFFFFF, name);
		}

		//                
		if (p_open != NULL)
		{
			auto id = GetCurrentWindow()->GetID("#CLOSE");
			const ImRect bb(
				pos + ImVec2(size.x - 17 - 5, 5 + 0),
				pos + ImVec2(size.x - 0 - 5, 5 + 17));
			bool is_clipped = !ItemAdd(bb, id);
			bool hovered, held;
			bool pressed = ButtonBehavior(bb, id, &hovered, &held);

			if (!is_clipped)
			{
				if (held)
					AddImage(n_01, ImVec2(512, 512), pos + ImVec2(size.x - 17 - 5, 5), pos + ImVec2(size.x - 5, 5 + 17), ImVec4(125, 241, 17, 17));
				else if (hovered)
					AddImage(n_01, ImVec2(512, 512), pos + ImVec2(size.x - 17 - 5, 5), pos + ImVec2(size.x - 5, 5 + 17), ImVec4(103, 241, 17, 17));
				else
					AddImage(n_01, ImVec2(512, 512), pos + ImVec2(size.x - 17 - 5, 5), pos + ImVec2(size.x - 5, 5 + 17), ImVec4(81, 241, 17, 17));
			}

			if (pressed)
				*p_open = false;
		}
	}

	if (canItDrawAsda)
	{
		ImGui::PopStyleVar(3);
		if (ImGui::GetIO().Fonts->Fonts.size() > 3)
			ImGui::PushFont(ImGui::GetIO().Fonts->Fonts[3]);
		ImGui::SetCursorPosY(ImGui::GetCursorPosY() - 5 + 37);
	}

	return result;
}
void ImGui::SetNextWindowPosCenter(ImGuiCond_ cond)
{
	SetNextWindowPos(ImVec2(GetIO().DisplaySize.x * 0.5f, GetIO().DisplaySize.y * 0.5f), ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
	ImGui::SetNextWindowBgAlpha(1.0f);
}

Screenshots/Video:

No response

Minimal, Complete and Verifiable Example code:

No response

@abumettleq abumettleq changed the title What are these bleaches on the window? (After upgrading the version to v1.90,3) What are these bleaches on the window? (After upgrading to v1.90.3) Feb 22, 2024
@GamingMinds-DanielC
Copy link
Contributor

Hard to say without more information. Could be an obscure bug in the library or render backend that manifests itself with your custom rendering, could be a mistake in your custom rendering that didn't make a difference until some bug was fixed in the library.

What version did you use before and how did it look then? Can you pinpoint the revision that broke your custom rendering? Should be doable in a small amount of attempts if you use a binary search pattern while switching revisions. F.e., if the current revision -1000 still worked, try -500. If that still works, you limited the break to the range of -500 to 0, try -250 next. If -500 already didn't work, the break is in -1000 to -500, try -750 next. After 10 steps like this, you are down to the exact revision.

Also always a good way to analyze rendering problems: make a frame capture with RenderDoc and look if anything is incorrectly set up.

@abumettleq
Copy link
Author

abumettleq commented Feb 22, 2024

@GamingMinds-DanielC
Answering your questions:

  1. I moved from "dear imgui, v1.63 WIP" to "1.90.3"
  2. It looked like this ...
    image
  • to note that previously I didn't have to round the window, now I need to round it by '20.0f' to look like the one provided in the image.
  1. I don't have this project uploaded to Github to restore/revise the changes, however, I have created two folders of this project, one from before the upgrade, and one after.

Also I had to change some code lines to adapt the deleted functions, e.g. :

\\ From
if (window->DC.ItemFlags & ImGuiItemFlags_ButtonRepeat)
	flags |= ImGuiButtonFlags_Repeat;
bool hovered, held;
bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags);
if (pressed)
	MarkItemValueChanged(id);

\\ To
if (window->Flags & ImGuiItemFlags_ButtonRepeat)
	flags |= ImGuiButtonFlags_Repeat;
bool hovered, held;
bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags);
if (pressed)
	MarkItemEdited(id);

To note that I'm not experinced at ImGui, I'm still learning and I appreciate the community help, thanks.

@GamingMinds-DanielC
Copy link
Contributor

GamingMinds-DanielC commented Feb 22, 2024

Version 1.63 is quite ancient (from 2018), so it's most likely not a single commit that is to blame. My best guess is that the blending setup in the renderer backend changed since then. The best way to check that is still RenderDoc, by capturing frames in both versions and comparing render states. There you can also check if your textures are OK.

Your AddImage() looks like a candidate to do something strange. How is that function implemented? Also, have you tried commenting out different AddImage() calls to see which ones are responsible? What does your n_01texture contain?

@abumettleq
Copy link
Author

The AddImage() function is implemented to draw an image from a texture sheet.

void ImGui::AddImage(ImTextureID user_texture_id, const ImVec2& texture_size, const ImVec2& a, const ImVec2& b, const ImVec4& uv, ImU32 col)
{
	auto u0 = uv.x / texture_size.x;
	auto v0 = uv.y / texture_size.y;
	auto u1 = u0 + uv.z / texture_size.x;
	auto v1 = v0 + uv.w / texture_size.y;
	ImGui::GetWindowDrawList()->AddImage(user_texture_id, a, b, ImVec2(u0, v0), ImVec2(u1, v1), col);
}

The n_01 texture is nothing but a texture sheet.
image

I will try RenderDoc out and inform you if I find something wrong.

@GamingMinds-DanielC
Copy link
Contributor

Ah, I figured out what's wrong. The old backend version likely used point sampling while the current one uses a bilinear magnification filter. Your texture doesn't extend its contained images into a small border, that's why stretched images bleed into the background color while filtering. This one f.e.:

AddImage(n_01, ImVec2(512, 512), pos + ImVec2(48, 0), pos + ImVec2(size.x - 86, 37), ImVec4(414, 471, 4, 37));

If you want to stretch a 4 texel wide image across a lot more pixels, you need to add a border in your atlas, so that at least 1 pixel to the left and right are identical. Otherwise, the leftmost pixel is halfway between the leftmost texel of your specified coordinates and the texel to the left of it. Same goes for the right side, also for the top and bottom for vertically stretched textures. In your case 1 texel border should be enough, more are needed if you have mip maps for minification filters.

A proper pre-processing of your texture would mark all pixels as part of a tile or part of the background gaps first. Then, set every texel to the average of all tile texels of the 8 texels around it if there are any. Mark those texels as tiles, repeat the process as many times as your borders need to be thick, or until no texels marked as background remain.

An alternative would be to switch the texture sampler in the backend back to point sampling.

@ocornut
Copy link
Owner

ocornut commented Feb 22, 2024

On this specific suggestion by Daniel, also refer to #7230

@abumettleq
Copy link
Author

abumettleq commented Feb 22, 2024

Interesting ...

image

What could be wrong now? as you see, the window is very dim, also the close button (still clickable).

PS: changes I've done

void ImGui::AddImage(ImTextureID user_texture_id, const ImVec2& texture_size, const ImVec2& a, const ImVec2& b, const ImVec4& uv, ImU32 col)
{
	ImVec4 imVec4Clamp(uv.x / 256.0f, uv.y / 256.0f, uv.z / 256.0f, uv.w / 256.0f);

    auto u0 = ImClamp(imVec4Clamp.x / texture_size.x, 0.0f, 1.0f);
    auto v0 = ImClamp(imVec4Clamp.y / texture_size.y, 0.0f, 1.0f);
    auto u1 = ImClamp((imVec4Clamp.x + imVec4Clamp.z) / texture_size.x, 0.0f, 1.0f);
    auto v1 = ImClamp((imVec4Clamp.y + imVec4Clamp.w) / texture_size.y, 0.0f, 1.0f);
    ImGui::GetWindowDrawList()->AddImage(user_texture_id, a, b, ImVec2(u0, v0), ImVec2(u1, v1), col);
}

@GamingMinds-DanielC
Copy link
Contributor

You divided all coordinates by 256, then still by the texture size which is 512x512. So basically you are only sampling from the top-left 2x2 texels of your texture, which are just the background color between tiles. Everything being black is to be expected in this case.

But why did you add additional clamping in the first place? Clamping is not the problem here, your texture coordinates were correct before. Your problem is either the missing border around tiles in your texture or the sampler setup in the render backend, neither is addressed by this change. Even if clamping was the problem it would be in the wrong place (the correct one would be the sampler setup again).

@abumettleq
Copy link
Author

Before I proceed to change the sampler setup, I wanna make sure if the function alright?

void ImGui::AddImage(ImTextureID user_texture_id, const ImVec2& texture_size, const ImVec2& a, const ImVec2& b, const ImVec4& uv, ImU32 col)
{
    auto u0 = ImClamp(uv.x / texture_size.x, 0.0f, 1.0f);
    auto v0 = ImClamp(uv.y / texture_size.y, 0.0f, 1.0f);
    auto u1 = ImClamp((uv.x + uv.z) / texture_size.x, 0.0f, 1.0f);
    auto v1 = ImClamp((uv.y + uv.w) / texture_size.y, 0.0f, 1.0f);
    ImGui::GetWindowDrawList()->AddImage(user_texture_id, a, b, ImVec2(u0, v0), ImVec2(u1, v1), col);
}

and the way to call it is like this?

AddImage(n_01, ImVec2(512, 512), pos + ImVec2(size.x - 20, size.y - 20), pos + ImVec2(size.x, size.y), ImVec4(488, 447, 20, 20));

@GamingMinds-DanielC
Copy link
Contributor

Before I proceed to change the sampler setup, I wanna make sure if the function alright?

Yes, that looks correct.

@abumettleq
Copy link
Author

Now what I did here, is I only reverted the 'imgui_impl_dx9.cpp' to the previous one.
And everything now working correctly.

image

Thank you for the help. 😃

@ocornut
Copy link
Owner

ocornut commented Feb 22, 2024

Please use latest version and alter sampling state using AddCallback(), similarly to what is suggested there:
#7230 (comment)

Or adjust your texture to leave 1 pixel empty space between items.

@ocornut ocornut closed this as completed Feb 22, 2024
@abumettleq
Copy link
Author

Done, thanks.

// altered
bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
// default
//bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
//bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);

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

3 participants