Browse Source

Examples: DirectX9 example application handle window resizing.

ocornut 10 years ago
parent
commit
866fa95aaa

+ 8 - 8
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 *)&current_time); 

+ 28 - 10
examples/directx9_example/imgui_impl_dx9.cpp

@@ -10,6 +10,7 @@
 #include <dinput.h>
 
 // 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 *)&current_time); 

+ 4 - 0
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 <windows.h> types. You can copy the extern declaration in your code.

+ 36 - 23
examples/directx9_example/main.cpp

@@ -1,5 +1,4 @@
 // ImGui - standalone example application for DirectX 9
-// TODO: Allow resizing the application window.
 
 #include <imgui.h>
 #include "imgui_impl_dx9.h"
@@ -7,6 +6,10 @@
 #define DIRECTINPUT_VERSION 0x0800
 #include <dinput.h>
 
+// 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);