aboutsummaryrefslogtreecommitdiff
path: root/3rdparty/imgui/backend/imgui_impl_dx11.cpp
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2022-02-19 13:30:03 -0800
committerrtk0c <[email protected]>2022-02-19 13:30:03 -0800
commit9dcdcf68f6a60741cbdd287e7eda23b4a21a080e (patch)
treef5ff4c569607e1f63de9dd87bb7442e021b1f620 /3rdparty/imgui/backend/imgui_impl_dx11.cpp
parent2599909052ef552efd5622bf73b60913e815b498 (diff)
Fix build errors and update all dependencies to latest version
- Fixed doctest executable not compiling - Fixed class accessibility error in Workflow_Main.cpp - Fixed selection of OpenGL loader in imgui OpenGL 2 & 3 backends - All loading is handled in our code now, the imgui_*_backend.cpp files are instructed to do nothing
Diffstat (limited to '3rdparty/imgui/backend/imgui_impl_dx11.cpp')
-rw-r--r--3rdparty/imgui/backend/imgui_impl_dx11.cpp209
1 files changed, 126 insertions, 83 deletions
diff --git a/3rdparty/imgui/backend/imgui_impl_dx11.cpp b/3rdparty/imgui/backend/imgui_impl_dx11.cpp
index f114cdc..3f628cb 100644
--- a/3rdparty/imgui/backend/imgui_impl_dx11.cpp
+++ b/3rdparty/imgui/backend/imgui_impl_dx11.cpp
@@ -5,12 +5,15 @@
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
-// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
+// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
+// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Read online: https://github.com/ocornut/imgui/tree/master/docs
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
+// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
+// 2021-05-19: DirectX11: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
// 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer.
// 2019-08-01: DirectX11: Fixed code querying the Geometry Shader state (would generally error with Debug layer enabled).
// 2019-07-21: DirectX11: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX10_RenderDrawData. Clearing Hull/Domain/Compute shaders without backup/restore.
@@ -37,30 +40,46 @@
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
#endif
-// DirectX data
-static ID3D11Device* g_pd3dDevice = NULL;
-static ID3D11DeviceContext* g_pd3dDeviceContext = NULL;
-static IDXGIFactory* g_pFactory = NULL;
-static ID3D11Buffer* g_pVB = NULL;
-static ID3D11Buffer* g_pIB = NULL;
-static ID3D11VertexShader* g_pVertexShader = NULL;
-static ID3D11InputLayout* g_pInputLayout = NULL;
-static ID3D11Buffer* g_pVertexConstantBuffer = NULL;
-static ID3D11PixelShader* g_pPixelShader = NULL;
-static ID3D11SamplerState* g_pFontSampler = NULL;
-static ID3D11ShaderResourceView*g_pFontTextureView = NULL;
-static ID3D11RasterizerState* g_pRasterizerState = NULL;
-static ID3D11BlendState* g_pBlendState = NULL;
-static ID3D11DepthStencilState* g_pDepthStencilState = NULL;
-static int g_VertexBufferSize = 5000, g_IndexBufferSize = 10000;
+// DirectX11 data
+struct ImGui_ImplDX11_Data
+{
+ ID3D11Device* pd3dDevice;
+ ID3D11DeviceContext* pd3dDeviceContext;
+ IDXGIFactory* pFactory;
+ ID3D11Buffer* pVB;
+ ID3D11Buffer* pIB;
+ ID3D11VertexShader* pVertexShader;
+ ID3D11InputLayout* pInputLayout;
+ ID3D11Buffer* pVertexConstantBuffer;
+ ID3D11PixelShader* pPixelShader;
+ ID3D11SamplerState* pFontSampler;
+ ID3D11ShaderResourceView* pFontTextureView;
+ ID3D11RasterizerState* pRasterizerState;
+ ID3D11BlendState* pBlendState;
+ ID3D11DepthStencilState* pDepthStencilState;
+ int VertexBufferSize;
+ int IndexBufferSize;
+
+ ImGui_ImplDX11_Data() { memset(this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; }
+};
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)
{
+ ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
+
// Setup viewport
D3D11_VIEWPORT vp;
memset(&vp, 0, sizeof(D3D11_VIEWPORT));
@@ -74,14 +93,14 @@ static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceC
// Setup shader and vertex buffers
unsigned int stride = sizeof(ImDrawVert);
unsigned int offset = 0;
- ctx->IASetInputLayout(g_pInputLayout);
- ctx->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset);
- ctx->IASetIndexBuffer(g_pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
+ ctx->IASetInputLayout(bd->pInputLayout);
+ ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
+ ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
- ctx->VSSetShader(g_pVertexShader, NULL, 0);
- ctx->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer);
- ctx->PSSetShader(g_pPixelShader, NULL, 0);
- ctx->PSSetSamplers(0, 1, &g_pFontSampler);
+ ctx->VSSetShader(bd->pVertexShader, NULL, 0);
+ ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
+ ctx->PSSetShader(bd->pPixelShader, NULL, 0);
+ ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
ctx->GSSetShader(NULL, NULL, 0);
ctx->HSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used..
ctx->DSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used..
@@ -89,9 +108,9 @@ static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceC
// Setup blend state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
- ctx->OMSetBlendState(g_pBlendState, blend_factor, 0xffffffff);
- ctx->OMSetDepthStencilState(g_pDepthStencilState, 0);
- ctx->RSSetState(g_pRasterizerState);
+ ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
+ ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0);
+ ctx->RSSetState(bd->pRasterizerState);
}
// Render function
@@ -101,42 +120,43 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
return;
- ID3D11DeviceContext* ctx = g_pd3dDeviceContext;
+ ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
+ ID3D11DeviceContext* ctx = bd->pd3dDeviceContext;
// Create and grow vertex/index buffers if needed
- if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount)
+ if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
{
- if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
- g_VertexBufferSize = draw_data->TotalVtxCount + 5000;
+ if (bd->pVB) { bd->pVB->Release(); bd->pVB = NULL; }
+ bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
D3D11_BUFFER_DESC desc;
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
desc.Usage = D3D11_USAGE_DYNAMIC;
- desc.ByteWidth = g_VertexBufferSize * sizeof(ImDrawVert);
+ desc.ByteWidth = bd->VertexBufferSize * sizeof(ImDrawVert);
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
- if (g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVB) < 0)
+ if (bd->pd3dDevice->CreateBuffer(&desc, NULL, &bd->pVB) < 0)
return;
}
- if (!g_pIB || g_IndexBufferSize < draw_data->TotalIdxCount)
+ if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
{
- if (g_pIB) { g_pIB->Release(); g_pIB = NULL; }
- g_IndexBufferSize = draw_data->TotalIdxCount + 10000;
+ if (bd->pIB) { bd->pIB->Release(); bd->pIB = NULL; }
+ bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
D3D11_BUFFER_DESC desc;
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
desc.Usage = D3D11_USAGE_DYNAMIC;
- desc.ByteWidth = g_IndexBufferSize * sizeof(ImDrawIdx);
+ desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
- if (g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pIB) < 0)
+ if (bd->pd3dDevice->CreateBuffer(&desc, NULL, &bd->pIB) < 0)
return;
}
// Upload vertex/index data into a single contiguous GPU buffer
D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource;
- if (ctx->Map(g_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK)
+ if (ctx->Map(bd->pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK)
return;
- if (ctx->Map(g_pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK)
+ if (ctx->Map(bd->pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK)
return;
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData;
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData;
@@ -148,14 +168,14 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
vtx_dst += cmd_list->VtxBuffer.Size;
idx_dst += cmd_list->IdxBuffer.Size;
}
- ctx->Unmap(g_pVB, 0);
- ctx->Unmap(g_pIB, 0);
+ ctx->Unmap(bd->pVB, 0);
+ ctx->Unmap(bd->pIB, 0);
// Setup orthographic projection matrix into our constant buffer
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
{
D3D11_MAPPED_SUBRESOURCE mapped_resource;
- if (ctx->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
+ if (ctx->Map(bd->pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
return;
VERTEX_CONSTANT_BUFFER* constant_buffer = (VERTEX_CONSTANT_BUFFER*)mapped_resource.pData;
float L = draw_data->DisplayPos.x;
@@ -170,7 +190,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
};
memcpy(&constant_buffer->mvp, mvp, sizeof(mvp));
- ctx->Unmap(g_pVertexConstantBuffer, 0);
+ ctx->Unmap(bd->pVertexConstantBuffer, 0);
}
// Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
@@ -198,7 +218,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
DXGI_FORMAT IndexBufferFormat;
ID3D11InputLayout* InputLayout;
};
- BACKUP_DX11_STATE old;
+ BACKUP_DX11_STATE old = {};
old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
@@ -243,12 +263,18 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
}
else
{
+ // Project scissor/clipping rectangles into framebuffer space
+ ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
+ ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
+ if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
+ continue;
+
// Apply scissor/clipping rectangle
- const D3D11_RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) };
+ const D3D11_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
ctx->RSSetScissorRects(1, &r);
// Bind texture, Draw
- ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->TextureId;
+ ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->GetTexID();
ctx->PSSetShaderResources(0, 1, &texture_srv);
ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
}
@@ -281,6 +307,7 @@ static void ImGui_ImplDX11_CreateFontsTexture()
{
// Build texture atlas
ImGuiIO& io = ImGui::GetIO();
+ ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
unsigned char* pixels;
int width, height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
@@ -304,7 +331,8 @@ static void ImGui_ImplDX11_CreateFontsTexture()
subResource.pSysMem = pixels;
subResource.SysMemPitch = desc.Width * 4;
subResource.SysMemSlicePitch = 0;
- g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
+ bd->pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
+ IM_ASSERT(pTexture != NULL);
// Create texture view
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
@@ -313,12 +341,12 @@ static void ImGui_ImplDX11_CreateFontsTexture()
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = desc.MipLevels;
srvDesc.Texture2D.MostDetailedMip = 0;
- g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &g_pFontTextureView);
+ bd->pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &bd->pFontTextureView);
pTexture->Release();
}
// Store our identifier
- io.Fonts->SetTexID((ImTextureID)g_pFontTextureView);
+ io.Fonts->SetTexID((ImTextureID)bd->pFontTextureView);
// Create texture sampler
{
@@ -332,15 +360,16 @@ static void ImGui_ImplDX11_CreateFontsTexture()
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
desc.MinLOD = 0.f;
desc.MaxLOD = 0.f;
- g_pd3dDevice->CreateSamplerState(&desc, &g_pFontSampler);
+ bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
}
}
bool ImGui_ImplDX11_CreateDeviceObjects()
{
- if (!g_pd3dDevice)
+ ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
+ if (!bd->pd3dDevice)
return false;
- if (g_pFontSampler)
+ if (bd->pFontSampler)
ImGui_ImplDX11_InvalidateDeviceObjects();
// By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
@@ -382,7 +411,7 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
ID3DBlob* vertexShaderBlob;
if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &vertexShaderBlob, NULL)))
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
- if (g_pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), NULL, &g_pVertexShader) != S_OK)
+ if (bd->pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), NULL, &bd->pVertexShader) != S_OK)
{
vertexShaderBlob->Release();
return false;
@@ -395,7 +424,7 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)IM_OFFSETOF(ImDrawVert, col), D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
- if (g_pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK)
+ if (bd->pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pInputLayout) != S_OK)
{
vertexShaderBlob->Release();
return false;
@@ -410,7 +439,7 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
- g_pd3dDevice->CreateBuffer(&desc, NULL, &g_pVertexConstantBuffer);
+ bd->pd3dDevice->CreateBuffer(&desc, NULL, &bd->pVertexConstantBuffer);
}
}
@@ -435,7 +464,7 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
ID3DBlob* pixelShaderBlob;
if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &pixelShaderBlob, NULL)))
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
- if (g_pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), NULL, &g_pPixelShader) != S_OK)
+ if (bd->pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), NULL, &bd->pPixelShader) != S_OK)
{
pixelShaderBlob->Release();
return false;
@@ -456,7 +485,7 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
- g_pd3dDevice->CreateBlendState(&desc, &g_pBlendState);
+ bd->pd3dDevice->CreateBlendState(&desc, &bd->pBlendState);
}
// Create the rasterizer state
@@ -467,7 +496,7 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
desc.CullMode = D3D11_CULL_NONE;
desc.ScissorEnable = true;
desc.DepthClipEnable = true;
- g_pd3dDevice->CreateRasterizerState(&desc, &g_pRasterizerState);
+ bd->pd3dDevice->CreateRasterizerState(&desc, &bd->pRasterizerState);
}
// Create depth-stencil State
@@ -481,7 +510,7 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
desc.BackFace = desc.FrontFace;
- g_pd3dDevice->CreateDepthStencilState(&desc, &g_pDepthStencilState);
+ bd->pd3dDevice->CreateDepthStencilState(&desc, &bd->pDepthStencilState);
}
ImGui_ImplDX11_CreateFontsTexture();
@@ -491,27 +520,31 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
void ImGui_ImplDX11_InvalidateDeviceObjects()
{
- if (!g_pd3dDevice)
+ ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
+ if (!bd->pd3dDevice)
return;
- if (g_pFontSampler) { g_pFontSampler->Release(); g_pFontSampler = NULL; }
- if (g_pFontTextureView) { g_pFontTextureView->Release(); g_pFontTextureView = NULL; ImGui::GetIO().Fonts->SetTexID(NULL); } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
- if (g_pIB) { g_pIB->Release(); g_pIB = NULL; }
- if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
-
- if (g_pBlendState) { g_pBlendState->Release(); g_pBlendState = NULL; }
- if (g_pDepthStencilState) { g_pDepthStencilState->Release(); g_pDepthStencilState = NULL; }
- if (g_pRasterizerState) { g_pRasterizerState->Release(); g_pRasterizerState = NULL; }
- if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
- if (g_pVertexConstantBuffer) { g_pVertexConstantBuffer->Release(); g_pVertexConstantBuffer = NULL; }
- if (g_pInputLayout) { g_pInputLayout->Release(); g_pInputLayout = NULL; }
- if (g_pVertexShader) { g_pVertexShader->Release(); g_pVertexShader = NULL; }
+ if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = NULL; }
+ if (bd->pFontTextureView) { bd->pFontTextureView->Release(); bd->pFontTextureView = NULL; ImGui::GetIO().Fonts->SetTexID(NULL); } // We copied data->pFontTextureView to io.Fonts->TexID so let's clear that as well.
+ if (bd->pIB) { bd->pIB->Release(); bd->pIB = NULL; }
+ if (bd->pVB) { bd->pVB->Release(); bd->pVB = NULL; }
+ if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = NULL; }
+ if (bd->pDepthStencilState) { bd->pDepthStencilState->Release(); bd->pDepthStencilState = NULL; }
+ if (bd->pRasterizerState) { bd->pRasterizerState->Release(); bd->pRasterizerState = NULL; }
+ if (bd->pPixelShader) { bd->pPixelShader->Release(); bd->pPixelShader = NULL; }
+ if (bd->pVertexConstantBuffer) { bd->pVertexConstantBuffer->Release(); bd->pVertexConstantBuffer = NULL; }
+ if (bd->pInputLayout) { bd->pInputLayout->Release(); bd->pInputLayout = NULL; }
+ if (bd->pVertexShader) { bd->pVertexShader->Release(); bd->pVertexShader = NULL; }
}
bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context)
{
- // Setup backend capabilities flags
ImGuiIO& io = ImGui::GetIO();
+ IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!");
+
+ // Setup backend capabilities flags
+ 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.
@@ -524,28 +557,38 @@ bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_co
if (pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter)) == S_OK)
if (pDXGIAdapter->GetParent(IID_PPV_ARGS(&pFactory)) == S_OK)
{
- g_pd3dDevice = device;
- g_pd3dDeviceContext = device_context;
- g_pFactory = pFactory;
+ bd->pd3dDevice = device;
+ bd->pd3dDeviceContext = device_context;
+ bd->pFactory = pFactory;
}
if (pDXGIDevice) pDXGIDevice->Release();
if (pDXGIAdapter) pDXGIAdapter->Release();
- g_pd3dDevice->AddRef();
- g_pd3dDeviceContext->AddRef();
+ bd->pd3dDevice->AddRef();
+ bd->pd3dDeviceContext->AddRef();
return true;
}
void ImGui_ImplDX11_Shutdown()
{
+ ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
+ IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?");
+ ImGuiIO& io = ImGui::GetIO();
+
ImGui_ImplDX11_InvalidateDeviceObjects();
- if (g_pFactory) { g_pFactory->Release(); g_pFactory = NULL; }
- if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; }
- if (g_pd3dDeviceContext) { g_pd3dDeviceContext->Release(); g_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;
+ IM_DELETE(bd);
}
void ImGui_ImplDX11_NewFrame()
{
- if (!g_pFontSampler)
+ ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
+ IM_ASSERT(bd != NULL && "Did you call ImGui_ImplDX11_Init()?");
+
+ if (!bd->pFontSampler)
ImGui_ImplDX11_CreateDeviceObjects();
}