IMGUI_DX11显示自定义图片

本文详细解析了在IMGUI中加载自定义图片的过程,包括使用Direct11创建纹理并将其转换为纹理ID的方法,以及如何在代码中实现这一过程的具体步骤。

IMGUI官方自带的例子里有一个Widgets项,里面有个Images

由于官方只演示了字体默认图片,并没有演示如何加载自定义图片


我们先搜索一下这个Images关键词

 通过代码搜索,观察发现,这个纹理ID是画图的关键

ImTextureID my_tex_id = io.Fonts->TexID;

 我们搜索看看io.Fonts->TexID是什么时候被赋值的(以下是Direct11的IMGUI)

 

 

 

观察得到流程为CreateTexture2D->CreateShaderResourceView->TexID

根据D3D11的相关知识,可以知道先创建一个2D纹理得到ID3D11Texture2D句柄,再通过CreateShaderResourceView得到ID3D11ShaderResourceView* g_pFontTextureView

即为纹理ID。

只要模拟这个过程就可以得到纹理ID:


ID3D11ShaderResourceView* DX11LoadTextureImageFromFile(ID3D11Device *pD3dDevice, wchar_t* lpszFilePath)
{

	ID3D11Texture2D * pTexture2D = NULL;
	D3D11_TEXTURE2D_DESC dec;


	HRESULT result;
	D3DX11_IMAGE_LOAD_INFO loadInfo;
	ZeroMemory(&loadInfo, sizeof(D3DX11_IMAGE_LOAD_INFO));
	loadInfo.BindFlags = D3D11_BIND_SHADER_RESOURCE;
	loadInfo.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	loadInfo.MipLevels = D3DX11_DEFAULT; //这时会产生最大的mipmaps层。 
	loadInfo.MipFilter = D3DX11_FILTER_LINEAR;
	result = D3DX11CreateTextureFromFile(pD3dDevice, lpszFilePath, &loadInfo, NULL, (ID3D11Resource**)(&pTexture2D), NULL);
	pTexture2D->GetDesc(&dec);

	if (result != S_OK)
	{
		return NULL;
	}

	ID3D11ShaderResourceView*pFontTextureView = NULL;

	// Create texture view
	D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
	ZeroMemory(&srvDesc, sizeof(srvDesc));
	srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
	srvDesc.Texture2D.MipLevels = dec.MipLevels;
	srvDesc.Texture2D.MostDetailedMip = 0;
	pD3dDevice->CreateShaderResourceView(pTexture2D, &srvDesc, &pFontTextureView);


	return pFontTextureView;
}

调用例子: 

	if (ImGui::Begin(u8"IMGUI", false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize))
	{
		if (!m_pImageTextureView1)
		{
			m_pImageTextureView1 = DX11LoadTextureImageFromFile(GetD3dDevice(), (wchar_t*)L"D:\\1.jpg");

		}
		ImTextureID my_tex_id = m_pImageTextureView1;
		float my_tex_w = (float)300;
		float my_tex_h = (float)400;
		ImGui::Image(my_tex_id, ImVec2(my_tex_w, my_tex_h), ImVec2(0, 0), ImVec2(1, 1), ImVec4(1.0f, 1.0f, 1.0f, 1.0f), ImVec4(1.0f, 1.0f, 1.0f, 0.5f));

	}

 

 

D3D9同理

你遇到的链接错误如下: ``` error LNK2019: 无法解析的外部符号 "void __cdecl ImGui::UpdatePlatformWindows(void)" error LNK2019: 无法解析的外部符号 "void __cdecl ImGui::RenderPlatformWindowsDefault(void *, void *)" error LNK2019: 无法解析的外部符号 "void __cdecl ImGui::DestroyPlatformWindows(void)" ``` 这些错误表明你正在使用 **ImGui 的多视口(Multi-Viewport)功能**,但没有正确编译或链接对应的源文件。 --- ## ✅ 解决方案一:添加 `imgui_platform.cpp` 到项目中(推荐) 这些函数 `UpdatePlatformWindows()`、`RenderPlatformWindowsDefault()` 和 `DestroyPlatformWindows()` 是在 `imgui_platform.cpp` 中实现的。 ### ✅ 操作步骤: 1. 找到你的 ImGui 源码目录(通常是 `imgui/backends/` 或 `imgui/src/`)。 2. 将 `imgui_platform.cpp` 添加到你的 Visual Studio 项目中: - 右键项目 → 添加 → 现有项 - 选择 `imgui_platform.cpp` 3. 重新编译项目。 --- ## ✅ 解决方案二:如果你**不需要多视口功能**,可以在初始化 ImGui 时禁用它 在你初始化 ImGui 上下文之后,添加如下代码: ```cpp ImGuiIO& io = ImGui::GetIO(); (void)io; io.ConfigFlags &= ~ImGuiConfigFlags_ViewportsEnable; ``` 这样就不会调用 `UpdatePlatformWindows()` 和 `RenderPlatformWindowsDefault()`,也就不会产生链接错误。 ### ✅ 示例代码: ```cpp // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; // 👇 关闭多视口支持 io.ConfigFlags &= ~ImGuiConfigFlags_ViewportsEnable; // 其他配置 io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Setup Dear ImGui style ImGui::StyleColorsDark(); // Setup Platform/Renderer backends ImGui_ImplWin32_Init(hwnd); ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext); ``` > ⚠️ 如果你关闭了 `ViewportsEnable`,那么下面这段代码也应该注释掉或删除: ```cpp if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) { ImGui::UpdatePlatformWindows(); ImGui::RenderPlatformWindowsDefault(); } ``` --- ## ✅ 解决方案三:检查你是否使用了最新版 ImGui 这些函数是在 **ImGui 1.89+** 版本中引入的。如果你使用的是旧版本,可能没有 `imgui_platform.cpp` 或者函数未定义。 👉 建议从 GitHub 获取最新版本: [https://github.com/ocornut/imgui](https://github.com/ocornut/imgui) --- ## ✅ 补充说明:ImGui 多视口功能的作用 - `ImGui::UpdatePlatformWindows()`:更新所有平台窗口(如拖出主窗口的 ImGui 窗口) - `ImGui::RenderPlatformWindowsDefault()`:渲染这些平台窗口的内容 - `ImGui::DestroyPlatformWindows()`:清理所有平台窗口资源 启用后,你可以将 ImGui 的窗口拖出主窗口成为一个独立的窗口。 --- ## 🧩 相关问题
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值