From cf2daf353ebffdc84e081b76fe5112776af8a1f4 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 30 Jun 2021 15:22:15 +0200 Subject: [PATCH] Backends: Cleanup, removed unnecessary create/destroy wrappers. Fix allegro5 backend + use same code as other backend. + Update gallery links (#4280) --- backends/imgui_impl_allegro5.cpp | 33 ++++++++++++++----------------- backends/imgui_impl_dx10.cpp | 21 ++++++++++---------- backends/imgui_impl_dx11.cpp | 23 ++++++++++----------- backends/imgui_impl_dx12.cpp | 34 +++++++++++++++++--------------- backends/imgui_impl_dx9.cpp | 19 +++++++++--------- backends/imgui_impl_glfw.cpp | 17 ++++++++-------- backends/imgui_impl_opengl2.cpp | 12 ++++++----- backends/imgui_impl_opengl3.cpp | 19 ++++++++++-------- backends/imgui_impl_sdl.cpp | 21 ++++++++------------ backends/imgui_impl_vulkan.cpp | 21 +++++++++++--------- backends/imgui_impl_win32.cpp | 22 +++++++++++---------- docs/FAQ.md | 4 ++-- docs/README.md | 4 ++-- 13 files changed, 129 insertions(+), 121 deletions(-) diff --git a/backends/imgui_impl_allegro5.cpp b/backends/imgui_impl_allegro5.cpp index 96f47f75..6b1e81f7 100644 --- a/backends/imgui_impl_allegro5.cpp +++ b/backends/imgui_impl_allegro5.cpp @@ -67,11 +67,10 @@ struct ImGui_ImplAllegro5_Data ImGui_ImplAllegro5_Data() { memset(this, 0, sizeof(*this)); } }; -// Wrapping access to backend data (to facilitate multiple-contexts stored in io.BackendPlatformUserData) -static ImGui_ImplAllegro5_Data* g_Data; -static ImGui_ImplAllegro5_Data* ImGui_ImplAllegro5_CreateBackendData() { IM_ASSERT(g_Data == NULL); g_Data = IM_NEW(ImGui_ImplAllegro5_Data); return g_Data; } -static ImGui_ImplAllegro5_Data* ImGui_ImplAllegro5_GetBackendData() { return ImGui::GetCurrentContext() != NULL ? g_Data : NULL; } -static void ImGui_ImplAllegro5_DestroyBackendData() { IM_DELETE(g_Data); g_Data = NULL; } +// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts +// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +// FIXME: multi-context support is not well tested and probably dysfunctional in this backend. +static ImGui_ImplAllegro5_Data* ImGui_ImplAllegro5_GetBackendData() { return ImGui::GetCurrentContext() ? (ImGui_ImplAllegro5_Data*)ImGui::GetIO().BackendPlatformUserData : NULL; } struct ImDrawVertAllegro { @@ -274,13 +273,13 @@ bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display) ImGuiIO& io = ImGui::GetIO(); IM_ASSERT(io.BackendPlatformUserData == NULL && "Already initialized a platform backend!"); - ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_CreateBackendData(); - bd->Display = display; - // Setup backend capabilities flags - io.BackendRendererUserData = (void*)bd; - io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) + ImGui_ImplAllegro5_Data* bd = IM_NEW(ImGui_ImplAllegro5_Data)(); + io.BackendPlatformUserData = (void*)bd; io.BackendPlatformName = io.BackendRendererName = "imgui_impl_allegro5"; + io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) + + bd->Display = display; // Create custom vertex declaration. // Unfortunately Allegro doesn't support 32-bit packed colors so we have to convert them to 4 floats. @@ -329,20 +328,18 @@ bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display) void ImGui_ImplAllegro5_Shutdown() { + ImGuiIO& io = ImGui::GetIO(); ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData(); - ImGui_ImplAllegro5_InvalidateDeviceObjects(); - - bd->Display = NULL; - bd->Time = 0.0; + ImGui_ImplAllegro5_InvalidateDeviceObjects(); if (bd->VertexDecl) al_destroy_vertex_decl(bd->VertexDecl); - bd->VertexDecl = NULL; - if (bd->ClipboardTextData) al_free(bd->ClipboardTextData); - bd->ClipboardTextData = NULL; - ImGui_ImplAllegro5_DestroyBackendData(); + + io.BackendPlatformUserData = NULL; + io.BackendPlatformName = io.BackendRendererName = NULL; + IM_DELETE(bd); } // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. diff --git a/backends/imgui_impl_dx10.cpp b/backends/imgui_impl_dx10.cpp index 9923fb58..5fdf8327 100644 --- a/backends/imgui_impl_dx10.cpp +++ b/backends/imgui_impl_dx10.cpp @@ -62,17 +62,18 @@ struct ImGui_ImplDX10_Data ImGui_ImplDX10_Data() { memset(this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; } }; -// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts -// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. -static ImGui_ImplDX10_Data* ImGui_ImplDX10_CreateBackendData() { return IM_NEW(ImGui_ImplDX10_Data)(); } -static ImGui_ImplDX10_Data* ImGui_ImplDX10_GetBackendData() { return (ImGui_ImplDX10_Data*)ImGui::GetIO().BackendRendererUserData; } -static void ImGui_ImplDX10_DestroyBackendData() { IM_DELETE(ImGui_ImplDX10_GetBackendData()); } - struct VERTEX_CONSTANT_BUFFER { float mvp[4][4]; }; +// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts +// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +static ImGui_ImplDX10_Data* ImGui_ImplDX10_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplDX10_Data*)ImGui::GetIO().BackendRendererUserData : NULL; +} + // Functions static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device* ctx) { @@ -524,7 +525,7 @@ bool ImGui_ImplDX10_Init(ID3D10Device* device) IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!"); // Setup backend capabilities flags - ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_CreateBackendData(); + ImGui_ImplDX10_Data* bd = IM_NEW(ImGui_ImplDX10_Data)(); io.BackendRendererUserData = (void*)bd; io.BackendRendererName = "imgui_impl_dx10"; io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. @@ -553,11 +554,11 @@ void ImGui_ImplDX10_Shutdown() ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData(); ImGui_ImplDX10_InvalidateDeviceObjects(); - if (bd->pFactory) { bd->pFactory->Release(); bd->pFactory = NULL; } - if (bd->pd3dDevice) { bd->pd3dDevice->Release(); bd->pd3dDevice = NULL; } + if (bd->pFactory) { bd->pFactory->Release(); } + if (bd->pd3dDevice) { bd->pd3dDevice->Release(); } io.BackendRendererName = NULL; io.BackendRendererUserData = NULL; - ImGui_ImplDX10_DestroyBackendData(); + IM_DELETE(bd); } void ImGui_ImplDX10_NewFrame() diff --git a/backends/imgui_impl_dx11.cpp b/backends/imgui_impl_dx11.cpp index 1f074256..b24fbb1a 100644 --- a/backends/imgui_impl_dx11.cpp +++ b/backends/imgui_impl_dx11.cpp @@ -63,17 +63,18 @@ struct ImGui_ImplDX11_Data ImGui_ImplDX11_Data() { memset(this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; } }; -// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts -// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. -static ImGui_ImplDX11_Data* ImGui_ImplDX11_CreateBackendData() { return IM_NEW(ImGui_ImplDX11_Data)(); } -static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData() { return (ImGui_ImplDX11_Data*)ImGui::GetIO().BackendRendererUserData; } -static void ImGui_ImplDX11_DestroyBackendData() { IM_DELETE(ImGui_ImplDX11_GetBackendData()); } - struct VERTEX_CONSTANT_BUFFER { float mvp[4][4]; }; +// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts +// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplDX11_Data*)ImGui::GetIO().BackendRendererUserData : NULL; +} + // Functions static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* ctx) { @@ -536,7 +537,7 @@ bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_co IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!"); // Setup backend capabilities flags - ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_CreateBackendData(); + ImGui_ImplDX11_Data* bd = IM_NEW(ImGui_ImplDX11_Data)(); io.BackendRendererUserData = (void*)bd; io.BackendRendererName = "imgui_impl_dx11"; io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. @@ -568,12 +569,12 @@ void ImGui_ImplDX11_Shutdown() ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData(); ImGui_ImplDX11_InvalidateDeviceObjects(); - if (bd->pFactory) { bd->pFactory->Release(); bd->pFactory = NULL; } - if (bd->pd3dDevice) { bd->pd3dDevice->Release(); bd->pd3dDevice = NULL; } - if (bd->pd3dDeviceContext) { bd->pd3dDeviceContext->Release(); bd->pd3dDeviceContext = NULL; } + if (bd->pFactory) { bd->pFactory->Release(); } + if (bd->pd3dDevice) { bd->pd3dDevice->Release(); } + if (bd->pd3dDeviceContext) { bd->pd3dDeviceContext->Release(); } io.BackendRendererName = NULL; io.BackendRendererUserData = NULL; - ImGui_ImplDX11_DestroyBackendData(); + IM_DELETE(bd); } void ImGui_ImplDX11_NewFrame() diff --git a/backends/imgui_impl_dx12.cpp b/backends/imgui_impl_dx12.cpp index 1d9810aa..38c4dab0 100644 --- a/backends/imgui_impl_dx12.cpp +++ b/backends/imgui_impl_dx12.cpp @@ -74,25 +74,19 @@ struct ImGui_ImplDX12_Data ImGui_ImplDX12_Data() { memset(this, 0, sizeof(*this)); frameIndex = UINT_MAX; } }; -// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts -// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. -static ImGui_ImplDX12_Data* ImGui_ImplDX12_CreateBackendData() { return IM_NEW(ImGui_ImplDX12_Data)(); } -static ImGui_ImplDX12_Data* ImGui_ImplDX12_GetBackendData() { return (ImGui_ImplDX12_Data*)ImGui::GetIO().BackendRendererUserData; } -static void ImGui_ImplDX12_DestroyBackendData() { IM_DELETE(ImGui_ImplDX12_GetBackendData()); } - -template -static void SafeRelease(T*& res) -{ - if (res) - res->Release(); - res = NULL; -} - struct VERTEX_CONSTANT_BUFFER { float mvp[4][4]; }; +// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts +// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +static ImGui_ImplDX12_Data* ImGui_ImplDX12_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplDX12_Data*)ImGui::GetIO().BackendRendererUserData : NULL; +} + +// Functions static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx, ImGui_ImplDX12_RenderBuffers* fr) { ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData(); @@ -150,6 +144,14 @@ static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12Graphic ctx->OMSetBlendFactor(blend_factor); } +template +static inline void SafeRelease(T*& res) +{ + if (res) + res->Release(); + res = NULL; +} + // Render function void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx) { @@ -691,7 +693,7 @@ bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FO IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!"); // Setup backend capabilities flags - ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_CreateBackendData(); + ImGui_ImplDX12_Data* bd = IM_NEW(ImGui_ImplDX12_Data)(); io.BackendRendererUserData = (void*)bd; io.BackendRendererName = "imgui_impl_dx12"; io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. @@ -727,7 +729,7 @@ void ImGui_ImplDX12_Shutdown() delete[] bd->pFrameResources; io.BackendRendererName = NULL; io.BackendRendererUserData = NULL; - ImGui_ImplDX12_DestroyBackendData(); + IM_DELETE(bd); } void ImGui_ImplDX12_NewFrame() diff --git a/backends/imgui_impl_dx9.cpp b/backends/imgui_impl_dx9.cpp index fcfab090..01e2bd60 100644 --- a/backends/imgui_impl_dx9.cpp +++ b/backends/imgui_impl_dx9.cpp @@ -49,12 +49,6 @@ struct ImGui_ImplDX9_Data ImGui_ImplDX9_Data() { memset(this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; } }; -// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts -// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. -static ImGui_ImplDX9_Data* ImGui_ImplDX9_CreateBackendData() { return IM_NEW(ImGui_ImplDX9_Data)(); } -static ImGui_ImplDX9_Data* ImGui_ImplDX9_GetBackendData() { return (ImGui_ImplDX9_Data*)ImGui::GetIO().BackendRendererUserData; } -static void ImGui_ImplDX9_DestroyBackendData() { IM_DELETE(ImGui_ImplDX9_GetBackendData()); } - struct CUSTOMVERTEX { float pos[3]; @@ -69,6 +63,13 @@ struct CUSTOMVERTEX #define IMGUI_COL_TO_DX9_ARGB(_COL) (((_COL) & 0xFF00FF00) | (((_COL) & 0xFF0000) >> 16) | (((_COL) & 0xFF) << 16)) #endif +// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts +// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +static ImGui_ImplDX9_Data* ImGui_ImplDX9_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplDX9_Data*)ImGui::GetIO().BackendRendererUserData : NULL; +} + // Functions static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data) { @@ -274,7 +275,7 @@ bool ImGui_ImplDX9_Init(IDirect3DDevice9* device) IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!"); // Setup backend capabilities flags - ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_CreateBackendData(); + ImGui_ImplDX9_Data* bd = IM_NEW(ImGui_ImplDX9_Data)(); io.BackendRendererUserData = (void*)bd; io.BackendRendererName = "imgui_impl_dx9"; io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. @@ -291,10 +292,10 @@ void ImGui_ImplDX9_Shutdown() ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); ImGui_ImplDX9_InvalidateDeviceObjects(); - if (bd->pd3dDevice) { bd->pd3dDevice->Release(); bd->pd3dDevice = NULL; } + if (bd->pd3dDevice) { bd->pd3dDevice->Release(); } io.BackendRendererName = NULL; io.BackendRendererUserData = NULL; - ImGui_ImplDX9_DestroyBackendData(); + IM_DELETE(bd); } static bool ImGui_ImplDX9_CreateFontsTexture() diff --git a/backends/imgui_impl_glfw.cpp b/backends/imgui_impl_glfw.cpp index c48e33af..58508a65 100644 --- a/backends/imgui_impl_glfw.cpp +++ b/backends/imgui_impl_glfw.cpp @@ -90,9 +90,10 @@ struct ImGui_ImplGlfw_Data // It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. // FIXME: multi-context support is not well tested and probably dysfunctional in this backend. // FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context. -static ImGui_ImplGlfw_Data* ImGui_ImplGlfw_CreateBackendData() { return IM_NEW(ImGui_ImplGlfw_Data)(); } -static ImGui_ImplGlfw_Data* ImGui_ImplGlfw_GetBackendData() { return (ImGui_ImplGlfw_Data*)ImGui::GetIO().BackendPlatformUserData; } -static void ImGui_ImplGlfw_DestroyBackendData() { IM_DELETE(ImGui_ImplGlfw_GetBackendData()); } +static ImGui_ImplGlfw_Data* ImGui_ImplGlfw_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplGlfw_Data*)ImGui::GetIO().BackendPlatformUserData : NULL; +} // Functions static const char* ImGui_ImplGlfw_GetClipboardText(void* user_data) @@ -167,16 +168,16 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw ImGuiIO& io = ImGui::GetIO(); IM_ASSERT(io.BackendPlatformUserData == NULL && "Already initialized a platform backend!"); - ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_CreateBackendData(); - bd->Window = window; - bd->Time = 0.0; - // Setup backend capabilities flags + ImGui_ImplGlfw_Data* bd = IM_NEW(ImGui_ImplGlfw_Data)(); io.BackendPlatformUserData = (void*)bd; io.BackendPlatformName = "imgui_impl_glfw"; io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) + bd->Window = window; + bd->Time = 0.0; + // Keyboard mapping. Dear ImGui will use those indices to peek into the io.KeysDown[] array. io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT; @@ -282,7 +283,7 @@ void ImGui_ImplGlfw_Shutdown() io.BackendPlatformName = NULL; io.BackendPlatformUserData = NULL; - ImGui_ImplGlfw_DestroyBackendData(); + IM_DELETE(bd); } static void ImGui_ImplGlfw_UpdateMousePosAndButtons() diff --git a/backends/imgui_impl_opengl2.cpp b/backends/imgui_impl_opengl2.cpp index 01f2eb54..0fa94e40 100644 --- a/backends/imgui_impl_opengl2.cpp +++ b/backends/imgui_impl_opengl2.cpp @@ -65,9 +65,10 @@ struct ImGui_ImplOpenGL2_Data // Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts // It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. -static ImGui_ImplOpenGL2_Data* ImGui_ImplOpenGL2_CreateBackendData() { return IM_NEW(ImGui_ImplOpenGL2_Data)(); } -static ImGui_ImplOpenGL2_Data* ImGui_ImplOpenGL2_GetBackendData() { return (ImGui_ImplOpenGL2_Data*)ImGui::GetIO().BackendRendererUserData; } -static void ImGui_ImplOpenGL2_DestroyBackendData() { IM_DELETE(ImGui_ImplOpenGL2_GetBackendData()); } +static ImGui_ImplOpenGL2_Data* ImGui_ImplOpenGL2_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL2_Data*)ImGui::GetIO().BackendRendererUserData : NULL; +} // Functions bool ImGui_ImplOpenGL2_Init() @@ -76,7 +77,7 @@ bool ImGui_ImplOpenGL2_Init() IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!"); // Setup backend capabilities flags - ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_CreateBackendData(); + ImGui_ImplOpenGL2_Data* bd = IM_NEW(ImGui_ImplOpenGL2_Data)(); io.BackendRendererUserData = (void*)bd; io.BackendRendererName = "imgui_impl_opengl2"; @@ -86,11 +87,12 @@ bool ImGui_ImplOpenGL2_Init() void ImGui_ImplOpenGL2_Shutdown() { ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData(); ImGui_ImplOpenGL2_DestroyDeviceObjects(); io.BackendRendererName = NULL; io.BackendRendererUserData = NULL; - ImGui_ImplOpenGL2_DestroyBackendData(); + IM_DELETE(bd); } void ImGui_ImplOpenGL2_NewFrame() diff --git a/backends/imgui_impl_opengl3.cpp b/backends/imgui_impl_opengl3.cpp index c7ef6432..8f72d438 100644 --- a/backends/imgui_impl_opengl3.cpp +++ b/backends/imgui_impl_opengl3.cpp @@ -191,9 +191,10 @@ struct ImGui_ImplOpenGL3_Data // Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts // It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. -static ImGui_ImplOpenGL3_Data* ImGui_ImplOpenGL3_CreateBackendData() { return IM_NEW(ImGui_ImplOpenGL3_Data)(); } -static ImGui_ImplOpenGL3_Data* ImGui_ImplOpenGL3_GetBackendData() { return (ImGui_ImplOpenGL3_Data*)ImGui::GetIO().BackendRendererUserData; } -static void ImGui_ImplOpenGL3_DestroyBackendData() { IM_DELETE(ImGui_ImplOpenGL3_GetBackendData()); } +static ImGui_ImplOpenGL3_Data* ImGui_ImplOpenGL3_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL3_Data*)ImGui::GetIO().BackendRendererUserData : NULL; +} // Functions bool ImGui_ImplOpenGL3_Init(const char* glsl_version) @@ -201,7 +202,10 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version) ImGuiIO& io = ImGui::GetIO(); IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!"); - ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_CreateBackendData(); + // Setup backend capabilities flags + ImGui_ImplOpenGL3_Data* bd = IM_NEW(ImGui_ImplOpenGL3_Data)();; + io.BackendRendererUserData = (void*)bd; + io.BackendRendererName = "imgui_impl_opengl3"; // Query for GL version (e.g. 320 for GL 3.2) #if !defined(IMGUI_IMPL_OPENGL_ES2) @@ -220,9 +224,6 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version) bd->GlVersion = 200; // GLES 2 #endif - // Setup backend capabilities flags - io.BackendRendererUserData = (void*)bd; - io.BackendRendererName = "imgui_impl_opengl3"; #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET if (bd->GlVersion >= 320) io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. @@ -296,10 +297,12 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version) void ImGui_ImplOpenGL3_Shutdown() { ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData(); + ImGui_ImplOpenGL3_DestroyDeviceObjects(); io.BackendRendererName = NULL; io.BackendRendererUserData = NULL; - ImGui_ImplOpenGL3_DestroyBackendData(); + IM_DELETE(bd); } void ImGui_ImplOpenGL3_NewFrame() diff --git a/backends/imgui_impl_sdl.cpp b/backends/imgui_impl_sdl.cpp index b9e4cfc1..e0ce176c 100644 --- a/backends/imgui_impl_sdl.cpp +++ b/backends/imgui_impl_sdl.cpp @@ -77,9 +77,10 @@ struct ImGui_ImplSDL2_Data // It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. // FIXME: multi-context support is not well tested and probably dysfunctional in this backend. // FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context. -static ImGui_ImplSDL2_Data* ImGui_ImplSDL2_CreateBackendData() { return IM_NEW(ImGui_ImplSDL2_Data)(); } -static ImGui_ImplSDL2_Data* ImGui_ImplSDL2_GetBackendData() { return (ImGui_ImplSDL2_Data*)ImGui::GetIO().BackendPlatformUserData; } -static void ImGui_ImplSDL2_DestroyBackendData() { IM_DELETE(ImGui_ImplSDL2_GetBackendData()); } +static ImGui_ImplSDL2_Data* ImGui_ImplSDL2_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplSDL2_Data*)ImGui::GetIO().BackendPlatformUserData : NULL; +} // Functions static const char* ImGui_ImplSDL2_GetClipboardText(void*) @@ -153,15 +154,15 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window) ImGuiIO& io = ImGui::GetIO(); IM_ASSERT(io.BackendPlatformUserData == NULL && "Already initialized a platform backend!"); - ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_CreateBackendData(); - bd->Window = window; - // Setup backend capabilities flags + ImGui_ImplSDL2_Data* bd = IM_NEW(ImGui_ImplSDL2_Data)(); io.BackendPlatformUserData = (void*)bd; io.BackendPlatformName = "imgui_impl_sdl"; io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) + bd->Window = window; + // Keyboard mapping. Dear ImGui will use those indices to peek into the io.KeysDown[] array. io.KeyMap[ImGuiKey_Tab] = SDL_SCANCODE_TAB; io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; @@ -253,21 +254,15 @@ void ImGui_ImplSDL2_Shutdown() { ImGuiIO& io = ImGui::GetIO(); ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); - bd->Window = NULL; - // Destroy last known clipboard data if (bd->ClipboardTextData) SDL_free(bd->ClipboardTextData); - bd->ClipboardTextData = NULL; - - // Destroy SDL mouse cursors for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++) SDL_FreeCursor(bd->MouseCursors[cursor_n]); - memset(bd->MouseCursors, 0, sizeof(bd->MouseCursors)); io.BackendPlatformName = NULL; io.BackendPlatformUserData = NULL; - ImGui_ImplSDL2_DestroyBackendData(); + IM_DELETE(bd); } static void ImGui_ImplSDL2_UpdateMousePosAndButtons() diff --git a/backends/imgui_impl_vulkan.cpp b/backends/imgui_impl_vulkan.cpp index 36d861a5..a2e85b8d 100644 --- a/backends/imgui_impl_vulkan.cpp +++ b/backends/imgui_impl_vulkan.cpp @@ -110,13 +110,6 @@ struct ImGui_ImplVulkan_Data } }; -// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts -// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. -// FIXME: multi-context support is not tested and probably dysfunctional in this backend. -static ImGui_ImplVulkan_Data* ImGui_ImplVulkan_CreateBackendData() { return IM_NEW(ImGui_ImplVulkan_Data)(); } -static ImGui_ImplVulkan_Data* ImGui_ImplVulkan_GetBackendData() { return (ImGui_ImplVulkan_Data*)ImGui::GetIO().BackendRendererUserData; } -static void ImGui_ImplVulkan_DestroyBackendData() { IM_DELETE(ImGui_ImplVulkan_GetBackendData()); } - // Forward Declarations bool ImGui_ImplVulkan_CreateDeviceObjects(); void ImGui_ImplVulkan_DestroyDeviceObjects(); @@ -314,6 +307,14 @@ static uint32_t __glsl_shader_frag_spv[] = // FUNCTIONS //----------------------------------------------------------------------------- +// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts +// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. +// FIXME: multi-context support is not tested and probably dysfunctional in this backend. +static ImGui_ImplVulkan_Data* ImGui_ImplVulkan_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplVulkan_Data*)ImGui::GetIO().BackendRendererUserData : NULL; +} + static uint32_t ImGui_ImplVulkan_MemoryType(VkMemoryPropertyFlags properties, uint32_t type_bits) { ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); @@ -1026,7 +1027,7 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!"); // Setup backend capabilities flags - ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_CreateBackendData(); + ImGui_ImplVulkan_Data* bd = IM_NEW(ImGui_ImplVulkan_Data)(); io.BackendRendererUserData = (void*)bd; io.BackendRendererName = "imgui_impl_vulkan"; io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. @@ -1052,10 +1053,12 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend void ImGui_ImplVulkan_Shutdown() { ImGuiIO& io = ImGui::GetIO(); + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + ImGui_ImplVulkan_DestroyDeviceObjects(); io.BackendRendererName = NULL; io.BackendRendererUserData = NULL; - ImGui_ImplVulkan_DestroyBackendData(); + IM_DELETE(bd); } void ImGui_ImplVulkan_NewFrame() diff --git a/backends/imgui_impl_win32.cpp b/backends/imgui_impl_win32.cpp index 7e60a511..52f738da 100644 --- a/backends/imgui_impl_win32.cpp +++ b/backends/imgui_impl_win32.cpp @@ -86,9 +86,10 @@ struct ImGui_ImplWin32_Data // It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts. // FIXME: multi-context support is not well tested and probably dysfunctional in this backend. // FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context. -static ImGui_ImplWin32_Data* ImGui_ImplWin32_CreateBackendData() { return IM_NEW(ImGui_ImplWin32_Data)(); } -static ImGui_ImplWin32_Data* ImGui_ImplWin32_GetBackendData() { return (ImGui_ImplWin32_Data*)ImGui::GetIO().BackendPlatformUserData; } -static void ImGui_ImplWin32_DestroyBackendData() { IM_DELETE(ImGui_ImplWin32_GetBackendData()); } +static ImGui_ImplWin32_Data* ImGui_ImplWin32_GetBackendData() +{ + return ImGui::GetCurrentContext() ? (ImGui_ImplWin32_Data*)ImGui::GetIO().BackendPlatformUserData : NULL; +} // Functions bool ImGui_ImplWin32_Init(void* hwnd) @@ -102,18 +103,19 @@ bool ImGui_ImplWin32_Init(void* hwnd) if (!::QueryPerformanceCounter((LARGE_INTEGER*)&perf_counter)) return false; - ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_CreateBackendData(); + // Setup backend capabilities flags + ImGui_ImplWin32_Data* bd = IM_NEW(ImGui_ImplWin32_Data)(); + io.BackendPlatformUserData = (void*)bd; + io.BackendPlatformName = "imgui_impl_win32"; + io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) + io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) + bd->hWnd = (HWND)hwnd; bd->WantUpdateHasGamepad = true; bd->TicksPerSecond = perf_frequency; bd->Time = perf_counter; bd->LastMouseCursor = ImGuiMouseCursor_COUNT; - // Setup backend capabilities flags - io.BackendPlatformUserData = (void*)bd; - io.BackendPlatformName = "imgui_impl_win32"; - io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) - io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) io.ImeWindowHandle = hwnd; // Keyboard mapping. Dear ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime. @@ -176,7 +178,7 @@ void ImGui_ImplWin32_Shutdown() io.BackendPlatformName = NULL; io.BackendPlatformUserData = NULL; - ImGui_ImplWin32_DestroyBackendData(); + IM_DELETE(bd); } static bool ImGui_ImplWin32_UpdateMouseCursor() diff --git a/docs/FAQ.md b/docs/FAQ.md index f7f88497..de9ceac6 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -609,7 +609,7 @@ You may take a look at: - [Quotes](https://github.com/ocornut/imgui/wiki/Quotes) - [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) - [Sponsors](https://github.com/ocornut/imgui/wiki/Sponsors) -- [Gallery](https://github.com/ocornut/imgui/issues/3488) +- [Gallery](https://github.com/ocornut/imgui/issues/3793) ##### [Return to Index](#index) @@ -655,7 +655,7 @@ There is an auto-generated [c-api for Dear ImGui (cimgui)](https://github.com/ci - Individuals: you can support continued maintenance and development via PayPal donations. See [README](https://github.com/ocornut/imgui/blob/master/docs/README.md). - If you are experienced with Dear ImGui and C++, look at [GitHub Issues](https://github.com/ocornut/imgui/issues), [GitHub Discussions](https://github.com/ocornut/imgui/discussions), the [Wiki](https://github.com/ocornut/imgui/wiki), read [docs/TODO.txt](https://github.com/ocornut/imgui/blob/master/docs/TODO.txt) and see how you want to help and can help! - Disclose your usage of Dear ImGui via a dev blog post, a tweet, a screenshot, a mention somewhere etc. -You may post screenshot or links in the [gallery threads](https://github.com/ocornut/imgui/issues/3488). Visuals are ideal as they inspire other programmers. Disclosing your use of Dear ImGui helps the library grow credibility, and help other teams and programmers with taking decisions. +You may post screenshot or links in the [gallery threads](https://github.com/ocornut/imgui/issues/3793). Visuals are ideal as they inspire other programmers. Disclosing your use of Dear ImGui helps the library grow credibility, and help other teams and programmers with taking decisions. - If you have issues or if you need to hack into the library, even if you don't expect any support it is useful that you share your issues or sometimes incomplete PR. ##### [Return to Index](#index) diff --git a/docs/README.md b/docs/README.md index c729d9c9..f51781ee 100644 --- a/docs/README.md +++ b/docs/README.md @@ -141,7 +141,7 @@ Some of the goals for 2021 are: ### Gallery -For more user-submitted screenshots of projects using Dear ImGui, check out the [Gallery Threads](https://github.com/ocornut/imgui/issues/3488)! +For more user-submitted screenshots of projects using Dear ImGui, check out the [Gallery Threads](https://github.com/ocornut/imgui/issues/3793)! For a list of third-party widgets and extensions, check out the [Useful Extensions/Widgets](https://github.com/ocornut/imgui/wiki/Useful-Extensions) wiki page. @@ -174,7 +174,7 @@ Advanced users may want to use the `docking` branch with [Multi-Viewport](https: **Who uses Dear ImGui?** -See the [Quotes](https://github.com/ocornut/imgui/wiki/Quotes), [Sponsors](https://github.com/ocornut/imgui/wiki/Sponsors), [Software using dear imgui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) Wiki pages for an idea of who is using Dear ImGui. Please add your game/software if you can! Also see the [Gallery Threads](https://github.com/ocornut/imgui/issues/3488)! +See the [Quotes](https://github.com/ocornut/imgui/wiki/Quotes), [Sponsors](https://github.com/ocornut/imgui/wiki/Sponsors), [Software using dear imgui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) Wiki pages for an idea of who is using Dear ImGui. Please add your game/software if you can! Also see the [Gallery Threads](https://github.com/ocornut/imgui/issues/3793)! How to help -----------