imgui显示图片

搞了半天终于会用imgui显示图片了,记录一下

#include <windows.h>
#include <assert.h>

#include <d3d9.h>
#pragma comment(lib,"d3d9")

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"

#include "imgui/imgui.h"
#include "imgui/imgui_impl_dx9.h"
#include "imgui/imgui_impl_win32.h"

//全局变量
const char* g_name = "image_mark";
HWND g_hwnd;
IDirect3D9* g_idrect3d9;
LPDIRECT3DDEVICE9 g_direct3ddevice9;
D3DPRESENT_PARAMETERS g_present;
LPDIRECT3DTEXTURE9 g_texture;


//前向声明
void initialize_wnd() noexcept;
void initialize_d3d9() noexcept;
void initialize_imgui() noexcept;
void message_handle() noexcept;
void render_handle() noexcept;
void reset_device() noexcept;
void clear_setting() noexcept;
void load_image() noexcept;
LRESULT _stdcall window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);

int main(int argc, char* argv[])
{
	initialize_wnd();
	initialize_d3d9();
	initialize_imgui();
	message_handle();
	clear_setting();
	return 0;
}

//初始化窗口
void initialize_wnd() noexcept
{
	WNDCLASSEXA wc =
	{
		sizeof(WNDCLASSEX),CS_CLASSDC,window_proc,0L,0L,GetModuleHandle(NULL),
		NULL,NULL,NULL,NULL,g_name,NULL
	};
	assert(RegisterClassExA(&wc));

	g_hwnd = CreateWindow(g_name, g_name, WS_OVERLAPPEDWINDOW,
		100, 100, 800, 500, NULL, NULL, wc.hInstance, NULL);
	assert(g_hwnd);

	ShowWindow(g_hwnd, SW_SHOW);
	UpdateWindow(g_hwnd);
}

//初始化d3d9设备
void initialize_d3d9() noexcept
{
	g_idrect3d9 = Direct3DCreate9(D3D_SDK_VERSION);
	assert(g_idrect3d9);

	ZeroMemory(&g_present, sizeof(g_present));
	g_present.Windowed = TRUE;
	g_present.SwapEffect = D3DSWAPEFFECT_DISCARD;
	g_present.BackBufferFormat = D3DFMT_UNKNOWN;
	g_present.EnableAutoDepthStencil = TRUE;
	g_present.AutoDepthStencilFormat = D3DFMT_D16;
	g_present.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
	HRESULT state = g_idrect3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &g_present, &g_direct3ddevice9);
	assert(state == S_OK);
}

//初始化界面库
void initialize_imgui() noexcept
{
	IMGUI_CHECKVERSION();
	ImGui::CreateContext();
	ImGuiIO& io = ImGui::GetIO(); (void)io;
	io.IniFilename = nullptr;
	io.LogFilename = nullptr;
	ImGui::StyleColorsDark();
	ImGui_ImplWin32_Init(g_hwnd);
	ImGui_ImplDX9_Init(g_direct3ddevice9);
	io.Fonts->AddFontFromFileTTF("msyh.ttc", 20.0f, NULL, io.Fonts->GetGlyphRangesChineseFull());
}

//消息处理
void message_handle() noexcept
{
	MSG msg{ 0 };
	while (msg.message != WM_QUIT)
	{
		if (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessageA(&msg);
		}
		else render_handle();
	}
}

//渲染处理
void render_handle() noexcept
{
	load_image();

	ImGui_ImplDX9_NewFrame();
	ImGui_ImplWin32_NewFrame();
	ImGui::NewFrame();

	ImGui::Begin(u8"控制窗口");
	ImGui::Button(u8"点击我");
    // ImGui::GetBackgroundDrawList()->AddImage()	// 这个函数是添加图片到背景的
	// ImGui::Image(g_texture, ImVec2(576, 324), ImVec2(0, 0), ImVec2(1, 1), ImVec4(1.0f, 1.0f, 1.0f, 1.0f), ImVec4(1.0f, 1.0f, 1.0f, 0.5f));
	ImGui::Image(g_texture, ImGui::GetContentRegionAvail());
	ImGui::End();

	ImGui::EndFrame();
	g_direct3ddevice9->SetRenderState(D3DRS_ZENABLE, false);
	g_direct3ddevice9->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
	g_direct3ddevice9->SetRenderState(D3DRS_SCISSORTESTENABLE, false);
	g_direct3ddevice9->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(200, 200, 200, 200), 1.0f, 0);
	if (g_direct3ddevice9->BeginScene() >= 0)
	{
		ImGui::Render();
		ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
		g_direct3ddevice9->EndScene();
	}
	if (g_direct3ddevice9->Present(NULL, NULL, NULL, NULL) == D3DERR_DEVICELOST
		&& g_direct3ddevice9->TestCooperativeLevel() == D3DERR_DEVICENOTRESET)
		reset_device();

	g_texture->Release();
}

