imgui显示图片

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

#include 
#include 

#include 
#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::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);
}

imgui显示图片_第1张图片

你可能感兴趣的:(imgui)