From 866fa95aaad79b1912fa8ed5f94e10d7921cdee3 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 9 Mar 2015 14:13:29 +0000 Subject: [PATCH] Examples: DirectX9 example application handle window resizing. --- .../directx11_example/imgui_impl_dx11.cpp | 16 ++--- examples/directx9_example/imgui_impl_dx9.cpp | 38 ++++++++---- examples/directx9_example/imgui_impl_dx9.h | 4 ++ examples/directx9_example/main.cpp | 59 +++++++++++-------- 4 files changed, 76 insertions(+), 41 deletions(-) diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index bc693a473..c2e90ae50 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -15,6 +15,7 @@ static INT64 g_Time = 0; static INT64 g_TicksPerSecond = 0; static bool g_FontTextureLoaded = false; +static HWND g_hWnd = 0; static ID3D11Device* g_pd3dDevice = NULL; static ID3D11DeviceContext* g_pd3dDeviceContext = NULL; static ID3D11Buffer* g_pVB = NULL; @@ -355,6 +356,7 @@ static bool InitDirect3DState() bool ImGui_ImplDX11_Init(void* hwnd, ID3D11Device* device, ID3D11DeviceContext* device_context) { + g_hWnd = (HWND)hwnd; g_pd3dDevice = device; g_pd3dDeviceContext = device_context; @@ -369,14 +371,7 @@ bool ImGui_ImplDX11_Init(void* hwnd, ID3D11Device* device, ID3D11DeviceContex if (!QueryPerformanceCounter((LARGE_INTEGER *)&g_Time)) return false; - // FIXME: resizing - RECT rect; - GetClientRect((HWND)hwnd, &rect); - int display_w = (int)(rect.right - rect.left); - int display_h = (int)(rect.bottom - rect.top); - ImGuiIO& io = ImGui::GetIO(); - io.DisplaySize = ImVec2((float)display_w, (float)display_h); // Display size, in pixels. For clamping windows positions. io.KeyMap[ImGuiKey_Tab] = VK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime. io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT; io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT; @@ -396,7 +391,7 @@ bool ImGui_ImplDX11_Init(void* hwnd, ID3D11Device* device, ID3D11DeviceContex io.KeyMap[ImGuiKey_Z] = 'Z'; io.RenderDrawListsFn = ImGui_ImplDX11_RenderDrawLists; - io.ImeWindowHandle = hwnd; + io.ImeWindowHandle = g_hWnd; return true; } @@ -428,6 +423,11 @@ void ImGui_ImplDX11_NewFrame() ImGuiIO& io = ImGui::GetIO(); + // Setup display size (every frame to accommodate for window resizing) + RECT rect; + GetClientRect(g_hWnd, &rect); + io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top)); + // Setup time step INT64 current_time; QueryPerformanceCounter((LARGE_INTEGER *)¤t_time); diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index ccddbe05e..c69a8d2e0 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -10,6 +10,7 @@ #include // Data +static HWND g_hWnd = 0; static INT64 g_Time = 0; static INT64 g_TicksPerSecond = 0; static bool g_FontTextureLoaded = false; @@ -177,20 +178,15 @@ void ImGui_ImplDX9_InitFontsTexture() bool ImGui_ImplDX9_Init(void* hwnd, IDirect3DDevice9* device) { + g_hWnd = (HWND)hwnd; g_pd3dDevice = device; + if (!QueryPerformanceFrequency((LARGE_INTEGER *)&g_TicksPerSecond)) return false; if (!QueryPerformanceCounter((LARGE_INTEGER *)&g_Time)) return false; - // FIXME: resizing - RECT rect; - GetClientRect((HWND)hwnd, &rect); - int display_w = (int)(rect.right - rect.left); - int display_h = (int)(rect.bottom - rect.top); - ImGuiIO& io = ImGui::GetIO(); - io.DisplaySize = ImVec2((float)display_w, (float)display_h); // Display size, in pixels. For clamping windows positions. io.KeyMap[ImGuiKey_Tab] = VK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime. io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT; io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT; @@ -210,17 +206,18 @@ bool ImGui_ImplDX9_Init(void* hwnd, IDirect3DDevice9* device) io.KeyMap[ImGuiKey_Z] = 'Z'; io.RenderDrawListsFn = ImGui_ImplDX9_RenderDrawLists; - io.ImeWindowHandle = hwnd; + io.ImeWindowHandle = g_hWnd; - // Create the vertex buffer if (g_pd3dDevice->CreateVertexBuffer(10000 * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL) < 0) return false; return true; } -void ImGui_ImplDX9_Shutdown() +void ImGui_ImplDX9_InvalidateDeviceObjects() { + if (!g_pd3dDevice) + return; if (g_pVB) { g_pVB->Release(); @@ -231,8 +228,24 @@ void ImGui_ImplDX9_Shutdown() tex->Release(); ImGui::GetIO().Fonts->TexID = 0; } +} +void ImGui_ImplDX9_CreateDeviceObjects() +{ + if (!g_pd3dDevice) + return; + if (g_pd3dDevice->CreateVertexBuffer(10000 * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL) < 0) + return; + + ImGui_ImplDX9_InitFontsTexture(); +} + +void ImGui_ImplDX9_Shutdown() +{ + ImGui_ImplDX9_InvalidateDeviceObjects(); ImGui::Shutdown(); + g_pd3dDevice = NULL; + g_hWnd = 0; } void ImGui_ImplDX9_NewFrame() @@ -242,6 +255,11 @@ void ImGui_ImplDX9_NewFrame() ImGuiIO& io = ImGui::GetIO(); + // Setup display size (every frame to accommodate for window resizing) + RECT rect; + GetClientRect(g_hWnd, &rect); + io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top)); + // Setup time step INT64 current_time; QueryPerformanceCounter((LARGE_INTEGER *)¤t_time); diff --git a/examples/directx9_example/imgui_impl_dx9.h b/examples/directx9_example/imgui_impl_dx9.h index 6574e3f73..1822bee88 100644 --- a/examples/directx9_example/imgui_impl_dx9.h +++ b/examples/directx9_example/imgui_impl_dx9.h @@ -8,6 +8,10 @@ void ImGui_ImplDX9_InitFontsTexture(); void ImGui_ImplDX9_Shutdown(); void ImGui_ImplDX9_NewFrame(); +// Use if you want to reset your rendering device without losing ImGui state. +void ImGui_ImplDX9_InvalidateDeviceObjects(); +void ImGui_ImplDX9_CreateDeviceObjects(); + // Handler for Win32 messages, update mouse/keyboard data. // You may or not need this for your implementation, but it can serve as reference for handling inputs. // Commented out to avoid dragging dependencies on types. You can copy the extern declaration in your code. diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index 9224be508..2f2a6188b 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -1,5 +1,4 @@ // ImGui - standalone example application for DirectX 9 -// TODO: Allow resizing the application window. #include #include "imgui_impl_dx9.h" @@ -7,6 +6,10 @@ #define DIRECTINPUT_VERSION 0x0800 #include +// Data +static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; +static D3DPRESENT_PARAMETERS g_d3dpp; + extern LRESULT ImGui_ImplDX9_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { @@ -15,6 +18,18 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) switch (msg) { + case WM_SIZE: + if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED) + { + ImGui_ImplDX9_InvalidateDeviceObjects(); + g_d3dpp.BackBufferWidth = LOWORD(lParam); + g_d3dpp.BackBufferHeight = HIWORD(lParam); + HRESULT hr = g_pd3dDevice->Reset(&g_d3dpp); + if (hr == D3DERR_INVALIDCALL) + IM_ASSERT(0); + ImGui_ImplDX9_CreateDeviceObjects(); + } + return 0; case WM_DESTROY: PostQuitMessage(0); return 0; @@ -36,29 +51,24 @@ int main(int argc, char** argv) UnregisterClass(L"ImGui Example", wc.hInstance); return 0; } - D3DPRESENT_PARAMETERS d3dpp; - ZeroMemory(&d3dpp, sizeof(d3dpp)); - d3dpp.Windowed = TRUE; - d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; - d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; - d3dpp.EnableAutoDepthStencil = TRUE; - d3dpp.AutoDepthStencilFormat = D3DFMT_D16; - d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + ZeroMemory(&g_d3dpp, sizeof(g_d3dpp)); + g_d3dpp.Windowed = TRUE; + g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + g_d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; + g_d3dpp.EnableAutoDepthStencil = TRUE; + g_d3dpp.AutoDepthStencilFormat = D3DFMT_D16; + g_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Create the D3DDevice - LPDIRECT3DDEVICE9 pd3dDevice = NULL; - if (pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &pd3dDevice) < 0) + if (pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &g_d3dpp, &g_pd3dDevice) < 0) { pD3D->Release(); UnregisterClass(L"ImGui Example", wc.hInstance); return 0; } - ShowWindow(hwnd, SW_SHOWDEFAULT); - UpdateWindow(hwnd); - // Setup ImGui binding - ImGui_ImplDX9_Init(hwnd, pd3dDevice); + ImGui_ImplDX9_Init(hwnd, g_pd3dDevice); //ImGuiIO& io = ImGui::GetIO(); //ImFont* my_font1 = io.Fonts->AddFontDefault(); //ImFont* my_font2 = io.Fonts->AddFontFromFileTTF("extra_fonts/Karla-Regular.ttf", 15.0f); @@ -67,6 +77,9 @@ int main(int argc, char** argv) //ImFont* my_font5 = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, io.Fonts->GetGlyphRangesJapanese()); ImGui_ImplDX9_InitFontsTexture(); + ShowWindow(hwnd, SW_SHOWDEFAULT); + UpdateWindow(hwnd); + bool show_test_window = true; bool show_another_window = false; ImVec4 clear_col = ImColor(114, 144, 154); @@ -112,21 +125,21 @@ int main(int argc, char** argv) } // Rendering - pd3dDevice->SetRenderState(D3DRS_ZENABLE, false); - pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false); - pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, false); + g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, false); + g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false); + g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, false); D3DCOLOR clear_col_dx = D3DCOLOR_RGBA((int)(clear_col.x*255.0f), (int)(clear_col.y*255.0f), (int)(clear_col.z*255.0f), (int)(clear_col.w*255.0f)); - pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, clear_col_dx, 1.0f, 0); - if (pd3dDevice->BeginScene() >= 0) + g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, clear_col_dx, 1.0f, 0); + if (g_pd3dDevice->BeginScene() >= 0) { ImGui::Render(); - pd3dDevice->EndScene(); + g_pd3dDevice->EndScene(); } - pd3dDevice->Present(NULL, NULL, NULL, NULL); + g_pd3dDevice->Present(NULL, NULL, NULL, NULL); } ImGui_ImplDX9_Shutdown(); - if (pd3dDevice) pd3dDevice->Release(); + if (g_pd3dDevice) g_pd3dDevice->Release(); if (pD3D) pD3D->Release(); UnregisterClass(L"ImGui Example", wc.hInstance);