ソースを参照

Backends: Cleanup, removed unnecessary create/destroy wrappers. Fix allegro5 backend + use same code as other backend.

+ Update gallery links (#4280)
ocornut 4 年 前
コミット
cf2daf353e

+ 15 - 18
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.

+ 11 - 10
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()

+ 12 - 11
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()

+ 18 - 16
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<typename T>
-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<typename T>
+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()

+ 10 - 9
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()

+ 9 - 8
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()

+ 7 - 5
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()

+ 11 - 8
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()

+ 8 - 13
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()

+ 12 - 9
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()

+ 12 - 10
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()

+ 2 - 2
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)

+ 2 - 2
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
 -----------