//处理设备丢失
void reset_device() noexcept
{
	if (g_direct3ddevice9)
	{
		ImGui_ImplDX9_InvalidateDeviceObjects();
		g_direct3ddevice9->Reset(&g_present);
		ImGui_ImplDX9_CreateDeviceObjects();
	}
}

//清理所有设置
void clear_setting() noexcept
{
	ImGui_ImplDX9_Shutdown();
	ImGui_ImplWin32_Shutdown();
	ImGui::DestroyContext();

	if (g_idrect3d9) g_idrect3d9->Release();
	if (g_direct3ddevice9) g_direct3ddevice9->Release();

	DestroyWindow(g_hwnd);
	::UnregisterClass(g_name, GetModuleHandle(NULL));
}

void load_image() noexcept
{
	int width, height, channel;
	unsigned char* data = stbi_load("h:\\test.jpg", &width, &height, &channel, 3);

	g_direct3ddevice9->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &g_texture, NULL);
	D3DLOCKED_RECT lock_rect;
	unsigned char* buffer = new unsigned char[width * height * (channel + 1)];
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			buffer[(i*width + j) * 4 + 0] = data[(i * width + j) * 3 + 2];
			buffer[(i*width + j) * 4 + 1] = data[(i * width + j) * 3 + 1];
			buffer[(i*width + j) * 4 + 2] = data[(i * width + j) * 3 + 0];
			buffer[(i*width + j) * 4 + 3] = 0xff;
		}
	}
	g_texture->LockRect(0, &lock_rect, NULL, 0);
	for (int y = 0; y < height; y++)
		memcpy((unsigned char *)lock_rect.pBits + lock_rect.Pitch * y, buffer + (width * (channel + 1)) * y, (width * (channel + 1)));
	g_texture->UnlockRect(0);
	delete[] buffer;
}

//窗口过程
extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT _stdcall window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
	if (ImGui_ImplWin32_WndProcHandler(hwnd, msg, wparam, lparam)) return true;

	static PAINTSTRUCT ps;
	static HDC hdc;
	switch (msg)
	{
	case  WM_SIZE:	
	{
		g_present.BackBufferWidth = LOWORD(lparam);
		g_present.BackBufferHeight = HIWORD(lparam);
		reset_device();
		break;
	}
	case WM_DESTROY: PostQuitMessage(0); break;
	}

	return DefWindowProcA(hwnd, msg, wparam, lparam);
}

  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在 imgui 中实时显示 CUDA 渲染的图片,需要将 CUDA 渲染的结果存储到内存中,然后将其绑定到 imgui 的纹理中进行显示。以下是一个简单的示例代码: ```c++ // CUDA 渲染函数 void cudaRender(float* result, int width, int height) { // 在 CUDA 中进行渲染,并将结果存储到 result 数组中 // result 数组的大小应为 width * height * 4(RGBA 四个通道) } // imgui 显示函数 void showImage(float* imageData, int width, int height) { // 将 imageData 绑定到 imgui 的纹理中 ImTextureID textureID = (ImTextureID)imageData; ImGui::Image(textureID, ImVec2(width, height)); } // 主函数 int main() { // 创建 imgui 窗口 ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); ImGui_ImplGlfw_InitForOpenGL(window, true); ImGui_ImplOpenGL3_Init("#version 330 core"); // 创建用于存储 CUDA 渲染结果的数组 float* cudaResult = new float[width * height * 4]; // 进入主循环 while (!glfwWindowShouldClose(window)) { // 在 CUDA 中进行渲染 cudaRender(cudaResult, width, height); // 显示渲染结果 showImage(cudaResult, width, height); // 渲染 imgui 窗口 ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); // 交换缓冲区 glfwSwapBuffers(window); glfwPollEvents(); } // 清理 imgui 相关资源 ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); // 清理 CUDA 渲染结果数组 delete[] cudaResult; return 0; } ``` 需要注意的是,由于 imgui 的纹理只支持 RGBA 四个通道的图片,因此在 CUDA 中进行渲染时需要将结果存储为 RGBA 格式。另外,由于 imgui 的纹理 ID 类型为 void*,因此在将 CUDA 渲染结果绑定到 imgui 纹理时需要将其转换为 void* 类型。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值