搞了半天终于会用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);
}