1
0
mirror of https://github.com/ocornut/imgui.git synced 2025-01-31 03:53:44 +01:00

Merge branch 'docking' into SDL_gpu

This commit is contained in:
Acclution 2024-11-13 18:33:48 +01:00
commit 1b40db822e
72 changed files with 4162 additions and 2082 deletions

View File

@ -42,5 +42,5 @@ jobs:
fi fi
cd examples/example_null cd examples/example_null
pvs-studio-analyzer trace -- make WITH_EXTRA_WARNINGS=1 pvs-studio-analyzer trace -- make WITH_EXTRA_WARNINGS=1
pvs-studio-analyzer analyze --disableLicenseExpirationCheck -e ../../imstb_rectpack.h -e ../../imstb_textedit.h -e ../../imstb_truetype.h -l ../../pvs-studio.lic -o pvs-studio.log pvs-studio-analyzer analyze -e ../../imstb_rectpack.h -e ../../imstb_textedit.h -e ../../imstb_truetype.h -l ../../pvs-studio.lic -o pvs-studio.log
plog-converter -a 'GA:1,2;OP:1' -d V1071 -t errorfile -w pvs-studio.log plog-converter -a 'GA:1,2;OP:1' -d V1071 -t errorfile -w pvs-studio.log

View File

@ -3,7 +3,7 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'ALLEGRO_BITMAP*' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: User texture binding. Use 'ALLEGRO_BITMAP*' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy ALLEGRO_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy ALLEGRO_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
// [X] Platform: Clipboard support (from Allegro 5.1.12) // [X] Platform: Clipboard support (from Allegro 5.1.12)
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// Missing features: // Missing features:
@ -150,14 +150,14 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
// Render command lists // Render command lists
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* draw_list = draw_data->CmdLists[n];
ImVector<ImDrawVertAllegro>& vertices = bd->BufVertices; ImVector<ImDrawVertAllegro>& vertices = bd->BufVertices;
#if ALLEGRO_HAS_DRAW_INDEXED_PRIM #if ALLEGRO_HAS_DRAW_INDEXED_PRIM
vertices.resize(cmd_list->VtxBuffer.Size); vertices.resize(draw_list->VtxBuffer.Size);
for (int i = 0; i < cmd_list->VtxBuffer.Size; i++) for (int i = 0; i < draw_list->VtxBuffer.Size; i++)
{ {
const ImDrawVert* src_v = &cmd_list->VtxBuffer[i]; const ImDrawVert* src_v = &draw_list->VtxBuffer[i];
ImDrawVertAllegro* dst_v = &vertices[i]; ImDrawVertAllegro* dst_v = &vertices[i];
DRAW_VERT_IMGUI_TO_ALLEGRO(dst_v, src_v); DRAW_VERT_IMGUI_TO_ALLEGRO(dst_v, src_v);
} }
@ -167,21 +167,21 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
// FIXME-OPT: Allegro doesn't support 16-bit indices. // FIXME-OPT: Allegro doesn't support 16-bit indices.
// You can '#define ImDrawIdx int' in imconfig.h to request Dear ImGui to output 32-bit indices. // You can '#define ImDrawIdx int' in imconfig.h to request Dear ImGui to output 32-bit indices.
// Otherwise, we convert them from 16-bit to 32-bit at runtime here, which works perfectly but is a little wasteful. // Otherwise, we convert them from 16-bit to 32-bit at runtime here, which works perfectly but is a little wasteful.
bd->BufIndices.resize(cmd_list->IdxBuffer.Size); bd->BufIndices.resize(draw_list->IdxBuffer.Size);
for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i) for (int i = 0; i < draw_list->IdxBuffer.Size; ++i)
bd->BufIndices[i] = (int)cmd_list->IdxBuffer.Data[i]; bd->BufIndices[i] = (int)draw_list->IdxBuffer.Data[i];
indices = bd->BufIndices.Data; indices = bd->BufIndices.Data;
} }
else if (sizeof(ImDrawIdx) == 4) else if (sizeof(ImDrawIdx) == 4)
{ {
indices = (const int*)cmd_list->IdxBuffer.Data; indices = (const int*)draw_list->IdxBuffer.Data;
} }
#else #else
// Allegro's implementation of al_draw_indexed_prim() for DX9 was broken until 5.2.5. Unindex buffers ourselves while converting vertex format. // Allegro's implementation of al_draw_indexed_prim() for DX9 was broken until 5.2.5. Unindex buffers ourselves while converting vertex format.
vertices.resize(cmd_list->IdxBuffer.Size); vertices.resize(draw_list->IdxBuffer.Size);
for (int i = 0; i < cmd_list->IdxBuffer.Size; i++) for (int i = 0; i < draw_list->IdxBuffer.Size; i++)
{ {
const ImDrawVert* src_v = &cmd_list->VtxBuffer[cmd_list->IdxBuffer[i]]; const ImDrawVert* src_v = &draw_list->VtxBuffer[draw_list->IdxBuffer[i]];
ImDrawVertAllegro* dst_v = &vertices[i]; ImDrawVertAllegro* dst_v = &vertices[i];
DRAW_VERT_IMGUI_TO_ALLEGRO(dst_v, src_v); DRAW_VERT_IMGUI_TO_ALLEGRO(dst_v, src_v);
} }
@ -189,9 +189,9 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
// Render command lists // Render command lists
ImVec2 clip_off = draw_data->DisplayPos; ImVec2 clip_off = draw_data->DisplayPos;
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
{ {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback) if (pcmd->UserCallback)
{ {
// User callback, registered via ImDrawList::AddCallback() // User callback, registered via ImDrawList::AddCallback()
@ -199,7 +199,7 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplAllegro5_SetupRenderState(draw_data); ImGui_ImplAllegro5_SetupRenderState(draw_data);
else else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(draw_list, pcmd);
} }
else else
{ {
@ -311,7 +311,9 @@ static void ImGui_ImplAllegro5_SetClipboardText(ImGuiContext*, const char* text)
} }
#endif #endif
static ImGuiKey ImGui_ImplAllegro5_KeyCodeToImGuiKey(int key_code) // Not static to allow third-party code to use that if they want to (but undocumented)
ImGuiKey ImGui_ImplAllegro5_KeyCodeToImGuiKey(int key_code);
ImGuiKey ImGui_ImplAllegro5_KeyCodeToImGuiKey(int key_code)
{ {
switch (key_code) switch (key_code)
{ {

View File

@ -3,7 +3,7 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'ALLEGRO_BITMAP*' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: User texture binding. Use 'ALLEGRO_BITMAP*' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy ALLEGRO_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy ALLEGRO_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
// [X] Platform: Clipboard support (from Allegro 5.1.12) // [X] Platform: Clipboard support (from Allegro 5.1.12)
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// Missing features: // Missing features:

View File

@ -2,7 +2,7 @@
// This needs to be used along with the OpenGL 3 Renderer (imgui_impl_opengl3) // This needs to be used along with the OpenGL 3 Renderer (imgui_impl_opengl3)
// Implemented features: // Implemented features:
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy AKEYCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy AKEYCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen. // [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
// Missing features: // Missing features:
// [ ] Platform: Clipboard support. // [ ] Platform: Clipboard support.

View File

@ -2,7 +2,7 @@
// This needs to be used along with the OpenGL 3 Renderer (imgui_impl_opengl3) // This needs to be used along with the OpenGL 3 Renderer (imgui_impl_opengl3)
// Implemented features: // Implemented features:
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy AKEYCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy AKEYCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen. // [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
// Missing features: // Missing features:
// [ ] Platform: Clipboard support. // [ ] Platform: Clipboard support.

View File

@ -17,6 +17,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2024-10-07: DirectX10: Changed default texture sampler to Clamp instead of Repeat/Wrap.
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. // 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
// 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-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: DirectX10: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) // 2021-05-19: DirectX10: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
@ -82,11 +83,11 @@ static ImGui_ImplDX10_Data* ImGui_ImplDX10_GetBackendData()
} }
// Forward Declarations // Forward Declarations
static void ImGui_ImplDX10_InitPlatformInterface(); static void ImGui_ImplDX10_InitMultiViewportSupport();
static void ImGui_ImplDX10_ShutdownPlatformInterface(); static void ImGui_ImplDX10_ShutdownMultiViewportSupport();
// Functions // Functions
static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device* ctx) static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device* device)
{ {
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData(); ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
@ -98,26 +99,26 @@ static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device*
vp.MinDepth = 0.0f; vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f; vp.MaxDepth = 1.0f;
vp.TopLeftX = vp.TopLeftY = 0; vp.TopLeftX = vp.TopLeftY = 0;
ctx->RSSetViewports(1, &vp); device->RSSetViewports(1, &vp);
// Bind shader and vertex buffers // Bind shader and vertex buffers
unsigned int stride = sizeof(ImDrawVert); unsigned int stride = sizeof(ImDrawVert);
unsigned int offset = 0; unsigned int offset = 0;
ctx->IASetInputLayout(bd->pInputLayout); device->IASetInputLayout(bd->pInputLayout);
ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset); device->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0); device->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
ctx->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); device->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ctx->VSSetShader(bd->pVertexShader); device->VSSetShader(bd->pVertexShader);
ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer); device->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
ctx->PSSetShader(bd->pPixelShader); device->PSSetShader(bd->pPixelShader);
ctx->PSSetSamplers(0, 1, &bd->pFontSampler); device->PSSetSamplers(0, 1, &bd->pFontSampler);
ctx->GSSetShader(nullptr); device->GSSetShader(nullptr);
// Setup render state // Setup render state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f }; const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff); device->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0); device->OMSetDepthStencilState(bd->pDepthStencilState, 0);
ctx->RSSetState(bd->pRasterizerState); device->RSSetState(bd->pRasterizerState);
} }
// Render function // Render function
@ -128,7 +129,7 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
return; return;
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData(); ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
ID3D10Device* ctx = bd->pd3dDevice; ID3D10Device* device = bd->pd3dDevice;
// Create and grow vertex/index buffers if needed // Create and grow vertex/index buffers if needed
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount) if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
@ -142,7 +143,7 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
desc.MiscFlags = 0; desc.MiscFlags = 0;
if (ctx->CreateBuffer(&desc, nullptr, &bd->pVB) < 0) if (device->CreateBuffer(&desc, nullptr, &bd->pVB) < 0)
return; return;
} }
@ -156,7 +157,7 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx); desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
desc.BindFlags = D3D10_BIND_INDEX_BUFFER; desc.BindFlags = D3D10_BIND_INDEX_BUFFER;
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
if (ctx->CreateBuffer(&desc, nullptr, &bd->pIB) < 0) if (device->CreateBuffer(&desc, nullptr, &bd->pIB) < 0)
return; return;
} }
@ -167,11 +168,11 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
bd->pIB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&idx_dst); bd->pIB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&idx_dst);
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* draw_list = draw_data->CmdLists[n];
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
vtx_dst += cmd_list->VtxBuffer.Size; vtx_dst += draw_list->VtxBuffer.Size;
idx_dst += cmd_list->IdxBuffer.Size; idx_dst += draw_list->IdxBuffer.Size;
} }
bd->pVB->Unmap(); bd->pVB->Unmap();
bd->pIB->Unmap(); bd->pIB->Unmap();
@ -223,24 +224,24 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
}; };
BACKUP_DX10_STATE old = {}; BACKUP_DX10_STATE old = {};
old.ScissorRectsCount = old.ViewportsCount = D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; old.ScissorRectsCount = old.ViewportsCount = D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects); device->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports); device->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS); device->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask); device->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef); device->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource); device->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler); device->PSGetSamplers(0, 1, &old.PSSampler);
ctx->PSGetShader(&old.PS); device->PSGetShader(&old.PS);
ctx->VSGetShader(&old.VS); device->VSGetShader(&old.VS);
ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer); device->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
ctx->GSGetShader(&old.GS); device->GSGetShader(&old.GS);
ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology); device->IAGetPrimitiveTopology(&old.PrimitiveTopology);
ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset); device->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); device->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
ctx->IAGetInputLayout(&old.InputLayout); device->IAGetInputLayout(&old.InputLayout);
// Setup desired DX state // Setup desired DX state
ImGui_ImplDX10_SetupRenderState(draw_data, ctx); ImGui_ImplDX10_SetupRenderState(draw_data, device);
// Render command lists // Render command lists
// (Because we merged all buffers into a single one, we maintain our own offset into them) // (Because we merged all buffers into a single one, we maintain our own offset into them)
@ -249,18 +250,18 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
ImVec2 clip_off = draw_data->DisplayPos; ImVec2 clip_off = draw_data->DisplayPos;
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* draw_list = draw_data->CmdLists[n];
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
{ {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback) if (pcmd->UserCallback)
{ {
// User callback, registered via ImDrawList::AddCallback() // User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplDX10_SetupRenderState(draw_data, ctx); ImGui_ImplDX10_SetupRenderState(draw_data, device);
else else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(draw_list, pcmd);
} }
else else
{ {
@ -272,34 +273,34 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
// Apply scissor/clipping rectangle // Apply scissor/clipping rectangle
const D3D10_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y }; const D3D10_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
ctx->RSSetScissorRects(1, &r); device->RSSetScissorRects(1, &r);
// Bind texture, Draw // Bind texture, Draw
ID3D10ShaderResourceView* texture_srv = (ID3D10ShaderResourceView*)pcmd->GetTexID(); ID3D10ShaderResourceView* texture_srv = (ID3D10ShaderResourceView*)pcmd->GetTexID();
ctx->PSSetShaderResources(0, 1, &texture_srv); device->PSSetShaderResources(0, 1, &texture_srv);
ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset); device->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
} }
} }
global_idx_offset += cmd_list->IdxBuffer.Size; global_idx_offset += draw_list->IdxBuffer.Size;
global_vtx_offset += cmd_list->VtxBuffer.Size; global_vtx_offset += draw_list->VtxBuffer.Size;
} }
// Restore modified DX state // Restore modified DX state
ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects); device->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
ctx->RSSetViewports(old.ViewportsCount, old.Viewports); device->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release(); device->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release(); device->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release(); device->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release(); device->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release(); device->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release(); device->PSSetShader(old.PS); if (old.PS) old.PS->Release();
ctx->VSSetShader(old.VS); if (old.VS) old.VS->Release(); device->VSSetShader(old.VS); if (old.VS) old.VS->Release();
ctx->GSSetShader(old.GS); if (old.GS) old.GS->Release(); device->GSSetShader(old.GS); if (old.GS) old.GS->Release();
ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release(); device->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
ctx->IASetPrimitiveTopology(old.PrimitiveTopology); device->IASetPrimitiveTopology(old.PrimitiveTopology);
ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release(); device->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release(); device->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); device->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
} }
static void ImGui_ImplDX10_CreateFontsTexture() static void ImGui_ImplDX10_CreateFontsTexture()
@ -353,9 +354,9 @@ static void ImGui_ImplDX10_CreateFontsTexture()
D3D10_SAMPLER_DESC desc; D3D10_SAMPLER_DESC desc;
ZeroMemory(&desc, sizeof(desc)); ZeroMemory(&desc, sizeof(desc));
desc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR; desc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR;
desc.AddressU = D3D10_TEXTURE_ADDRESS_WRAP; desc.AddressU = D3D10_TEXTURE_ADDRESS_CLAMP;
desc.AddressV = D3D10_TEXTURE_ADDRESS_WRAP; desc.AddressV = D3D10_TEXTURE_ADDRESS_CLAMP;
desc.AddressW = D3D10_TEXTURE_ADDRESS_WRAP; desc.AddressW = D3D10_TEXTURE_ADDRESS_CLAMP;
desc.MipLODBias = 0.f; desc.MipLODBias = 0.f;
desc.ComparisonFunc = D3D10_COMPARISON_ALWAYS; desc.ComparisonFunc = D3D10_COMPARISON_ALWAYS;
desc.MinLOD = 0.f; desc.MinLOD = 0.f;
@ -565,8 +566,8 @@ bool ImGui_ImplDX10_Init(ID3D10Device* device)
if (pDXGIAdapter) pDXGIAdapter->Release(); if (pDXGIAdapter) pDXGIAdapter->Release();
bd->pd3dDevice->AddRef(); bd->pd3dDevice->AddRef();
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) ImGui_ImplDX10_InitMultiViewportSupport();
ImGui_ImplDX10_InitPlatformInterface();
return true; return true;
} }
@ -576,7 +577,7 @@ void ImGui_ImplDX10_Shutdown()
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?"); IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGui_ImplDX10_ShutdownPlatformInterface(); ImGui_ImplDX10_ShutdownMultiViewportSupport();
ImGui_ImplDX10_InvalidateDeviceObjects(); ImGui_ImplDX10_InvalidateDeviceObjects();
if (bd->pFactory) { bd->pFactory->Release(); } if (bd->pFactory) { bd->pFactory->Release(); }
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); } if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
@ -703,7 +704,7 @@ static void ImGui_ImplDX10_SwapBuffers(ImGuiViewport* viewport, void*)
vd->SwapChain->Present(0, 0); // Present without vsync vd->SwapChain->Present(0, 0); // Present without vsync
} }
void ImGui_ImplDX10_InitPlatformInterface() void ImGui_ImplDX10_InitMultiViewportSupport()
{ {
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
platform_io.Renderer_CreateWindow = ImGui_ImplDX10_CreateWindow; platform_io.Renderer_CreateWindow = ImGui_ImplDX10_CreateWindow;
@ -713,7 +714,7 @@ void ImGui_ImplDX10_InitPlatformInterface()
platform_io.Renderer_SwapBuffers = ImGui_ImplDX10_SwapBuffers; platform_io.Renderer_SwapBuffers = ImGui_ImplDX10_SwapBuffers;
} }
void ImGui_ImplDX10_ShutdownPlatformInterface() void ImGui_ImplDX10_ShutdownMultiViewportSupport()
{ {
ImGui::DestroyPlatformWindows(); ImGui::DestroyPlatformWindows();
} }

View File

@ -27,7 +27,7 @@ IMGUI_IMPL_API void ImGui_ImplDX10_NewFrame();
IMGUI_IMPL_API void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data); IMGUI_IMPL_API void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data);
// Use if you want to reset your rendering device without losing Dear ImGui state. // Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API void ImGui_ImplDX10_InvalidateDeviceObjects();
IMGUI_IMPL_API bool ImGui_ImplDX10_CreateDeviceObjects(); IMGUI_IMPL_API bool ImGui_ImplDX10_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplDX10_InvalidateDeviceObjects();
#endif // #ifndef IMGUI_DISABLE #endif // #ifndef IMGUI_DISABLE

View File

@ -4,6 +4,7 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. // [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
// You can 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.
@ -17,12 +18,14 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2024-10-07: DirectX11: Changed default texture sampler to Clamp instead of Repeat/Wrap.
// 2024-10-07: DirectX11: Expose selected render state in ImGui_ImplDX11_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. // 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
// 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-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-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. // 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-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. // 2019-07-21: DirectX11: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX11_RenderDrawData. Clearing Hull/Domain/Compute shaders without backup/restore.
// 2019-05-29: DirectX11: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. // 2019-05-29: DirectX11: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
// 2019-04-30: DirectX11: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. // 2019-04-30: DirectX11: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile(). // 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile().
@ -83,11 +86,11 @@ static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData()
} }
// Forward Declarations // Forward Declarations
static void ImGui_ImplDX11_InitPlatformInterface(); static void ImGui_ImplDX11_InitMultiViewportSupport();
static void ImGui_ImplDX11_ShutdownPlatformInterface(); static void ImGui_ImplDX11_ShutdownMultiViewportSupport();
// Functions // Functions
static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* ctx) static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* device_ctx)
{ {
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData(); ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
@ -99,29 +102,29 @@ static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceC
vp.MinDepth = 0.0f; vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f; vp.MaxDepth = 1.0f;
vp.TopLeftX = vp.TopLeftY = 0; vp.TopLeftX = vp.TopLeftY = 0;
ctx->RSSetViewports(1, &vp); device_ctx->RSSetViewports(1, &vp);
// Setup shader and vertex buffers // Setup shader and vertex buffers
unsigned int stride = sizeof(ImDrawVert); unsigned int stride = sizeof(ImDrawVert);
unsigned int offset = 0; unsigned int offset = 0;
ctx->IASetInputLayout(bd->pInputLayout); device_ctx->IASetInputLayout(bd->pInputLayout);
ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset); device_ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0); device_ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); device_ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ctx->VSSetShader(bd->pVertexShader, nullptr, 0); device_ctx->VSSetShader(bd->pVertexShader, nullptr, 0);
ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer); device_ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
ctx->PSSetShader(bd->pPixelShader, nullptr, 0); device_ctx->PSSetShader(bd->pPixelShader, nullptr, 0);
ctx->PSSetSamplers(0, 1, &bd->pFontSampler); device_ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
ctx->GSSetShader(nullptr, nullptr, 0); device_ctx->GSSetShader(nullptr, nullptr, 0);
ctx->HSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used.. device_ctx->HSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
ctx->DSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used.. device_ctx->DSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
ctx->CSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used.. device_ctx->CSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
// Setup blend state // Setup blend state
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f }; const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff); device_ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0); device_ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0);
ctx->RSSetState(bd->pRasterizerState); device_ctx->RSSetState(bd->pRasterizerState);
} }
// Render function // Render function
@ -132,7 +135,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
return; return;
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData(); ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
ID3D11DeviceContext* ctx = bd->pd3dDeviceContext; ID3D11DeviceContext* device = bd->pd3dDeviceContext;
// Create and grow vertex/index buffers if needed // Create and grow vertex/index buffers if needed
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount) if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
@ -165,28 +168,28 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
// Upload vertex/index data into a single contiguous GPU buffer // Upload vertex/index data into a single contiguous GPU buffer
D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource; D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource;
if (ctx->Map(bd->pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK) if (device->Map(bd->pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK)
return; return;
if (ctx->Map(bd->pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK) if (device->Map(bd->pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK)
return; return;
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData; ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData;
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData; ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData;
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* draw_list = draw_data->CmdLists[n];
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
vtx_dst += cmd_list->VtxBuffer.Size; vtx_dst += draw_list->VtxBuffer.Size;
idx_dst += cmd_list->IdxBuffer.Size; idx_dst += draw_list->IdxBuffer.Size;
} }
ctx->Unmap(bd->pVB, 0); device->Unmap(bd->pVB, 0);
ctx->Unmap(bd->pIB, 0); device->Unmap(bd->pIB, 0);
// Setup orthographic projection matrix into our constant buffer // 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. // 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; D3D11_MAPPED_SUBRESOURCE mapped_resource;
if (ctx->Map(bd->pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK) if (device->Map(bd->pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
return; return;
VERTEX_CONSTANT_BUFFER_DX11* constant_buffer = (VERTEX_CONSTANT_BUFFER_DX11*)mapped_resource.pData; VERTEX_CONSTANT_BUFFER_DX11* constant_buffer = (VERTEX_CONSTANT_BUFFER_DX11*)mapped_resource.pData;
float L = draw_data->DisplayPos.x; float L = draw_data->DisplayPos.x;
@ -201,7 +204,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f }, { (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
}; };
memcpy(&constant_buffer->mvp, mvp, sizeof(mvp)); memcpy(&constant_buffer->mvp, mvp, sizeof(mvp));
ctx->Unmap(bd->pVertexConstantBuffer, 0); device->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!) // Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
@ -231,26 +234,34 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
}; };
BACKUP_DX11_STATE old = {}; BACKUP_DX11_STATE old = {};
old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects); device->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports); device->RSGetViewports(&old.ViewportsCount, old.Viewports);
ctx->RSGetState(&old.RS); device->RSGetState(&old.RS);
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask); device->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef); device->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource); device->PSGetShaderResources(0, 1, &old.PSShaderResource);
ctx->PSGetSamplers(0, 1, &old.PSSampler); device->PSGetSamplers(0, 1, &old.PSSampler);
old.PSInstancesCount = old.VSInstancesCount = old.GSInstancesCount = 256; old.PSInstancesCount = old.VSInstancesCount = old.GSInstancesCount = 256;
ctx->PSGetShader(&old.PS, old.PSInstances, &old.PSInstancesCount); device->PSGetShader(&old.PS, old.PSInstances, &old.PSInstancesCount);
ctx->VSGetShader(&old.VS, old.VSInstances, &old.VSInstancesCount); device->VSGetShader(&old.VS, old.VSInstances, &old.VSInstancesCount);
ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer); device->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
ctx->GSGetShader(&old.GS, old.GSInstances, &old.GSInstancesCount); device->GSGetShader(&old.GS, old.GSInstances, &old.GSInstancesCount);
ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology); device->IAGetPrimitiveTopology(&old.PrimitiveTopology);
ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset); device->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); device->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
ctx->IAGetInputLayout(&old.InputLayout); device->IAGetInputLayout(&old.InputLayout);
// Setup desired DX state // Setup desired DX state
ImGui_ImplDX11_SetupRenderState(draw_data, ctx); ImGui_ImplDX11_SetupRenderState(draw_data, device);
// Setup render state structure (for callbacks and custom texture bindings)
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
ImGui_ImplDX11_RenderState render_state;
render_state.Device = bd->pd3dDevice;
render_state.DeviceContext = bd->pd3dDeviceContext;
render_state.SamplerDefault = bd->pFontSampler;
platform_io.Renderer_RenderState = &render_state;
// Render command lists // Render command lists
// (Because we merged all buffers into a single one, we maintain our own offset into them) // (Because we merged all buffers into a single one, we maintain our own offset into them)
@ -259,18 +270,18 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
ImVec2 clip_off = draw_data->DisplayPos; ImVec2 clip_off = draw_data->DisplayPos;
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* draw_list = draw_data->CmdLists[n];
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
{ {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback != nullptr) if (pcmd->UserCallback != nullptr)
{ {
// User callback, registered via ImDrawList::AddCallback() // User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplDX11_SetupRenderState(draw_data, ctx); ImGui_ImplDX11_SetupRenderState(draw_data, device);
else else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(draw_list, pcmd);
} }
else else
{ {
@ -282,36 +293,37 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
// Apply scissor/clipping rectangle // Apply scissor/clipping rectangle
const D3D11_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.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); device->RSSetScissorRects(1, &r);
// Bind texture, Draw // Bind texture, Draw
ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->GetTexID(); ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->GetTexID();
ctx->PSSetShaderResources(0, 1, &texture_srv); device->PSSetShaderResources(0, 1, &texture_srv);
ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset); device->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
} }
} }
global_idx_offset += cmd_list->IdxBuffer.Size; global_idx_offset += draw_list->IdxBuffer.Size;
global_vtx_offset += cmd_list->VtxBuffer.Size; global_vtx_offset += draw_list->VtxBuffer.Size;
} }
platform_io.Renderer_RenderState = NULL;
// Restore modified DX state // Restore modified DX state
ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects); device->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
ctx->RSSetViewports(old.ViewportsCount, old.Viewports); device->RSSetViewports(old.ViewportsCount, old.Viewports);
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release(); device->RSSetState(old.RS); if (old.RS) old.RS->Release();
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release(); device->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release(); device->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release(); device->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release(); device->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release(); device->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
for (UINT i = 0; i < old.PSInstancesCount; i++) if (old.PSInstances[i]) old.PSInstances[i]->Release(); for (UINT i = 0; i < old.PSInstancesCount; i++) if (old.PSInstances[i]) old.PSInstances[i]->Release();
ctx->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release(); device->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release();
ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release(); device->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
ctx->GSSetShader(old.GS, old.GSInstances, old.GSInstancesCount); if (old.GS) old.GS->Release(); device->GSSetShader(old.GS, old.GSInstances, old.GSInstancesCount); if (old.GS) old.GS->Release();
for (UINT i = 0; i < old.VSInstancesCount; i++) if (old.VSInstances[i]) old.VSInstances[i]->Release(); for (UINT i = 0; i < old.VSInstancesCount; i++) if (old.VSInstances[i]) old.VSInstances[i]->Release();
ctx->IASetPrimitiveTopology(old.PrimitiveTopology); device->IASetPrimitiveTopology(old.PrimitiveTopology);
ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release(); device->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release(); device->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); device->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
} }
static void ImGui_ImplDX11_CreateFontsTexture() static void ImGui_ImplDX11_CreateFontsTexture()
@ -365,9 +377,9 @@ static void ImGui_ImplDX11_CreateFontsTexture()
D3D11_SAMPLER_DESC desc; D3D11_SAMPLER_DESC desc;
ZeroMemory(&desc, sizeof(desc)); ZeroMemory(&desc, sizeof(desc));
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
desc.MipLODBias = 0.f; desc.MipLODBias = 0.f;
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
desc.MinLOD = 0.f; desc.MinLOD = 0.f;
@ -580,8 +592,7 @@ bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_co
bd->pd3dDevice->AddRef(); bd->pd3dDevice->AddRef();
bd->pd3dDeviceContext->AddRef(); bd->pd3dDeviceContext->AddRef();
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) ImGui_ImplDX11_InitMultiViewportSupport();
ImGui_ImplDX11_InitPlatformInterface();
return true; return true;
} }
@ -592,7 +603,7 @@ void ImGui_ImplDX11_Shutdown()
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?"); IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGui_ImplDX11_ShutdownPlatformInterface(); ImGui_ImplDX11_ShutdownMultiViewportSupport();
ImGui_ImplDX11_InvalidateDeviceObjects(); ImGui_ImplDX11_InvalidateDeviceObjects();
if (bd->pFactory) { bd->pFactory->Release(); } if (bd->pFactory) { bd->pFactory->Release(); }
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); } if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
@ -720,7 +731,7 @@ static void ImGui_ImplDX11_SwapBuffers(ImGuiViewport* viewport, void*)
vd->SwapChain->Present(0, 0); // Present without vsync vd->SwapChain->Present(0, 0); // Present without vsync
} }
static void ImGui_ImplDX11_InitPlatformInterface() static void ImGui_ImplDX11_InitMultiViewportSupport()
{ {
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
platform_io.Renderer_CreateWindow = ImGui_ImplDX11_CreateWindow; platform_io.Renderer_CreateWindow = ImGui_ImplDX11_CreateWindow;
@ -730,7 +741,7 @@ static void ImGui_ImplDX11_InitPlatformInterface()
platform_io.Renderer_SwapBuffers = ImGui_ImplDX11_SwapBuffers; platform_io.Renderer_SwapBuffers = ImGui_ImplDX11_SwapBuffers;
} }
static void ImGui_ImplDX11_ShutdownPlatformInterface() static void ImGui_ImplDX11_ShutdownMultiViewportSupport()
{ {
ImGui::DestroyPlatformWindows(); ImGui::DestroyPlatformWindows();
} }

View File

@ -4,6 +4,7 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. // [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
// You can 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.
@ -20,6 +21,7 @@
struct ID3D11Device; struct ID3D11Device;
struct ID3D11DeviceContext; struct ID3D11DeviceContext;
struct ID3D11SamplerState;
// Follow "Getting Started" link and check examples/ folder to learn about using backends! // Follow "Getting Started" link and check examples/ folder to learn about using backends!
IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context); IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context);
@ -28,7 +30,17 @@ IMGUI_IMPL_API void ImGui_ImplDX11_NewFrame();
IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data); IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data);
// Use if you want to reset your rendering device without losing Dear ImGui state. // Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects(); IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
// [BETA] Selected render state data shared with callbacks.
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplDX11_RenderDrawData() call.
// (Please open an issue if you feel you need access to more data)
struct ImGui_ImplDX11_RenderState
{
ID3D11Device* Device;
ID3D11DeviceContext* DeviceContext;
ID3D11SamplerState* SamplerDefault;
};
#endif // #ifndef IMGUI_DISABLE #endif // #ifndef IMGUI_DISABLE

View File

@ -4,17 +4,10 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. // [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
// FIXME: The transition from removing a viewport and moving the window in an existing hosted viewport tends to flicker. // FIXME: The transition from removing a viewport and moving the window in an existing hosted viewport tends to flicker.
// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
// To build this on 32-bit systems:
// - [Solution 1] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'ImTextureID=ImU64' (this is what we do in the 'example_win32_direct12/example_win32_direct12.vcxproj' project file)
// - [Solution 2] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'IMGUI_USER_CONFIG="my_imgui_config.h"' and inside 'my_imgui_config.h' add '#define ImTextureID ImU64' and as many other options as you like.
// - [Solution 3] IDE/msbuild: edit imconfig.h and add '#define ImTextureID ImU64' (prefer solution 2 to create your own config file!)
// - [Solution 4] command-line: add '/D ImTextureID=ImU64' to your cl.exe command-line (this is what we do in the example_win32_direct12/build_win32.bat file)
// You can 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. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// Learn about Dear ImGui: // Learn about Dear ImGui:
@ -26,6 +19,10 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2024-10-23: DirectX12: Unmap() call specify written range. The range is informational and may be used by debug tools.
// 2024-10-07: DirectX12: Changed default texture sampler to Clamp instead of Repeat/Wrap.
// 2024-10-07: DirectX12: Expose selected render state in ImGui_ImplDX12_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
// 2024-10-07: DirectX12: Compiling with '#define ImTextureID=ImU64' is unnecessary now that dear imgui defaults ImTextureID to u64 instead of void*.
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. // 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
// 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-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: DirectX12: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) // 2021-05-19: DirectX12: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
@ -171,7 +168,7 @@ static void ImGui_ImplDX12_InitPlatformInterface();
static void ImGui_ImplDX12_ShutdownPlatformInterface(); static void ImGui_ImplDX12_ShutdownPlatformInterface();
// Functions // Functions
static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx, ImGui_ImplDX12_RenderBuffers* fr) static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12GraphicsCommandList* command_list, ImGui_ImplDX12_RenderBuffers* fr)
{ {
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData(); ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
@ -201,7 +198,7 @@ static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12Graphic
vp.MinDepth = 0.0f; vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f; vp.MaxDepth = 1.0f;
vp.TopLeftX = vp.TopLeftY = 0.0f; vp.TopLeftX = vp.TopLeftY = 0.0f;
ctx->RSSetViewports(1, &vp); command_list->RSSetViewports(1, &vp);
// Bind shader and vertex buffers // Bind shader and vertex buffers
unsigned int stride = sizeof(ImDrawVert); unsigned int stride = sizeof(ImDrawVert);
@ -211,21 +208,21 @@ static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12Graphic
vbv.BufferLocation = fr->VertexBuffer->GetGPUVirtualAddress() + offset; vbv.BufferLocation = fr->VertexBuffer->GetGPUVirtualAddress() + offset;
vbv.SizeInBytes = fr->VertexBufferSize * stride; vbv.SizeInBytes = fr->VertexBufferSize * stride;
vbv.StrideInBytes = stride; vbv.StrideInBytes = stride;
ctx->IASetVertexBuffers(0, 1, &vbv); command_list->IASetVertexBuffers(0, 1, &vbv);
D3D12_INDEX_BUFFER_VIEW ibv; D3D12_INDEX_BUFFER_VIEW ibv;
memset(&ibv, 0, sizeof(D3D12_INDEX_BUFFER_VIEW)); memset(&ibv, 0, sizeof(D3D12_INDEX_BUFFER_VIEW));
ibv.BufferLocation = fr->IndexBuffer->GetGPUVirtualAddress(); ibv.BufferLocation = fr->IndexBuffer->GetGPUVirtualAddress();
ibv.SizeInBytes = fr->IndexBufferSize * sizeof(ImDrawIdx); ibv.SizeInBytes = fr->IndexBufferSize * sizeof(ImDrawIdx);
ibv.Format = sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT; ibv.Format = sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT;
ctx->IASetIndexBuffer(&ibv); command_list->IASetIndexBuffer(&ibv);
ctx->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); command_list->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
ctx->SetPipelineState(bd->pPipelineState); command_list->SetPipelineState(bd->pPipelineState);
ctx->SetGraphicsRootSignature(bd->pRootSignature); command_list->SetGraphicsRootSignature(bd->pRootSignature);
ctx->SetGraphicsRoot32BitConstants(0, 16, &vertex_constant_buffer, 0); command_list->SetGraphicsRoot32BitConstants(0, 16, &vertex_constant_buffer, 0);
// Setup blend factor // Setup blend factor
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f }; const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
ctx->OMSetBlendFactor(blend_factor); command_list->OMSetBlendFactor(blend_factor);
} }
template<typename T> template<typename T>
@ -237,7 +234,7 @@ static inline void SafeRelease(T*& res)
} }
// Render function // Render function
void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx) void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* command_list)
{ {
// Avoid rendering when minimized // Avoid rendering when minimized
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f) if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
@ -297,9 +294,9 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
} }
// Upload vertex/index data into a single contiguous GPU buffer // Upload vertex/index data into a single contiguous GPU buffer
// During Map() we specify a null read range (as per DX12 API, this is informational and for tooling only)
void* vtx_resource, *idx_resource; void* vtx_resource, *idx_resource;
D3D12_RANGE range; D3D12_RANGE range = { 0, 0 };
memset(&range, 0, sizeof(D3D12_RANGE));
if (fr->VertexBuffer->Map(0, &range, &vtx_resource) != S_OK) if (fr->VertexBuffer->Map(0, &range, &vtx_resource) != S_OK)
return; return;
if (fr->IndexBuffer->Map(0, &range, &idx_resource) != S_OK) if (fr->IndexBuffer->Map(0, &range, &idx_resource) != S_OK)
@ -308,17 +305,30 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource; ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource;
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* draw_list = draw_data->CmdLists[n];
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
vtx_dst += cmd_list->VtxBuffer.Size; vtx_dst += draw_list->VtxBuffer.Size;
idx_dst += cmd_list->IdxBuffer.Size; idx_dst += draw_list->IdxBuffer.Size;
} }
// During Unmap() we specify the written range (as per DX12 API, this is informational and for tooling only)
range.End = (SIZE_T)((intptr_t)vtx_dst - (intptr_t)vtx_resource);
IM_ASSERT(range.End == draw_data->TotalVtxCount * sizeof(ImDrawVert));
fr->VertexBuffer->Unmap(0, &range); fr->VertexBuffer->Unmap(0, &range);
range.End = (SIZE_T)((intptr_t)idx_dst - (intptr_t)idx_resource);
IM_ASSERT(range.End == draw_data->TotalIdxCount * sizeof(ImDrawIdx));
fr->IndexBuffer->Unmap(0, &range); fr->IndexBuffer->Unmap(0, &range);
// Setup desired DX state // Setup desired DX state
ImGui_ImplDX12_SetupRenderState(draw_data, ctx, fr); ImGui_ImplDX12_SetupRenderState(draw_data, command_list, fr);
// Setup render state structure (for callbacks and custom texture bindings)
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
ImGui_ImplDX12_RenderState render_state;
render_state.Device = bd->pd3dDevice;
render_state.CommandList = command_list;
platform_io.Renderer_RenderState = &render_state;
// Render command lists // Render command lists
// (Because we merged all buffers into a single one, we maintain our own offset into them) // (Because we merged all buffers into a single one, we maintain our own offset into them)
@ -327,18 +337,18 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
ImVec2 clip_off = draw_data->DisplayPos; ImVec2 clip_off = draw_data->DisplayPos;
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* draw_list = draw_data->CmdLists[n];
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
{ {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback != nullptr) if (pcmd->UserCallback != nullptr)
{ {
// User callback, registered via ImDrawList::AddCallback() // User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplDX12_SetupRenderState(draw_data, ctx, fr); ImGui_ImplDX12_SetupRenderState(draw_data, command_list, fr);
else else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(draw_list, pcmd);
} }
else else
{ {
@ -348,18 +358,21 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
continue; continue;
// Apply Scissor/clipping rectangle, Bind texture, Draw // Apply scissor/clipping rectangle
const D3D12_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y }; const D3D12_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
command_list->RSSetScissorRects(1, &r);
// Bind texture, Draw
D3D12_GPU_DESCRIPTOR_HANDLE texture_handle = {}; D3D12_GPU_DESCRIPTOR_HANDLE texture_handle = {};
texture_handle.ptr = (UINT64)pcmd->GetTexID(); texture_handle.ptr = (UINT64)pcmd->GetTexID();
ctx->SetGraphicsRootDescriptorTable(1, texture_handle); command_list->SetGraphicsRootDescriptorTable(1, texture_handle);
ctx->RSSetScissorRects(1, &r); command_list->DrawIndexedInstanced(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
ctx->DrawIndexedInstanced(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
} }
} }
global_idx_offset += cmd_list->IdxBuffer.Size; global_idx_offset += draw_list->IdxBuffer.Size;
global_vtx_offset += cmd_list->VtxBuffer.Size; global_vtx_offset += draw_list->VtxBuffer.Size;
} }
platform_io.Renderer_RenderState = NULL;
} }
static void ImGui_ImplDX12_CreateFontsTexture() static void ImGui_ImplDX12_CreateFontsTexture()
@ -508,14 +521,6 @@ static void ImGui_ImplDX12_CreateFontsTexture()
} }
// Store our identifier // Store our identifier
// READ THIS IF THE STATIC_ASSERT() TRIGGERS:
// - Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
// - This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
// [Solution 1] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'ImTextureID=ImU64' (this is what we do in the 'example_win32_direct12/example_win32_direct12.vcxproj' project file)
// [Solution 2] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'IMGUI_USER_CONFIG="my_imgui_config.h"' and inside 'my_imgui_config.h' add '#define ImTextureID ImU64' and as many other options as you like.
// [Solution 3] IDE/msbuild: edit imconfig.h and add '#define ImTextureID ImU64' (prefer solution 2 to create your own config file!)
// [Solution 4] command-line: add '/D ImTextureID=ImU64' to your cl.exe command-line (this is what we do in the example_win32_direct12/build_win32.bat file)
static_assert(sizeof(ImTextureID) >= sizeof(bd->hFontSrvGpuDescHandle.ptr), "Can't pack descriptor handle into TexID, 32-bit not supported yet.");
io.Fonts->SetTexID((ImTextureID)bd->hFontSrvGpuDescHandle.ptr); io.Fonts->SetTexID((ImTextureID)bd->hFontSrvGpuDescHandle.ptr);
} }
@ -552,9 +557,9 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
// Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling. // Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling.
D3D12_STATIC_SAMPLER_DESC staticSampler = {}; D3D12_STATIC_SAMPLER_DESC staticSampler = {};
staticSampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; staticSampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
staticSampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; staticSampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
staticSampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; staticSampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
staticSampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; staticSampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
staticSampler.MipLODBias = 0.f; staticSampler.MipLODBias = 0.f;
staticSampler.MaxAnisotropy = 0; staticSampler.MaxAnisotropy = 0;
staticSampler.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS; staticSampler.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;

View File

@ -4,11 +4,9 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. // [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
// See imgui_impl_dx12.cpp file for details.
// You can 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. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
// Learn about Dear ImGui: // Learn about Dear ImGui:
@ -30,8 +28,7 @@ struct D3D12_GPU_DESCRIPTOR_HANDLE;
// Follow "Getting Started" link and check examples/ folder to learn about using backends! // Follow "Getting Started" link and check examples/ folder to learn about using backends!
// cmd_list is the command list that the implementation will use to render imgui draw lists. // Before calling the render function, caller must prepare the command list by resetting it and setting the appropriate
// Before calling the render function, caller must prepare cmd_list by resetting it and setting the appropriate
// render target and descriptor heap that contains font_srv_cpu_desc_handle/font_srv_gpu_desc_handle. // render target and descriptor heap that contains font_srv_cpu_desc_handle/font_srv_gpu_desc_handle.
// font_srv_cpu_desc_handle and font_srv_gpu_desc_handle are handles to a single SRV descriptor to use for the internal font texture. // font_srv_cpu_desc_handle and font_srv_gpu_desc_handle are handles to a single SRV descriptor to use for the internal font texture.
IMGUI_IMPL_API bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* cbv_srv_heap, IMGUI_IMPL_API bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* cbv_srv_heap,
@ -41,7 +38,16 @@ IMGUI_IMPL_API void ImGui_ImplDX12_NewFrame();
IMGUI_IMPL_API void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* graphics_command_list); IMGUI_IMPL_API void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* graphics_command_list);
// Use if you want to reset your rendering device without losing Dear ImGui state. // Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API void ImGui_ImplDX12_InvalidateDeviceObjects();
IMGUI_IMPL_API bool ImGui_ImplDX12_CreateDeviceObjects(); IMGUI_IMPL_API bool ImGui_ImplDX12_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplDX12_InvalidateDeviceObjects();
// [BETA] Selected render state data shared with callbacks.
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplDX12_RenderDrawData() call.
// (Please open an issue if you feel you need access to more data)
struct ImGui_ImplDX12_RenderState
{
ID3D12Device* Device;
ID3D12GraphicsCommandList* CommandList;
};
#endif // #ifndef IMGUI_DISABLE #endif // #ifndef IMGUI_DISABLE

View File

@ -17,6 +17,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2024-10-07: DirectX9: Changed default texture sampler to Clamp instead of Repeat/Wrap.
// 2024-02-12: DirectX9: Using RGBA format when supported by the driver to avoid CPU side conversion. (#6575) // 2024-02-12: DirectX9: Using RGBA format when supported by the driver to avoid CPU side conversion. (#6575)
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. // 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
// 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-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).
@ -79,8 +80,8 @@ static ImGui_ImplDX9_Data* ImGui_ImplDX9_GetBackendData()
} }
// Forward Declarations // Forward Declarations
static void ImGui_ImplDX9_InitPlatformInterface(); static void ImGui_ImplDX9_InitMultiViewportSupport();
static void ImGui_ImplDX9_ShutdownPlatformInterface(); static void ImGui_ImplDX9_ShutdownMultiViewportSupport();
static void ImGui_ImplDX9_CreateDeviceObjectsForPlatformWindows(); static void ImGui_ImplDX9_CreateDeviceObjectsForPlatformWindows();
static void ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows(); static void ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows();
@ -96,41 +97,45 @@ static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data)
vp.Height = (DWORD)draw_data->DisplaySize.y; vp.Height = (DWORD)draw_data->DisplaySize.y;
vp.MinZ = 0.0f; vp.MinZ = 0.0f;
vp.MaxZ = 1.0f; vp.MaxZ = 1.0f;
bd->pd3dDevice->SetViewport(&vp);
LPDIRECT3DDEVICE9 device = bd->pd3dDevice;
device->SetViewport(&vp);
// Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing, shade mode (for gradient), bilinear sampling. // Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing, shade mode (for gradient), bilinear sampling.
bd->pd3dDevice->SetPixelShader(nullptr); device->SetPixelShader(nullptr);
bd->pd3dDevice->SetVertexShader(nullptr); device->SetVertexShader(nullptr);
bd->pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
bd->pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
bd->pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
bd->pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
bd->pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
bd->pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE); device->SetRenderState(D3DRS_ZENABLE, FALSE);
bd->pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
bd->pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
bd->pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
bd->pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
bd->pd3dDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
bd->pd3dDevice->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE); device->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE);
bd->pd3dDevice->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA); device->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA);
bd->pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
bd->pd3dDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); device->SetRenderState(D3DRS_FOGENABLE, FALSE);
bd->pd3dDevice->SetRenderState(D3DRS_RANGEFOGENABLE, FALSE); device->SetRenderState(D3DRS_RANGEFOGENABLE, FALSE);
bd->pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE); device->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
bd->pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
bd->pd3dDevice->SetRenderState(D3DRS_CLIPPING, TRUE); device->SetRenderState(D3DRS_CLIPPING, TRUE);
bd->pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE); device->SetRenderState(D3DRS_LIGHTING, FALSE);
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
bd->pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
bd->pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); device->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
// Setup orthographic projection matrix // Setup orthographic projection matrix
// 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. // 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.
@ -148,9 +153,9 @@ static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data)
0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f,
(L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f (L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f
} } }; } } };
bd->pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity); device->SetTransform(D3DTS_WORLD, &mat_identity);
bd->pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity); device->SetTransform(D3DTS_VIEW, &mat_identity);
bd->pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection); device->SetTransform(D3DTS_PROJECTION, &mat_projection);
} }
} }
@ -161,51 +166,53 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f) if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
return; return;
// Create and grow buffers if needed
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData(); ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
LPDIRECT3DDEVICE9 device = bd->pd3dDevice;
// Create and grow buffers if needed
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount) if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
{ {
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; } if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000; bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
if (bd->pd3dDevice->CreateVertexBuffer(bd->VertexBufferSize * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &bd->pVB, nullptr) < 0) if (device->CreateVertexBuffer(bd->VertexBufferSize * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &bd->pVB, nullptr) < 0)
return; return;
} }
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount) if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
{ {
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; } if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000; bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
if (bd->pd3dDevice->CreateIndexBuffer(bd->IndexBufferSize * sizeof(ImDrawIdx), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, sizeof(ImDrawIdx) == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32, D3DPOOL_DEFAULT, &bd->pIB, nullptr) < 0) if (device->CreateIndexBuffer(bd->IndexBufferSize * sizeof(ImDrawIdx), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, sizeof(ImDrawIdx) == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32, D3DPOOL_DEFAULT, &bd->pIB, nullptr) < 0)
return; return;
} }
// Backup the DX9 state // Backup the DX9 state
IDirect3DStateBlock9* d3d9_state_block = nullptr; IDirect3DStateBlock9* state_block = nullptr;
if (bd->pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0) if (device->CreateStateBlock(D3DSBT_ALL, &state_block) < 0)
return; return;
if (d3d9_state_block->Capture() < 0) if (state_block->Capture() < 0)
{ {
d3d9_state_block->Release(); state_block->Release();
return; return;
} }
// Backup the DX9 transform (DX9 documentation suggests that it is included in the StateBlock but it doesn't appear to) // Backup the DX9 transform (DX9 documentation suggests that it is included in the StateBlock but it doesn't appear to)
D3DMATRIX last_world, last_view, last_projection; D3DMATRIX last_world, last_view, last_projection;
bd->pd3dDevice->GetTransform(D3DTS_WORLD, &last_world); device->GetTransform(D3DTS_WORLD, &last_world);
bd->pd3dDevice->GetTransform(D3DTS_VIEW, &last_view); device->GetTransform(D3DTS_VIEW, &last_view);
bd->pd3dDevice->GetTransform(D3DTS_PROJECTION, &last_projection); device->GetTransform(D3DTS_PROJECTION, &last_projection);
// Allocate buffers // Allocate buffers
CUSTOMVERTEX* vtx_dst; CUSTOMVERTEX* vtx_dst;
ImDrawIdx* idx_dst; ImDrawIdx* idx_dst;
if (bd->pVB->Lock(0, (UINT)(draw_data->TotalVtxCount * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0) if (bd->pVB->Lock(0, (UINT)(draw_data->TotalVtxCount * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0)
{ {
d3d9_state_block->Release(); state_block->Release();
return; return;
} }
if (bd->pIB->Lock(0, (UINT)(draw_data->TotalIdxCount * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0) if (bd->pIB->Lock(0, (UINT)(draw_data->TotalIdxCount * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0)
{ {
bd->pVB->Unlock(); bd->pVB->Unlock();
d3d9_state_block->Release(); state_block->Release();
return; return;
} }
@ -215,9 +222,9 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
// 2) to avoid repacking vertices: #define IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT struct ImDrawVert { ImVec2 pos; float z; ImU32 col; ImVec2 uv; } // 2) to avoid repacking vertices: #define IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT struct ImDrawVert { ImVec2 pos; float z; ImU32 col; ImVec2 uv; }
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* draw_list = draw_data->CmdLists[n];
const ImDrawVert* vtx_src = cmd_list->VtxBuffer.Data; const ImDrawVert* vtx_src = draw_list->VtxBuffer.Data;
for (int i = 0; i < cmd_list->VtxBuffer.Size; i++) for (int i = 0; i < draw_list->VtxBuffer.Size; i++)
{ {
vtx_dst->pos[0] = vtx_src->pos.x; vtx_dst->pos[0] = vtx_src->pos.x;
vtx_dst->pos[1] = vtx_src->pos.y; vtx_dst->pos[1] = vtx_src->pos.y;
@ -228,14 +235,14 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
vtx_dst++; vtx_dst++;
vtx_src++; vtx_src++;
} }
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
idx_dst += cmd_list->IdxBuffer.Size; idx_dst += draw_list->IdxBuffer.Size;
} }
bd->pVB->Unlock(); bd->pVB->Unlock();
bd->pIB->Unlock(); bd->pIB->Unlock();
bd->pd3dDevice->SetStreamSource(0, bd->pVB, 0, sizeof(CUSTOMVERTEX)); device->SetStreamSource(0, bd->pVB, 0, sizeof(CUSTOMVERTEX));
bd->pd3dDevice->SetIndices(bd->pIB); device->SetIndices(bd->pIB);
bd->pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX); device->SetFVF(D3DFVF_CUSTOMVERTEX);
// Setup desired DX state // Setup desired DX state
ImGui_ImplDX9_SetupRenderState(draw_data); ImGui_ImplDX9_SetupRenderState(draw_data);
@ -247,10 +254,10 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
ImVec2 clip_off = draw_data->DisplayPos; ImVec2 clip_off = draw_data->DisplayPos;
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* draw_list = draw_data->CmdLists[n];
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
{ {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback != nullptr) if (pcmd->UserCallback != nullptr)
{ {
// User callback, registered via ImDrawList::AddCallback() // User callback, registered via ImDrawList::AddCallback()
@ -258,7 +265,7 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplDX9_SetupRenderState(draw_data); ImGui_ImplDX9_SetupRenderState(draw_data);
else else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(draw_list, pcmd);
} }
else else
{ {
@ -268,16 +275,18 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
continue; continue;
// Apply Scissor/clipping rectangle, Bind texture, Draw // Apply scissor/clipping rectangle
const RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y }; const RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
device->SetScissorRect(&r);
// Bind texture, Draw
const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->GetTexID(); const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->GetTexID();
bd->pd3dDevice->SetTexture(0, texture); device->SetTexture(0, texture);
bd->pd3dDevice->SetScissorRect(&r); device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, pcmd->VtxOffset + global_vtx_offset, 0, (UINT)draw_list->VtxBuffer.Size, pcmd->IdxOffset + global_idx_offset, pcmd->ElemCount / 3);
bd->pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, pcmd->VtxOffset + global_vtx_offset, 0, (UINT)cmd_list->VtxBuffer.Size, pcmd->IdxOffset + global_idx_offset, pcmd->ElemCount / 3);
} }
} }
global_idx_offset += cmd_list->IdxBuffer.Size; global_idx_offset += draw_list->IdxBuffer.Size;
global_vtx_offset += cmd_list->VtxBuffer.Size; global_vtx_offset += draw_list->VtxBuffer.Size;
} }
// When using multi-viewports, it appears that there's an odd logic in DirectX9 which prevent subsequent windows // When using multi-viewports, it appears that there's an odd logic in DirectX9 which prevent subsequent windows
@ -286,13 +295,13 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
bd->pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 0, 0, 0); bd->pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 0, 0, 0);
// Restore the DX9 transform // Restore the DX9 transform
bd->pd3dDevice->SetTransform(D3DTS_WORLD, &last_world); device->SetTransform(D3DTS_WORLD, &last_world);
bd->pd3dDevice->SetTransform(D3DTS_VIEW, &last_view); device->SetTransform(D3DTS_VIEW, &last_view);
bd->pd3dDevice->SetTransform(D3DTS_PROJECTION, &last_projection); device->SetTransform(D3DTS_PROJECTION, &last_projection);
// Restore the DX9 state // Restore the DX9 state
d3d9_state_block->Apply(); state_block->Apply();
d3d9_state_block->Release(); state_block->Release();
} }
bool ImGui_ImplDX9_Init(IDirect3DDevice9* device) bool ImGui_ImplDX9_Init(IDirect3DDevice9* device)
@ -311,8 +320,7 @@ bool ImGui_ImplDX9_Init(IDirect3DDevice9* device)
bd->pd3dDevice = device; bd->pd3dDevice = device;
bd->pd3dDevice->AddRef(); bd->pd3dDevice->AddRef();
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) ImGui_ImplDX9_InitMultiViewportSupport();
ImGui_ImplDX9_InitPlatformInterface();
return true; return true;
} }
@ -323,7 +331,7 @@ void ImGui_ImplDX9_Shutdown()
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?"); IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGui_ImplDX9_ShutdownPlatformInterface(); ImGui_ImplDX9_ShutdownMultiViewportSupport();
ImGui_ImplDX9_InvalidateDeviceObjects(); ImGui_ImplDX9_InvalidateDeviceObjects();
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); } if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
io.BackendRendererName = nullptr; io.BackendRendererName = nullptr;
@ -537,7 +545,7 @@ static void ImGui_ImplDX9_SwapBuffers(ImGuiViewport* viewport, void*)
IM_ASSERT(SUCCEEDED(hr) || hr == D3DERR_DEVICELOST); IM_ASSERT(SUCCEEDED(hr) || hr == D3DERR_DEVICELOST);
} }
static void ImGui_ImplDX9_InitPlatformInterface() static void ImGui_ImplDX9_InitMultiViewportSupport()
{ {
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
platform_io.Renderer_CreateWindow = ImGui_ImplDX9_CreateWindow; platform_io.Renderer_CreateWindow = ImGui_ImplDX9_CreateWindow;
@ -547,7 +555,7 @@ static void ImGui_ImplDX9_InitPlatformInterface()
platform_io.Renderer_SwapBuffers = ImGui_ImplDX9_SwapBuffers; platform_io.Renderer_SwapBuffers = ImGui_ImplDX9_SwapBuffers;
} }
static void ImGui_ImplDX9_ShutdownPlatformInterface() static void ImGui_ImplDX9_ShutdownMultiViewportSupport()
{ {
ImGui::DestroyPlatformWindows(); ImGui::DestroyPlatformWindows();
} }

View File

@ -6,7 +6,7 @@
// Implemented features: // Implemented features:
// [X] Platform: Clipboard support. // [X] Platform: Clipboard support.
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen (Windows only). // [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen (Windows only).
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. // [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+). // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. // [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
@ -29,6 +29,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2024-11-05: [Docking] Added Linux workaround for spurious mouse up events emitted while dragging and creating new viewport. (#3158, #7733, #7922)
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO: // 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn // - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
// - io.SetClipboardTextFn -> platform_io.Platform_SetClipboardTextFn // - io.SetClipboardTextFn -> platform_io.Platform_SetClipboardTextFn
@ -172,6 +173,8 @@ struct ImGui_ImplGlfw_Data
double Time; double Time;
GLFWwindow* MouseWindow; GLFWwindow* MouseWindow;
GLFWcursor* MouseCursors[ImGuiMouseCursor_COUNT]; GLFWcursor* MouseCursors[ImGuiMouseCursor_COUNT];
bool MouseIgnoreButtonUpWaitForFocusLoss;
bool MouseIgnoreButtonUp;
ImVec2 LastValidMousePos; ImVec2 LastValidMousePos;
GLFWwindow* KeyOwnerWindows[GLFW_KEY_LAST]; GLFWwindow* KeyOwnerWindows[GLFW_KEY_LAST];
bool InstalledCallbacks; bool InstalledCallbacks;
@ -211,13 +214,17 @@ static ImGui_ImplGlfw_Data* ImGui_ImplGlfw_GetBackendData()
// Forward Declarations // Forward Declarations
static void ImGui_ImplGlfw_UpdateMonitors(); static void ImGui_ImplGlfw_UpdateMonitors();
static void ImGui_ImplGlfw_InitPlatformInterface(); static void ImGui_ImplGlfw_InitMultiViewportSupport();
static void ImGui_ImplGlfw_ShutdownPlatformInterface(); static void ImGui_ImplGlfw_ShutdownMultiViewportSupport();
// Functions // Functions
static ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int key)
// Not static to allow third-party code to use that if they want to (but undocumented)
ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int keycode, int scancode);
ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int keycode, int scancode)
{ {
switch (key) IM_UNUSED(scancode);
switch (keycode)
{ {
case GLFW_KEY_TAB: return ImGuiKey_Tab; case GLFW_KEY_TAB: return ImGuiKey_Tab;
case GLFW_KEY_LEFT: return ImGuiKey_LeftArrow; case GLFW_KEY_LEFT: return ImGuiKey_LeftArrow;
@ -363,6 +370,10 @@ void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int acti
if (bd->PrevUserCallbackMousebutton != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window)) if (bd->PrevUserCallbackMousebutton != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
bd->PrevUserCallbackMousebutton(window, button, action, mods); bd->PrevUserCallbackMousebutton(window, button, action, mods);
// Workaround for Linux: ignore mouse up events which are following an focus loss following a viewport creation
if (bd->MouseIgnoreButtonUp && action == GLFW_RELEASE)
return;
ImGui_ImplGlfw_UpdateKeyModifiers(window); ImGui_ImplGlfw_UpdateKeyModifiers(window);
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
@ -385,6 +396,7 @@ void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yo
io.AddMouseWheelEvent((float)xoffset, (float)yoffset); io.AddMouseWheelEvent((float)xoffset, (float)yoffset);
} }
// FIXME: should this be baked into ImGui_ImplGlfw_KeyToImGuiKey()? then what about the values passed to io.SetKeyEventNativeData()?
static int ImGui_ImplGlfw_TranslateUntranslatedKey(int key, int scancode) static int ImGui_ImplGlfw_TranslateUntranslatedKey(int key, int scancode)
{ {
#if GLFW_HAS_GETKEYNAME && !defined(EMSCRIPTEN_USE_EMBEDDED_GLFW3) #if GLFW_HAS_GETKEYNAME && !defined(EMSCRIPTEN_USE_EMBEDDED_GLFW3)
@ -435,7 +447,7 @@ void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int keycode, int scancode, i
keycode = ImGui_ImplGlfw_TranslateUntranslatedKey(keycode, scancode); keycode = ImGui_ImplGlfw_TranslateUntranslatedKey(keycode, scancode);
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGuiKey imgui_key = ImGui_ImplGlfw_KeyToImGuiKey(keycode); ImGuiKey imgui_key = ImGui_ImplGlfw_KeyToImGuiKey(keycode, scancode);
io.AddKeyEvent(imgui_key, (action == GLFW_PRESS)); io.AddKeyEvent(imgui_key, (action == GLFW_PRESS));
io.SetKeyEventNativeData(imgui_key, keycode, scancode); // To support legacy indexing (<1.87 user code) io.SetKeyEventNativeData(imgui_key, keycode, scancode); // To support legacy indexing (<1.87 user code)
} }
@ -446,6 +458,10 @@ void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused)
if (bd->PrevUserCallbackWindowFocus != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window)) if (bd->PrevUserCallbackWindowFocus != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
bd->PrevUserCallbackWindowFocus(window, focused); bd->PrevUserCallbackWindowFocus(window, focused);
// Workaround for Linux: when losing focus with MouseIgnoreButtonUpWaitForFocusLoss set, we will temporarily ignore subsequent Mouse Up events
bd->MouseIgnoreButtonUp = (bd->MouseIgnoreButtonUpWaitForFocusLoss && focused == 0);
bd->MouseIgnoreButtonUpWaitForFocusLoss = false;
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.AddFocusEvent(focused != 0); io.AddFocusEvent(focused != 0);
} }
@ -649,7 +665,8 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
if (install_callbacks) if (install_callbacks)
ImGui_ImplGlfw_InstallCallbacks(window); ImGui_ImplGlfw_InstallCallbacks(window);
// Update monitors the first time (note: monitor callback are broken in GLFW 3.2 and earlier, see github.com/glfw/glfw/issues/784) // Update monitor a first time during init
// (note: monitor callback are broken in GLFW 3.2 and earlier, see github.com/glfw/glfw/issues/784)
ImGui_ImplGlfw_UpdateMonitors(); ImGui_ImplGlfw_UpdateMonitors();
glfwSetMonitorCallback(ImGui_ImplGlfw_MonitorCallback); glfwSetMonitorCallback(ImGui_ImplGlfw_MonitorCallback);
@ -663,8 +680,7 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
#else #else
IM_UNUSED(main_viewport); IM_UNUSED(main_viewport);
#endif #endif
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) ImGui_ImplGlfw_InitMultiViewportSupport();
ImGui_ImplGlfw_InitPlatformInterface();
// Windows: register a WndProc hook so we can intercept some messages. // Windows: register a WndProc hook so we can intercept some messages.
#ifdef _WIN32 #ifdef _WIN32
@ -715,7 +731,7 @@ void ImGui_ImplGlfw_Shutdown()
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?"); IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGui_ImplGlfw_ShutdownPlatformInterface(); ImGui_ImplGlfw_ShutdownMultiViewportSupport();
if (bd->InstalledCallbacks) if (bd->InstalledCallbacks)
ImGui_ImplGlfw_RestoreCallbacks(bd->Window); ImGui_ImplGlfw_RestoreCallbacks(bd->Window);
@ -760,7 +776,7 @@ static void ImGui_ImplGlfw_UpdateMouseData()
#endif #endif
if (is_window_focused) if (is_window_focused)
{ {
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
// When multi-viewports are enabled, all Dear ImGui positions are same as OS positions. // When multi-viewports are enabled, all Dear ImGui positions are same as OS positions.
if (io.WantSetMousePos) if (io.WantSetMousePos)
glfwSetCursorPos(window, (double)(mouse_pos_prev.x - viewport->Pos.x), (double)(mouse_pos_prev.y - viewport->Pos.y)); glfwSetCursorPos(window, (double)(mouse_pos_prev.x - viewport->Pos.x), (double)(mouse_pos_prev.y - viewport->Pos.y));
@ -960,6 +976,7 @@ void ImGui_ImplGlfw_NewFrame()
io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f); io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f);
bd->Time = current_time; bd->Time = current_time;
bd->MouseIgnoreButtonUp = false;
ImGui_ImplGlfw_UpdateMouseData(); ImGui_ImplGlfw_UpdateMouseData();
ImGui_ImplGlfw_UpdateMouseCursor(); ImGui_ImplGlfw_UpdateMouseCursor();
@ -1099,6 +1116,11 @@ static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport)
ImGui_ImplGlfw_ViewportData* vd = IM_NEW(ImGui_ImplGlfw_ViewportData)(); ImGui_ImplGlfw_ViewportData* vd = IM_NEW(ImGui_ImplGlfw_ViewportData)();
viewport->PlatformUserData = vd; viewport->PlatformUserData = vd;
// Workaround for Linux: ignore mouse up events corresponding to losing focus of the previously focused window (#7733, #3158, #7922)
#ifdef __linux__
bd->MouseIgnoreButtonUpWaitForFocusLoss = true;
#endif
// GLFW 3.2 unfortunately always set focus on glfwCreateWindow() if GLFW_VISIBLE is set, regardless of GLFW_FOCUSED // GLFW 3.2 unfortunately always set focus on glfwCreateWindow() if GLFW_VISIBLE is set, regardless of GLFW_FOCUSED
// With GLFW 3.3, the hint GLFW_FOCUS_ON_SHOW fixes this problem // With GLFW 3.3, the hint GLFW_FOCUS_ON_SHOW fixes this problem
glfwWindowHint(GLFW_VISIBLE, false); glfwWindowHint(GLFW_VISIBLE, false);
@ -1329,7 +1351,7 @@ static int ImGui_ImplGlfw_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_inst
} }
#endif // GLFW_HAS_VULKAN #endif // GLFW_HAS_VULKAN
static void ImGui_ImplGlfw_InitPlatformInterface() static void ImGui_ImplGlfw_InitMultiViewportSupport()
{ {
// Register platform interface (will be coupled with a renderer interface) // Register platform interface (will be coupled with a renderer interface)
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
@ -1364,7 +1386,7 @@ static void ImGui_ImplGlfw_InitPlatformInterface()
main_viewport->PlatformHandle = (void*)bd->Window; main_viewport->PlatformHandle = (void*)bd->Window;
} }
static void ImGui_ImplGlfw_ShutdownPlatformInterface() static void ImGui_ImplGlfw_ShutdownMultiViewportSupport()
{ {
ImGui::DestroyPlatformWindows(); ImGui::DestroyPlatformWindows();
} }

View File

@ -6,7 +6,7 @@
// Implemented features: // Implemented features:
// [X] Platform: Clipboard support. // [X] Platform: Clipboard support.
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen (Windows only). // [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen (Windows only).
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. // [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+). // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. // [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.

View File

@ -6,13 +6,14 @@
// !!! Nowadays, prefer using GLFW or SDL instead! // !!! Nowadays, prefer using GLFW or SDL instead!
// Implemented features: // Implemented features:
// [X] Platform: Partial keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLUT values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] // [X] Platform: Partial keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLUT values are obsolete since 1.87 and not supported since 1.91.5]
// Missing features: // Issues:
// [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I // [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I
// [ ] Platform: Missing horizontal mouse wheel support. // [ ] Platform: Missing horizontal mouse wheel support.
// [ ] Platform: Missing mouse cursor shape/visibility support. // [ ] Platform: Missing mouse cursor shape/visibility support.
// [ ] Platform: Missing clipboard support (not supported by Glut). // [ ] Platform: Missing clipboard support (not supported by Glut).
// [ ] Platform: Missing gamepad support. // [ ] Platform: Missing gamepad support.
// [ ] Platform: Missing multi-viewport support (multiple windows).
// You can 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. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.

View File

@ -6,13 +6,14 @@
// !!! Nowadays, prefer using GLFW or SDL instead! // !!! Nowadays, prefer using GLFW or SDL instead!
// Implemented features: // Implemented features:
// [X] Platform: Partial keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLUT values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] // [X] Platform: Partial keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLUT values are obsolete since 1.87 and not supported since 1.91.5]
// Missing features: // Issues:
// [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I // [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I
// [ ] Platform: Missing horizontal mouse wheel support. // [ ] Platform: Missing horizontal mouse wheel support.
// [ ] Platform: Missing mouse cursor shape/visibility support. // [ ] Platform: Missing mouse cursor shape/visibility support.
// [ ] Platform: Missing clipboard support (not supported by Glut). // [ ] Platform: Missing clipboard support (not supported by Glut).
// [ ] Platform: Missing gamepad support. // [ ] Platform: Missing gamepad support.
// [ ] Platform: Missing multi-viewport support (multiple windows).
// You can 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. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.

View File

@ -41,8 +41,8 @@
#import <Metal/Metal.h> #import <Metal/Metal.h>
// Forward Declarations // Forward Declarations
static void ImGui_ImplMetal_InitPlatformInterface(); static void ImGui_ImplMetal_InitMultiViewportSupport();
static void ImGui_ImplMetal_ShutdownPlatformInterface(); static void ImGui_ImplMetal_ShutdownMultiViewportSupport();
static void ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows(); static void ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows();
static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows(); static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows();
@ -84,7 +84,7 @@ struct ImGui_ImplMetal_Data
{ {
MetalContext* SharedMetalContext; MetalContext* SharedMetalContext;
ImGui_ImplMetal_Data() { memset(this, 0, sizeof(*this)); } ImGui_ImplMetal_Data() { memset((void*)this, 0, sizeof(*this)); }
}; };
static ImGui_ImplMetal_Data* ImGui_ImplMetal_GetBackendData() { return ImGui::GetCurrentContext() ? (ImGui_ImplMetal_Data*)ImGui::GetIO().BackendRendererUserData : nullptr; } static ImGui_ImplMetal_Data* ImGui_ImplMetal_GetBackendData() { return ImGui::GetCurrentContext() ? (ImGui_ImplMetal_Data*)ImGui::GetIO().BackendRendererUserData : nullptr; }
@ -145,8 +145,7 @@ bool ImGui_ImplMetal_Init(id<MTLDevice> device)
bd->SharedMetalContext = [[MetalContext alloc] init]; bd->SharedMetalContext = [[MetalContext alloc] init];
bd->SharedMetalContext.device = device; bd->SharedMetalContext.device = device;
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) ImGui_ImplMetal_InitMultiViewportSupport();
ImGui_ImplMetal_InitPlatformInterface();
return true; return true;
} }
@ -155,7 +154,7 @@ void ImGui_ImplMetal_Shutdown()
{ {
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData(); ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?"); IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
ImGui_ImplMetal_ShutdownPlatformInterface(); ImGui_ImplMetal_ShutdownMultiViewportSupport();
ImGui_ImplMetal_DestroyDeviceObjects(); ImGui_ImplMetal_DestroyDeviceObjects();
ImGui_ImplMetal_DestroyBackendData(); ImGui_ImplMetal_DestroyBackendData();
@ -259,14 +258,14 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData, id<MTLCommandBuffer> c
size_t indexBufferOffset = 0; size_t indexBufferOffset = 0;
for (int n = 0; n < drawData->CmdListsCount; n++) for (int n = 0; n < drawData->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = drawData->CmdLists[n]; const ImDrawList* draw_list = drawData->CmdLists[n];
memcpy((char*)vertexBuffer.buffer.contents + vertexBufferOffset, cmd_list->VtxBuffer.Data, (size_t)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); memcpy((char*)vertexBuffer.buffer.contents + vertexBufferOffset, draw_list->VtxBuffer.Data, (size_t)draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
memcpy((char*)indexBuffer.buffer.contents + indexBufferOffset, cmd_list->IdxBuffer.Data, (size_t)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); memcpy((char*)indexBuffer.buffer.contents + indexBufferOffset, draw_list->IdxBuffer.Data, (size_t)draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
{ {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback) if (pcmd->UserCallback)
{ {
// User callback, registered via ImDrawList::AddCallback() // User callback, registered via ImDrawList::AddCallback()
@ -274,7 +273,7 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData, id<MTLCommandBuffer> c
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplMetal_SetupRenderState(drawData, commandBuffer, commandEncoder, renderPipelineState, vertexBuffer, vertexBufferOffset); ImGui_ImplMetal_SetupRenderState(drawData, commandBuffer, commandEncoder, renderPipelineState, vertexBuffer, vertexBufferOffset);
else else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(draw_list, pcmd);
} }
else else
{ {
@ -304,7 +303,7 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData, id<MTLCommandBuffer> c
// Bind texture, Draw // Bind texture, Draw
if (ImTextureID tex_id = pcmd->GetTexID()) if (ImTextureID tex_id = pcmd->GetTexID())
[commandEncoder setFragmentTexture:(__bridge id<MTLTexture>)(tex_id) atIndex:0]; [commandEncoder setFragmentTexture:(__bridge id<MTLTexture>)(void*)(intptr_t)(tex_id) atIndex:0];
[commandEncoder setVertexBufferOffset:(vertexBufferOffset + pcmd->VtxOffset * sizeof(ImDrawVert)) atIndex:0]; [commandEncoder setVertexBufferOffset:(vertexBufferOffset + pcmd->VtxOffset * sizeof(ImDrawVert)) atIndex:0];
[commandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle [commandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle
@ -315,8 +314,8 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData, id<MTLCommandBuffer> c
} }
} }
vertexBufferOffset += (size_t)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert); vertexBufferOffset += (size_t)draw_list->VtxBuffer.Size * sizeof(ImDrawVert);
indexBufferOffset += (size_t)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx); indexBufferOffset += (size_t)draw_list->IdxBuffer.Size * sizeof(ImDrawIdx);
} }
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer>) [commandBuffer addCompletedHandler:^(id<MTLCommandBuffer>)
@ -360,7 +359,7 @@ bool ImGui_ImplMetal_CreateFontsTexture(id<MTLDevice> device)
id <MTLTexture> texture = [device newTextureWithDescriptor:textureDescriptor]; id <MTLTexture> texture = [device newTextureWithDescriptor:textureDescriptor];
[texture replaceRegion:MTLRegionMake2D(0, 0, (NSUInteger)width, (NSUInteger)height) mipmapLevel:0 withBytes:pixels bytesPerRow:(NSUInteger)width * 4]; [texture replaceRegion:MTLRegionMake2D(0, 0, (NSUInteger)width, (NSUInteger)height) mipmapLevel:0 withBytes:pixels bytesPerRow:(NSUInteger)width * 4];
bd->SharedMetalContext.fontTexture = texture; bd->SharedMetalContext.fontTexture = texture;
io.Fonts->SetTexID((__bridge void*)bd->SharedMetalContext.fontTexture); // ImTextureID == void* io.Fonts->SetTexID((ImTextureID)(intptr_t)(__bridge void*)bd->SharedMetalContext.fontTexture); // ImTextureID == ImU64
return (bd->SharedMetalContext.fontTexture != nil); return (bd->SharedMetalContext.fontTexture != nil);
} }
@ -509,7 +508,7 @@ static void ImGui_ImplMetal_RenderWindow(ImGuiViewport* viewport, void*)
[commandBuffer commit]; [commandBuffer commit];
} }
static void ImGui_ImplMetal_InitPlatformInterface() static void ImGui_ImplMetal_InitMultiViewportSupport()
{ {
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
platform_io.Renderer_CreateWindow = ImGui_ImplMetal_CreateWindow; platform_io.Renderer_CreateWindow = ImGui_ImplMetal_CreateWindow;
@ -518,7 +517,7 @@ static void ImGui_ImplMetal_InitPlatformInterface()
platform_io.Renderer_RenderWindow = ImGui_ImplMetal_RenderWindow; platform_io.Renderer_RenderWindow = ImGui_ImplMetal_RenderWindow;
} }
static void ImGui_ImplMetal_ShutdownPlatformInterface() static void ImGui_ImplMetal_ShutdownMultiViewportSupport()
{ {
ImGui::DestroyPlatformWindows(); ImGui::DestroyPlatformWindows();
} }

View File

@ -24,6 +24,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2024-10-07: OpenGL: Changed default texture sampler to Clamp instead of Repeat/Wrap.
// 2024-06-28: OpenGL: ImGui_ImplOpenGL2_NewFrame() recreates font texture if it has been destroyed by ImGui_ImplOpenGL2_DestroyFontsTexture(). (#7748) // 2024-06-28: OpenGL: ImGui_ImplOpenGL2_NewFrame() recreates font texture if it has been destroyed by ImGui_ImplOpenGL2_DestroyFontsTexture(). (#7748)
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. // 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
// 2021-12-08: OpenGL: Fixed mishandling of the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86. // 2021-12-08: OpenGL: Fixed mishandling of the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
@ -83,8 +84,8 @@ static ImGui_ImplOpenGL2_Data* ImGui_ImplOpenGL2_GetBackendData()
} }
// Forward Declarations // Forward Declarations
static void ImGui_ImplOpenGL2_InitPlatformInterface(); static void ImGui_ImplOpenGL2_InitMultiViewportSupport();
static void ImGui_ImplOpenGL2_ShutdownPlatformInterface(); static void ImGui_ImplOpenGL2_ShutdownMultiViewportSupport();
// Functions // Functions
bool ImGui_ImplOpenGL2_Init() bool ImGui_ImplOpenGL2_Init()
@ -99,8 +100,7 @@ bool ImGui_ImplOpenGL2_Init()
io.BackendRendererName = "imgui_impl_opengl2"; io.BackendRendererName = "imgui_impl_opengl2";
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional) io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) ImGui_ImplOpenGL2_InitMultiViewportSupport();
ImGui_ImplOpenGL2_InitPlatformInterface();
return true; return true;
} }
@ -111,7 +111,7 @@ void ImGui_ImplOpenGL2_Shutdown()
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?"); IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGui_ImplOpenGL2_ShutdownPlatformInterface(); ImGui_ImplOpenGL2_ShutdownMultiViewportSupport();
ImGui_ImplOpenGL2_DestroyDeviceObjects(); ImGui_ImplOpenGL2_DestroyDeviceObjects();
io.BackendRendererName = nullptr; io.BackendRendererName = nullptr;
io.BackendRendererUserData = nullptr; io.BackendRendererUserData = nullptr;
@ -204,16 +204,16 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
// Render command lists // Render command lists
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* draw_list = draw_data->CmdLists[n];
const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, pos))); glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, pos)));
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, uv))); glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, uv)));
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, col))); glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, col)));
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
{ {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback) if (pcmd->UserCallback)
{ {
// User callback, registered via ImDrawList::AddCallback() // User callback, registered via ImDrawList::AddCallback()
@ -221,7 +221,7 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height); ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height);
else else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(draw_list, pcmd);
} }
else else
{ {
@ -275,6 +275,8 @@ bool ImGui_ImplOpenGL2_CreateFontsTexture()
glBindTexture(GL_TEXTURE_2D, bd->FontTexture); glBindTexture(GL_TEXTURE_2D, bd->FontTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
@ -327,13 +329,13 @@ static void ImGui_ImplOpenGL2_RenderWindow(ImGuiViewport* viewport, void*)
ImGui_ImplOpenGL2_RenderDrawData(viewport->DrawData); ImGui_ImplOpenGL2_RenderDrawData(viewport->DrawData);
} }
static void ImGui_ImplOpenGL2_InitPlatformInterface() static void ImGui_ImplOpenGL2_InitMultiViewportSupport()
{ {
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
platform_io.Renderer_RenderWindow = ImGui_ImplOpenGL2_RenderWindow; platform_io.Renderer_RenderWindow = ImGui_ImplOpenGL2_RenderWindow;
} }
static void ImGui_ImplOpenGL2_ShutdownPlatformInterface() static void ImGui_ImplOpenGL2_ShutdownMultiViewportSupport()
{ {
ImGui::DestroyPlatformWindows(); ImGui::DestroyPlatformWindows();
} }

View File

@ -24,6 +24,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2024-10-07: OpenGL: Changed default texture sampler to Clamp instead of Repeat/Wrap.
// 2024-06-28: OpenGL: ImGui_ImplOpenGL3_NewFrame() recreates font texture if it has been destroyed by ImGui_ImplOpenGL3_DestroyFontsTexture(). (#7748) // 2024-06-28: OpenGL: ImGui_ImplOpenGL3_NewFrame() recreates font texture if it has been destroyed by ImGui_ImplOpenGL3_DestroyFontsTexture(). (#7748)
// 2024-05-07: OpenGL: Update loader for Linux to support EGL/GLVND. (#7562) // 2024-05-07: OpenGL: Update loader for Linux to support EGL/GLVND. (#7562)
// 2024-04-16: OpenGL: Detect ES3 contexts on desktop based on version string, to e.g. avoid calling glPolygonMode() on them. (#7447) // 2024-04-16: OpenGL: Detect ES3 contexts on desktop based on version string, to e.g. avoid calling glPolygonMode() on them. (#7447)
@ -252,8 +253,8 @@ static ImGui_ImplOpenGL3_Data* ImGui_ImplOpenGL3_GetBackendData()
} }
// Forward Declarations // Forward Declarations
static void ImGui_ImplOpenGL3_InitPlatformInterface(); static void ImGui_ImplOpenGL3_InitMultiViewportSupport();
static void ImGui_ImplOpenGL3_ShutdownPlatformInterface(); static void ImGui_ImplOpenGL3_ShutdownMultiViewportSupport();
// OpenGL vertex attribute state (for ES 1.0 and ES 2.0 only) // OpenGL vertex attribute state (for ES 1.0 and ES 2.0 only)
#ifndef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY #ifndef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
@ -388,8 +389,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
} }
#endif #endif
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) ImGui_ImplOpenGL3_InitMultiViewportSupport();
ImGui_ImplOpenGL3_InitPlatformInterface();
return true; return true;
} }
@ -400,7 +400,7 @@ void ImGui_ImplOpenGL3_Shutdown()
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?"); IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGui_ImplOpenGL3_ShutdownPlatformInterface(); ImGui_ImplOpenGL3_ShutdownMultiViewportSupport();
ImGui_ImplOpenGL3_DestroyDeviceObjects(); ImGui_ImplOpenGL3_DestroyDeviceObjects();
io.BackendRendererName = nullptr; io.BackendRendererName = nullptr;
io.BackendRendererUserData = nullptr; io.BackendRendererUserData = nullptr;
@ -561,7 +561,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
// Render command lists // Render command lists
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* draw_list = draw_data->CmdLists[n];
// Upload vertex/index buffers // Upload vertex/index buffers
// - OpenGL drivers are in a very sorry state nowadays.... // - OpenGL drivers are in a very sorry state nowadays....
@ -571,8 +571,8 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
// - We are now back to using exclusively glBufferData(). So bd->UseBufferSubData IS ALWAYS FALSE in this code. // - We are now back to using exclusively glBufferData(). So bd->UseBufferSubData IS ALWAYS FALSE in this code.
// We are keeping the old code path for a while in case people finding new issues may want to test the bd->UseBufferSubData path. // We are keeping the old code path for a while in case people finding new issues may want to test the bd->UseBufferSubData path.
// - See https://github.com/ocornut/imgui/issues/4468 and please report any corruption issues. // - See https://github.com/ocornut/imgui/issues/4468 and please report any corruption issues.
const GLsizeiptr vtx_buffer_size = (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert); const GLsizeiptr vtx_buffer_size = (GLsizeiptr)draw_list->VtxBuffer.Size * (int)sizeof(ImDrawVert);
const GLsizeiptr idx_buffer_size = (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx); const GLsizeiptr idx_buffer_size = (GLsizeiptr)draw_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx);
if (bd->UseBufferSubData) if (bd->UseBufferSubData)
{ {
if (bd->VertexBufferSize < vtx_buffer_size) if (bd->VertexBufferSize < vtx_buffer_size)
@ -585,18 +585,18 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
bd->IndexBufferSize = idx_buffer_size; bd->IndexBufferSize = idx_buffer_size;
GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, bd->IndexBufferSize, nullptr, GL_STREAM_DRAW)); GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, bd->IndexBufferSize, nullptr, GL_STREAM_DRAW));
} }
GL_CALL(glBufferSubData(GL_ARRAY_BUFFER, 0, vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer.Data)); GL_CALL(glBufferSubData(GL_ARRAY_BUFFER, 0, vtx_buffer_size, (const GLvoid*)draw_list->VtxBuffer.Data));
GL_CALL(glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer.Data)); GL_CALL(glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, idx_buffer_size, (const GLvoid*)draw_list->IdxBuffer.Data));
} }
else else
{ {
GL_CALL(glBufferData(GL_ARRAY_BUFFER, vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW)); GL_CALL(glBufferData(GL_ARRAY_BUFFER, vtx_buffer_size, (const GLvoid*)draw_list->VtxBuffer.Data, GL_STREAM_DRAW));
GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW)); GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size, (const GLvoid*)draw_list->IdxBuffer.Data, GL_STREAM_DRAW));
} }
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
{ {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback != nullptr) if (pcmd->UserCallback != nullptr)
{ {
// User callback, registered via ImDrawList::AddCallback() // User callback, registered via ImDrawList::AddCallback()
@ -604,7 +604,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object); ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
else else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(draw_list, pcmd);
} }
else else
{ {
@ -692,6 +692,8 @@ bool ImGui_ImplOpenGL3_CreateFontsTexture()
GL_CALL(glBindTexture(GL_TEXTURE_2D, bd->FontTexture)); GL_CALL(glBindTexture(GL_TEXTURE_2D, bd->FontTexture));
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
#ifdef GL_UNPACK_ROW_LENGTH // Not on WebGL/ES #ifdef GL_UNPACK_ROW_LENGTH // Not on WebGL/ES
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)); GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
#endif #endif
@ -903,13 +905,15 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects()
// Create shaders // Create shaders
const GLchar* vertex_shader_with_version[2] = { bd->GlslVersionString, vertex_shader }; const GLchar* vertex_shader_with_version[2] = { bd->GlslVersionString, vertex_shader };
GLuint vert_handle = glCreateShader(GL_VERTEX_SHADER); GLuint vert_handle;
GL_CALL(vert_handle = glCreateShader(GL_VERTEX_SHADER));
glShaderSource(vert_handle, 2, vertex_shader_with_version, nullptr); glShaderSource(vert_handle, 2, vertex_shader_with_version, nullptr);
glCompileShader(vert_handle); glCompileShader(vert_handle);
CheckShader(vert_handle, "vertex shader"); CheckShader(vert_handle, "vertex shader");
const GLchar* fragment_shader_with_version[2] = { bd->GlslVersionString, fragment_shader }; const GLchar* fragment_shader_with_version[2] = { bd->GlslVersionString, fragment_shader };
GLuint frag_handle = glCreateShader(GL_FRAGMENT_SHADER); GLuint frag_handle;
GL_CALL(frag_handle = glCreateShader(GL_FRAGMENT_SHADER));
glShaderSource(frag_handle, 2, fragment_shader_with_version, nullptr); glShaderSource(frag_handle, 2, fragment_shader_with_version, nullptr);
glCompileShader(frag_handle); glCompileShader(frag_handle);
CheckShader(frag_handle, "fragment shader"); CheckShader(frag_handle, "fragment shader");
@ -977,13 +981,13 @@ static void ImGui_ImplOpenGL3_RenderWindow(ImGuiViewport* viewport, void*)
ImGui_ImplOpenGL3_RenderDrawData(viewport->DrawData); ImGui_ImplOpenGL3_RenderDrawData(viewport->DrawData);
} }
static void ImGui_ImplOpenGL3_InitPlatformInterface() static void ImGui_ImplOpenGL3_InitMultiViewportSupport()
{ {
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
platform_io.Renderer_RenderWindow = ImGui_ImplOpenGL3_RenderWindow; platform_io.Renderer_RenderWindow = ImGui_ImplOpenGL3_RenderWindow;
} }
static void ImGui_ImplOpenGL3_ShutdownPlatformInterface() static void ImGui_ImplOpenGL3_ShutdownMultiViewportSupport()
{ {
ImGui::DestroyPlatformWindows(); ImGui::DestroyPlatformWindows();
} }

View File

@ -181,6 +181,9 @@ typedef khronos_uint8_t GLubyte;
#define GL_LINEAR 0x2601 #define GL_LINEAR 0x2601
#define GL_TEXTURE_MAG_FILTER 0x2800 #define GL_TEXTURE_MAG_FILTER 0x2800
#define GL_TEXTURE_MIN_FILTER 0x2801 #define GL_TEXTURE_MIN_FILTER 0x2801
#define GL_TEXTURE_WRAP_S 0x2802
#define GL_TEXTURE_WRAP_T 0x2803
#define GL_REPEAT 0x2901
typedef void (APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode); typedef void (APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode);
typedef void (APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
@ -231,6 +234,9 @@ GLAPI void APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures);
GLAPI void APIENTRY glGenTextures (GLsizei n, GLuint *textures); GLAPI void APIENTRY glGenTextures (GLsizei n, GLuint *textures);
#endif #endif
#endif /* GL_VERSION_1_1 */ #endif /* GL_VERSION_1_1 */
#ifndef GL_VERSION_1_2
#define GL_CLAMP_TO_EDGE 0x812F
#endif /* GL_VERSION_1_2 */
#ifndef GL_VERSION_1_3 #ifndef GL_VERSION_1_3
#define GL_TEXTURE0 0x84C0 #define GL_TEXTURE0 0x84C0
#define GL_ACTIVE_TEXTURE 0x84E0 #define GL_ACTIVE_TEXTURE 0x84E0

View File

@ -6,7 +6,7 @@
// Implemented features: // Implemented features:
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: Mouse support. Can discriminate Mouse/Pen. // [X] Platform: Mouse support. Can discriminate Mouse/Pen.
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy kVK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy kVK_* values are obsolete since 1.87 and not supported since 1.91.5]
// [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend). // [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend).
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// [X] Platform: IME support. // [X] Platform: IME support.

View File

@ -6,7 +6,7 @@
// Implemented features: // Implemented features:
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: Mouse support. Can discriminate Mouse/Pen. // [X] Platform: Mouse support. Can discriminate Mouse/Pen.
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy kVK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy kVK_* values are obsolete since 1.87 and not supported since 1.91.5]
// [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend). // [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend).
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// [X] Platform: IME support. // [X] Platform: IME support.
@ -92,7 +92,7 @@ struct ImGui_ImplOSX_Data
id Monitor; id Monitor;
NSWindow* Window; NSWindow* Window;
ImGui_ImplOSX_Data() { memset(this, 0, sizeof(*this)); } ImGui_ImplOSX_Data() { memset((void*)this, 0, sizeof(*this)); }
}; };
static ImGui_ImplOSX_Data* ImGui_ImplOSX_GetBackendData() { return (ImGui_ImplOSX_Data*)ImGui::GetIO().BackendPlatformUserData; } static ImGui_ImplOSX_Data* ImGui_ImplOSX_GetBackendData() { return (ImGui_ImplOSX_Data*)ImGui::GetIO().BackendPlatformUserData; }
@ -101,8 +101,8 @@ static void ImGui_ImplOSX_DestroyBackendData() { IM_DELETE(
static inline CFTimeInterval GetMachAbsoluteTimeInSeconds() { return (CFTimeInterval)(double)(clock_gettime_nsec_np(CLOCK_UPTIME_RAW) / 1e9); } static inline CFTimeInterval GetMachAbsoluteTimeInSeconds() { return (CFTimeInterval)(double)(clock_gettime_nsec_np(CLOCK_UPTIME_RAW) / 1e9); }
// Forward Declarations // Forward Declarations
static void ImGui_ImplOSX_InitPlatformInterface(); static void ImGui_ImplOSX_InitMultiViewportSupport();
static void ImGui_ImplOSX_ShutdownPlatformInterface(); static void ImGui_ImplOSX_ShutdownMultiViewportSupport();
static void ImGui_ImplOSX_UpdateMonitors(); static void ImGui_ImplOSX_UpdateMonitors();
static void ImGui_ImplOSX_AddTrackingArea(NSView* _Nonnull view); static void ImGui_ImplOSX_AddTrackingArea(NSView* _Nonnull view);
static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view); static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view);
@ -289,7 +289,10 @@ static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view);
@end @end
// Functions // Functions
static ImGuiKey ImGui_ImplOSX_KeyCodeToImGuiKey(int key_code)
// Not static to allow third-party code to use that if they want to (but undocumented)
ImGuiKey ImGui_ImplOSX_KeyCodeToImGuiKey(int key_code);
ImGuiKey ImGui_ImplOSX_KeyCodeToImGuiKey(int key_code)
{ {
switch (key_code) switch (key_code)
{ {
@ -445,8 +448,7 @@ bool ImGui_ImplOSX_Init(NSView* view)
ImGuiViewport* main_viewport = ImGui::GetMainViewport(); ImGuiViewport* main_viewport = ImGui::GetMainViewport();
main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (__bridge_retained void*)bd->Window; main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (__bridge_retained void*)bd->Window;
ImGui_ImplOSX_UpdateMonitors(); ImGui_ImplOSX_UpdateMonitors();
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) ImGui_ImplOSX_InitMultiViewportSupport();
ImGui_ImplOSX_InitPlatformInterface();
// Load cursors. Some of them are undocumented. // Load cursors. Some of them are undocumented.
bd->MouseCursorHidden = false; bd->MouseCursorHidden = false;
@ -536,7 +538,7 @@ void ImGui_ImplOSX_Shutdown()
bd->Monitor = nullptr; bd->Monitor = nullptr;
} }
ImGui_ImplOSX_ShutdownPlatformInterface(); ImGui_ImplOSX_ShutdownMultiViewportSupport();
ImGui_ImplOSX_DestroyBackendData(); ImGui_ImplOSX_DestroyBackendData();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.BackendPlatformName = nullptr; io.BackendPlatformName = nullptr;
@ -1095,7 +1097,7 @@ static void ImGui_ImplOSX_UpdateMonitors()
} }
} }
static void ImGui_ImplOSX_InitPlatformInterface() static void ImGui_ImplOSX_InitMultiViewportSupport()
{ {
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData(); ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
@ -1129,7 +1131,7 @@ static void ImGui_ImplOSX_InitPlatformInterface()
object:nil]; object:nil];
} }
static void ImGui_ImplOSX_ShutdownPlatformInterface() static void ImGui_ImplOSX_ShutdownMultiViewportSupport()
{ {
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData(); ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
[NSNotificationCenter.defaultCenter removeObserver:bd->Observer [NSNotificationCenter.defaultCenter removeObserver:bd->Observer

View File

@ -6,7 +6,7 @@
// Implemented features: // Implemented features:
// [X] Platform: Clipboard support. // [X] Platform: Clipboard support.
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen. // [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. // [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
@ -26,6 +26,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2024-10-24: Emscripten: from SDL 2.30.9, SDL_EVENT_MOUSE_WHEEL event doesn't require dividing by 100.0f.
// 2024-09-09: use SDL_Vulkan_GetDrawableSize() when available. (#7967, #3190) // 2024-09-09: use SDL_Vulkan_GetDrawableSize() when available. (#7967, #3190)
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO: // 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn // - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
@ -126,8 +127,8 @@
#define SDL_HAS_DISPLAY_EVENT SDL_VERSION_ATLEAST(2,0,9) #define SDL_HAS_DISPLAY_EVENT SDL_VERSION_ATLEAST(2,0,9)
#define SDL_HAS_SHOW_WINDOW_ACTIVATION_HINT SDL_VERSION_ATLEAST(2,0,18) #define SDL_HAS_SHOW_WINDOW_ACTIVATION_HINT SDL_VERSION_ATLEAST(2,0,18)
#if SDL_HAS_VULKAN #if SDL_HAS_VULKAN
extern "C" { extern DECLSPEC void SDLCALL SDL_Vulkan_GetDrawableSize(SDL_Window* window, int* w, int* h); } #include <SDL_vulkan.h>
#elif #else
static const Uint32 SDL_WINDOW_VULKAN = 0x10000000; static const Uint32 SDL_WINDOW_VULKAN = 0x10000000;
#endif #endif
@ -170,8 +171,8 @@ static ImGui_ImplSDL2_Data* ImGui_ImplSDL2_GetBackendData()
// Forward Declarations // Forward Declarations
static void ImGui_ImplSDL2_UpdateMonitors(); static void ImGui_ImplSDL2_UpdateMonitors();
static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window* window, void* sdl_gl_context); static void ImGui_ImplSDL2_InitMultiViewportSupport(SDL_Window* window, void* sdl_gl_context);
static void ImGui_ImplSDL2_ShutdownPlatformInterface(); static void ImGui_ImplSDL2_ShutdownMultiViewportSupport();
// Functions // Functions
static const char* ImGui_ImplSDL2_GetClipboardText(ImGuiContext*) static const char* ImGui_ImplSDL2_GetClipboardText(ImGuiContext*)
@ -202,7 +203,9 @@ static void ImGui_ImplSDL2_PlatformSetImeData(ImGuiContext*, ImGuiViewport* view
} }
} }
static ImGuiKey ImGui_ImplSDL2_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode) // Not static to allow third-party code to use that if they want to (but undocumented)
ImGuiKey ImGui_ImplSDL2_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode);
ImGuiKey ImGui_ImplSDL2_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode)
{ {
IM_UNUSED(scancode); IM_UNUSED(scancode);
switch (keycode) switch (keycode)
@ -385,7 +388,7 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
float wheel_x = -(float)event->wheel.x; float wheel_x = -(float)event->wheel.x;
float wheel_y = (float)event->wheel.y; float wheel_y = (float)event->wheel.y;
#endif #endif
#ifdef __EMSCRIPTEN__ #if defined(__EMSCRIPTEN__) && !SDL_VERSION_ATLEAST(2,31,0)
wheel_x /= 100.0f; wheel_x /= 100.0f;
#endif #endif
io.AddMouseSourceEvent(event->wheel.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse); io.AddMouseSourceEvent(event->wheel.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
@ -520,7 +523,6 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
#else #else
bd->MouseCanReportHoveredViewport = false; bd->MouseCanReportHoveredViewport = false;
#endif #endif
bd->WantUpdateMonitors = true;
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText; platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText;
@ -531,6 +533,9 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { ImGui_ImplSDL2_EmscriptenOpenURL(url); return true; }; platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { ImGui_ImplSDL2_EmscriptenOpenURL(url); return true; };
#endif #endif
// Update monitor a first time during init
ImGui_ImplSDL2_UpdateMonitors();
// Gamepad handling // Gamepad handling
bd->GamepadMode = ImGui_ImplSDL2_GamepadMode_AutoFirst; bd->GamepadMode = ImGui_ImplSDL2_GamepadMode_AutoFirst;
bd->WantUpdateGamepadsList = true; bd->WantUpdateGamepadsList = true;
@ -584,9 +589,9 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
#endif #endif
// We need SDL_CaptureMouse(), SDL_GetGlobalMouseState() from SDL 2.0.4+ to support multiple viewports. // We need SDL_CaptureMouse(), SDL_GetGlobalMouseState() from SDL 2.0.4+ to support multiple viewports.
// We left the call to ImGui_ImplSDL2_InitPlatformInterface() outside of #ifdef to avoid unused-function warnings. // We left the call to ImGui_ImplSDL2_InitMultiViewportSupport() outside of #ifdef to avoid unused-function warnings.
if ((io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) && (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports)) if (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports)
ImGui_ImplSDL2_InitPlatformInterface(window, sdl_gl_context); ImGui_ImplSDL2_InitMultiViewportSupport(window, sdl_gl_context);
return true; return true;
} }
@ -639,7 +644,7 @@ void ImGui_ImplSDL2_Shutdown()
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?"); IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGui_ImplSDL2_ShutdownPlatformInterface(); ImGui_ImplSDL2_ShutdownMultiViewportSupport();
if (bd->ClipboardTextData) if (bd->ClipboardTextData)
SDL_free(bd->ClipboardTextData); SDL_free(bd->ClipboardTextData);
@ -672,7 +677,7 @@ static void ImGui_ImplSDL2_UpdateMouseData()
if (is_app_focused) if (is_app_focused)
{ {
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
if (io.WantSetMousePos) if (io.WantSetMousePos)
{ {
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE #if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
@ -1034,7 +1039,7 @@ static void ImGui_ImplSDL2_DestroyWindow(ImGuiViewport* viewport)
static void ImGui_ImplSDL2_ShowWindow(ImGuiViewport* viewport) static void ImGui_ImplSDL2_ShowWindow(ImGuiViewport* viewport)
{ {
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData; ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
#if defined(_WIN32) #if defined(_WIN32) && !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP || WINAPI_FAMILY == WINAPI_FAMILY_GAMES))
HWND hwnd = (HWND)viewport->PlatformHandleRaw; HWND hwnd = (HWND)viewport->PlatformHandleRaw;
// SDL hack: Hide icon from task bar // SDL hack: Hide icon from task bar
@ -1151,7 +1156,7 @@ static int ImGui_ImplSDL2_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_inst
} }
#endif // SDL_HAS_VULKAN #endif // SDL_HAS_VULKAN
static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window* window, void* sdl_gl_context) static void ImGui_ImplSDL2_InitMultiViewportSupport(SDL_Window* window, void* sdl_gl_context)
{ {
// Register platform interface (will be coupled with a renderer interface) // Register platform interface (will be coupled with a renderer interface)
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
@ -1187,7 +1192,7 @@ static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window* window, void* sdl_g
main_viewport->PlatformHandle = (void*)(intptr_t)vd->WindowID; main_viewport->PlatformHandle = (void*)(intptr_t)vd->WindowID;
} }
static void ImGui_ImplSDL2_ShutdownPlatformInterface() static void ImGui_ImplSDL2_ShutdownMultiViewportSupport()
{ {
ImGui::DestroyPlatformWindows(); ImGui::DestroyPlatformWindows();
} }

View File

@ -5,7 +5,7 @@
// Implemented features: // Implemented features:
// [X] Platform: Clipboard support. // [X] Platform: Clipboard support.
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen. // [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. // [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.

View File

@ -7,7 +7,7 @@
// Implemented features: // Implemented features:
// [X] Platform: Clipboard support. // [X] Platform: Clipboard support.
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen. // [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [x] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable' -> the OS animation effect when window gets created/destroyed is problematic. SDL2 backend doesn't have issue. // [x] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable' -> the OS animation effect when window gets created/destroyed is problematic. SDL2 backend doesn't have issue.
@ -26,6 +26,7 @@
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2024-09-11: (Docking) Added support for viewport->ParentViewportId field to support parenting at OS level. (#7973) // 2024-09-11: (Docking) Added support for viewport->ParentViewportId field to support parenting at OS level. (#7973)
// 2024-10-24: Emscripten: SDL_EVENT_MOUSE_WHEEL event doesn't require dividing by 100.0f on Emscripten.
// 2024-09-03: Update for SDL3 api changes: SDL_GetGamepads() memory ownership revert. (#7918, #7898, #7807) // 2024-09-03: Update for SDL3 api changes: SDL_GetGamepads() memory ownership revert. (#7918, #7898, #7807)
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO: // 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn // - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
@ -131,8 +132,8 @@ static ImGui_ImplSDL3_Data* ImGui_ImplSDL3_GetBackendData()
// Forward Declarations // Forward Declarations
static void ImGui_ImplSDL3_UpdateMonitors(); static void ImGui_ImplSDL3_UpdateMonitors();
static void ImGui_ImplSDL3_InitPlatformInterface(SDL_Window* window, void* sdl_gl_context); static void ImGui_ImplSDL3_InitMultiViewportSupport(SDL_Window* window, void* sdl_gl_context);
static void ImGui_ImplSDL3_ShutdownPlatformInterface(); static void ImGui_ImplSDL3_ShutdownMultiViewportSupport();
// Functions // Functions
static const char* ImGui_ImplSDL3_GetClipboardText(ImGuiContext*) static const char* ImGui_ImplSDL3_GetClipboardText(ImGuiContext*)
@ -173,7 +174,9 @@ static void ImGui_ImplSDL3_PlatformSetImeData(ImGuiContext*, ImGuiViewport* view
} }
} }
static ImGuiKey ImGui_ImplSDL3_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode) // Not static to allow third-party code to use that if they want to (but undocumented)
ImGuiKey ImGui_ImplSDL3_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode);
ImGuiKey ImGui_ImplSDL3_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode)
{ {
// Keypad doesn't have individual key values in SDL3 // Keypad doesn't have individual key values in SDL3
switch (scancode) switch (scancode)
@ -355,9 +358,6 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
//IMGUI_DEBUG_LOG("wheel %.2f %.2f, precise %.2f %.2f\n", (float)event->wheel.x, (float)event->wheel.y, event->wheel.preciseX, event->wheel.preciseY); //IMGUI_DEBUG_LOG("wheel %.2f %.2f, precise %.2f %.2f\n", (float)event->wheel.x, (float)event->wheel.y, event->wheel.preciseX, event->wheel.preciseY);
float wheel_x = -event->wheel.x; float wheel_x = -event->wheel.x;
float wheel_y = event->wheel.y; float wheel_y = event->wheel.y;
#ifdef __EMSCRIPTEN__
wheel_x /= 100.0f;
#endif
io.AddMouseSourceEvent(event->wheel.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse); io.AddMouseSourceEvent(event->wheel.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
io.AddMouseWheelEvent(wheel_x, wheel_y); io.AddMouseWheelEvent(wheel_x, wheel_y);
return true; return true;
@ -511,13 +511,15 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, SDL_
#else #else
bd->MouseCanReportHoveredViewport = false; bd->MouseCanReportHoveredViewport = false;
#endif #endif
bd->WantUpdateMonitors = true;
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL3_SetClipboardText; platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL3_SetClipboardText;
platform_io.Platform_GetClipboardTextFn = ImGui_ImplSDL3_GetClipboardText; platform_io.Platform_GetClipboardTextFn = ImGui_ImplSDL3_GetClipboardText;
platform_io.Platform_SetImeDataFn = ImGui_ImplSDL3_PlatformSetImeData; platform_io.Platform_SetImeDataFn = ImGui_ImplSDL3_PlatformSetImeData;
// Update monitor a first time during init
ImGui_ImplSDL3_UpdateMonitors();
// Gamepad handling // Gamepad handling
bd->GamepadMode = ImGui_ImplSDL3_GamepadMode_AutoFirst; bd->GamepadMode = ImGui_ImplSDL3_GamepadMode_AutoFirst;
bd->WantUpdateGamepadsList = true; bd->WantUpdateGamepadsList = true;
@ -553,8 +555,8 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, SDL_
// We need SDL_CaptureMouse(), SDL_GetGlobalMouseState() from SDL 2.0.4+ to support multiple viewports. // We need SDL_CaptureMouse(), SDL_GetGlobalMouseState() from SDL 2.0.4+ to support multiple viewports.
// We left the call to ImGui_ImplSDL3_InitPlatformInterface() outside of #ifdef to avoid unused-function warnings. // We left the call to ImGui_ImplSDL3_InitPlatformInterface() outside of #ifdef to avoid unused-function warnings.
if ((io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) && (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports)) if (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports)
ImGui_ImplSDL3_InitPlatformInterface(window, sdl_gl_context); ImGui_ImplSDL3_InitMultiViewportSupport(window, sdl_gl_context);
return true; return true;
} }
@ -610,7 +612,7 @@ void ImGui_ImplSDL3_Shutdown()
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?"); IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGui_ImplSDL3_ShutdownPlatformInterface(); ImGui_ImplSDL3_ShutdownMultiViewportSupport();
if (bd->ClipboardTextData) if (bd->ClipboardTextData)
SDL_free(bd->ClipboardTextData); SDL_free(bd->ClipboardTextData);
@ -633,7 +635,7 @@ static void ImGui_ImplSDL3_UpdateMouseData()
// We forward mouse input when hovered or captured (via SDL_EVENT_MOUSE_MOTION) or when focused (below) // We forward mouse input when hovered or captured (via SDL_EVENT_MOUSE_MOTION) or when focused (below)
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE #if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
// SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger other operations outside // SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger other operations outside
SDL_CaptureMouse((bd->MouseButtonsDown != 0) ? SDL_TRUE : SDL_FALSE); SDL_CaptureMouse(bd->MouseButtonsDown != 0);
SDL_Window* focused_window = SDL_GetKeyboardFocus(); SDL_Window* focused_window = SDL_GetKeyboardFocus();
const bool is_app_focused = (focused_window && (bd->Window == focused_window || ImGui_ImplSDL3_GetViewportForWindowID(SDL_GetWindowID(focused_window)) != NULL)); const bool is_app_focused = (focused_window && (bd->Window == focused_window || ImGui_ImplSDL3_GetViewportForWindowID(SDL_GetWindowID(focused_window)) != NULL));
#else #else
@ -642,7 +644,7 @@ static void ImGui_ImplSDL3_UpdateMouseData()
#endif #endif
if (is_app_focused) if (is_app_focused)
{ {
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
if (io.WantSetMousePos) if (io.WantSetMousePos)
{ {
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE #if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
@ -953,9 +955,9 @@ static void ImGui_ImplSDL3_CreateWindow(ImGuiViewport* viewport)
SDL_GL_MakeCurrent(main_viewport_data->Window, main_viewport_data->GLContext); SDL_GL_MakeCurrent(main_viewport_data->Window, main_viewport_data->GLContext);
} }
Uint32 sdl_flags = 0; SDL_WindowFlags sdl_flags = 0;
sdl_flags |= use_opengl ? SDL_WINDOW_OPENGL : (bd->UseVulkan ? SDL_WINDOW_VULKAN : 0); sdl_flags |= use_opengl ? SDL_WINDOW_OPENGL : (bd->UseVulkan ? SDL_WINDOW_VULKAN : 0);
sdl_flags |= SDL_GetWindowFlags(bd->Window); sdl_flags |= SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_HIGH_PIXEL_DENSITY;
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? SDL_WINDOW_BORDERLESS : 0; sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? SDL_WINDOW_BORDERLESS : 0;
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? 0 : SDL_WINDOW_RESIZABLE; sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? 0 : SDL_WINDOW_RESIZABLE;
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) ? SDL_WINDOW_UTILITY : 0; sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) ? SDL_WINDOW_UTILITY : 0;
@ -993,7 +995,7 @@ static void ImGui_ImplSDL3_DestroyWindow(ImGuiViewport* viewport)
static void ImGui_ImplSDL3_ShowWindow(ImGuiViewport* viewport) static void ImGui_ImplSDL3_ShowWindow(ImGuiViewport* viewport)
{ {
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData; ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
#if defined(_WIN32) #if defined(_WIN32) && !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP || WINAPI_FAMILY == WINAPI_FAMILY_GAMES))
HWND hwnd = (HWND)viewport->PlatformHandleRaw; HWND hwnd = (HWND)viewport->PlatformHandleRaw;
// SDL hack: Show icon in task bar (#7989) // SDL hack: Show icon in task bar (#7989)
@ -1108,11 +1110,11 @@ static int ImGui_ImplSDL3_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_inst
{ {
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData; ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
(void)vk_allocator; (void)vk_allocator;
SDL_bool ret = SDL_Vulkan_CreateSurface(vd->Window, (VkInstance)vk_instance, (VkAllocationCallbacks*)vk_allocator, (VkSurfaceKHR*)out_vk_surface); bool ret = SDL_Vulkan_CreateSurface(vd->Window, (VkInstance)vk_instance, (VkAllocationCallbacks*)vk_allocator, (VkSurfaceKHR*)out_vk_surface);
return ret ? 0 : 1; // ret ? VK_SUCCESS : VK_NOT_READY return ret ? 0 : 1; // ret ? VK_SUCCESS : VK_NOT_READY
} }
static void ImGui_ImplSDL3_InitPlatformInterface(SDL_Window* window, void* sdl_gl_context) static void ImGui_ImplSDL3_InitMultiViewportSupport(SDL_Window* window, void* sdl_gl_context)
{ {
// Register platform interface (will be coupled with a renderer interface) // Register platform interface (will be coupled with a renderer interface)
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
@ -1145,7 +1147,7 @@ static void ImGui_ImplSDL3_InitPlatformInterface(SDL_Window* window, void* sdl_g
main_viewport->PlatformHandle = (void*)(intptr_t)vd->WindowID; main_viewport->PlatformHandle = (void*)(intptr_t)vd->WindowID;
} }
static void ImGui_ImplSDL3_ShutdownPlatformInterface() static void ImGui_ImplSDL3_ShutdownMultiViewportSupport()
{ {
ImGui::DestroyPlatformWindows(); ImGui::DestroyPlatformWindows();
} }

View File

@ -7,7 +7,7 @@
// Implemented features: // Implemented features:
// [X] Platform: Clipboard support. // [X] Platform: Clipboard support.
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen. // [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [x] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable' -> the OS animation effect when window gets created/destroyed is problematic. SDL2 backend doesn't have issue. // [x] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable' -> the OS animation effect when window gets created/destroyed is problematic. SDL2 backend doesn't have issue.

View File

@ -10,6 +10,7 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
// Missing features: // Missing features:
// [ ] Renderer: Multi-viewport support (multiple windows). // [ ] Renderer: Multi-viewport support (multiple windows).
@ -22,6 +23,7 @@
// - Introduction, links and more at the top of imgui.cpp // - Introduction, links and more at the top of imgui.cpp
// CHANGELOG // CHANGELOG
// 2024-10-09: Expose selected render state in ImGui_ImplSDLRenderer2_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
// 2024-05-14: *BREAKING CHANGE* ImGui_ImplSDLRenderer3_RenderDrawData() requires SDL_Renderer* passed as parameter. // 2024-05-14: *BREAKING CHANGE* ImGui_ImplSDLRenderer3_RenderDrawData() requires SDL_Renderer* passed as parameter.
// 2023-05-30: Renamed imgui_impl_sdlrenderer.h/.cpp to imgui_impl_sdlrenderer2.h/.cpp to accommodate for upcoming SDL3. // 2023-05-30: Renamed imgui_impl_sdlrenderer.h/.cpp to imgui_impl_sdlrenderer2.h/.cpp to accommodate for upcoming SDL3.
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. // 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
@ -142,21 +144,29 @@ void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
SDL_RenderGetViewport(renderer, &old.Viewport); SDL_RenderGetViewport(renderer, &old.Viewport);
SDL_RenderGetClipRect(renderer, &old.ClipRect); SDL_RenderGetClipRect(renderer, &old.ClipRect);
// Setup desired state
ImGui_ImplSDLRenderer2_SetupRenderState(renderer);
// Setup render state structure (for callbacks and custom texture bindings)
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
ImGui_ImplSDLRenderer2_RenderState render_state;
render_state.Renderer = renderer;
platform_io.Renderer_RenderState = &render_state;
// Will project scissor/clipping rectangles into framebuffer space // Will project scissor/clipping rectangles into framebuffer space
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
ImVec2 clip_scale = render_scale; ImVec2 clip_scale = render_scale;
// Render command lists // Render command lists
ImGui_ImplSDLRenderer2_SetupRenderState(renderer);
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* draw_list = draw_data->CmdLists[n];
const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
{ {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback) if (pcmd->UserCallback)
{ {
// User callback, registered via ImDrawList::AddCallback() // User callback, registered via ImDrawList::AddCallback()
@ -164,7 +174,7 @@ void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplSDLRenderer2_SetupRenderState(renderer); ImGui_ImplSDLRenderer2_SetupRenderState(renderer);
else else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(draw_list, pcmd);
} }
else else
{ {
@ -195,11 +205,12 @@ void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
xy, (int)sizeof(ImDrawVert), xy, (int)sizeof(ImDrawVert),
color, (int)sizeof(ImDrawVert), color, (int)sizeof(ImDrawVert),
uv, (int)sizeof(ImDrawVert), uv, (int)sizeof(ImDrawVert),
cmd_list->VtxBuffer.Size - pcmd->VtxOffset, draw_list->VtxBuffer.Size - pcmd->VtxOffset,
idx_buffer + pcmd->IdxOffset, pcmd->ElemCount, sizeof(ImDrawIdx)); idx_buffer + pcmd->IdxOffset, pcmd->ElemCount, sizeof(ImDrawIdx));
} }
} }
} }
platform_io.Renderer_RenderState = NULL;
// Restore modified SDL_Renderer state // Restore modified SDL_Renderer state
SDL_RenderSetViewport(renderer, &old.Viewport); SDL_RenderSetViewport(renderer, &old.Viewport);

View File

@ -10,6 +10,7 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
// Missing features: // Missing features:
// [ ] Renderer: Multi-viewport support (multiple windows). // [ ] Renderer: Multi-viewport support (multiple windows).
@ -39,4 +40,12 @@ IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_DestroyFontsTexture();
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer2_CreateDeviceObjects(); IMGUI_IMPL_API bool ImGui_ImplSDLRenderer2_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_DestroyDeviceObjects(); IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_DestroyDeviceObjects();
// [BETA] Selected render state data shared with callbacks.
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplSDLRenderer2_RenderDrawData() call.
// (Please open an issue if you feel you need access to more data)
struct ImGui_ImplSDLRenderer2_RenderState
{
SDL_Renderer* Renderer;
};
#endif // #ifndef IMGUI_DISABLE #endif // #ifndef IMGUI_DISABLE

View File

@ -12,6 +12,7 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
// Missing features: // Missing features:
// [ ] Renderer: Multi-viewport support (multiple windows). // [ ] Renderer: Multi-viewport support (multiple windows).
@ -24,6 +25,7 @@
// - Introduction, links and more at the top of imgui.cpp // - Introduction, links and more at the top of imgui.cpp
// CHANGELOG // CHANGELOG
// 2024-10-09: Expose selected render state in ImGui_ImplSDLRenderer3_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
// 2024-07-01: Update for SDL3 api changes: SDL_RenderGeometryRaw() uint32 version was removed (SDL#9009). // 2024-07-01: Update for SDL3 api changes: SDL_RenderGeometryRaw() uint32 version was removed (SDL#9009).
// 2024-05-14: *BREAKING CHANGE* ImGui_ImplSDLRenderer3_RenderDrawData() requires SDL_Renderer* passed as parameter. // 2024-05-14: *BREAKING CHANGE* ImGui_ImplSDLRenderer3_RenderDrawData() requires SDL_Renderer* passed as parameter.
// 2024-02-12: Amend to query SDL_RenderViewportSet() and restore viewport accordingly. // 2024-02-12: Amend to query SDL_RenderViewportSet() and restore viewport accordingly.
@ -160,26 +162,34 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
SDL_Rect ClipRect; SDL_Rect ClipRect;
}; };
BackupSDLRendererState old = {}; BackupSDLRendererState old = {};
old.ViewportEnabled = SDL_RenderViewportSet(renderer) == SDL_TRUE; old.ViewportEnabled = SDL_RenderViewportSet(renderer);
old.ClipEnabled = SDL_RenderClipEnabled(renderer) == SDL_TRUE; old.ClipEnabled = SDL_RenderClipEnabled(renderer);
SDL_GetRenderViewport(renderer, &old.Viewport); SDL_GetRenderViewport(renderer, &old.Viewport);
SDL_GetRenderClipRect(renderer, &old.ClipRect); SDL_GetRenderClipRect(renderer, &old.ClipRect);
// Setup desired state
ImGui_ImplSDLRenderer3_SetupRenderState(renderer);
// Setup render state structure (for callbacks and custom texture bindings)
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
ImGui_ImplSDLRenderer3_RenderState render_state;
render_state.Renderer = renderer;
platform_io.Renderer_RenderState = &render_state;
// Will project scissor/clipping rectangles into framebuffer space // Will project scissor/clipping rectangles into framebuffer space
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
ImVec2 clip_scale = render_scale; ImVec2 clip_scale = render_scale;
// Render command lists // Render command lists
ImGui_ImplSDLRenderer3_SetupRenderState(renderer);
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* draw_list = draw_data->CmdLists[n];
const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
{ {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback) if (pcmd->UserCallback)
{ {
// User callback, registered via ImDrawList::AddCallback() // User callback, registered via ImDrawList::AddCallback()
@ -187,7 +197,7 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplSDLRenderer3_SetupRenderState(renderer); ImGui_ImplSDLRenderer3_SetupRenderState(renderer);
else else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(draw_list, pcmd);
} }
else else
{ {
@ -214,11 +224,12 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
xy, (int)sizeof(ImDrawVert), xy, (int)sizeof(ImDrawVert),
color, (int)sizeof(ImDrawVert), color, (int)sizeof(ImDrawVert),
uv, (int)sizeof(ImDrawVert), uv, (int)sizeof(ImDrawVert),
cmd_list->VtxBuffer.Size - pcmd->VtxOffset, draw_list->VtxBuffer.Size - pcmd->VtxOffset,
idx_buffer + pcmd->IdxOffset, pcmd->ElemCount, sizeof(ImDrawIdx)); idx_buffer + pcmd->IdxOffset, pcmd->ElemCount, sizeof(ImDrawIdx));
} }
} }
} }
platform_io.Renderer_RenderState = NULL;
// Restore modified SDL_Renderer state // Restore modified SDL_Renderer state
SDL_SetRenderViewport(renderer, old.ViewportEnabled ? &old.Viewport : nullptr); SDL_SetRenderViewport(renderer, old.ViewportEnabled ? &old.Viewport : nullptr);

View File

@ -12,6 +12,7 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
// Missing features: // Missing features:
// [ ] Renderer: Multi-viewport support (multiple windows). // [ ] Renderer: Multi-viewport support (multiple windows).
@ -41,4 +42,12 @@ IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_DestroyFontsTexture();
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer3_CreateDeviceObjects(); IMGUI_IMPL_API bool ImGui_ImplSDLRenderer3_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_DestroyDeviceObjects(); IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_DestroyDeviceObjects();
// [BETA] Selected render state data shared with callbacks.
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplSDLRenderer3_RenderDrawData() call.
// (Please open an issue if you feel you need access to more data)
struct ImGui_ImplSDLRenderer3_RenderState
{
SDL_Renderer* Renderer;
};
#endif // #ifndef IMGUI_DISABLE #endif // #ifndef IMGUI_DISABLE

View File

@ -4,16 +4,9 @@
// Implemented features: // Implemented features:
// [x] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions. // [x] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions.
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
// [x] Renderer: Multi-viewport / platform windows. With issues (flickering when creating a new viewport). // [x] Renderer: Multi-viewport / platform windows. With issues (flickering when creating a new viewport).
// Important: on 32-bit systems, user texture binding is only supported if your imconfig file has '#define ImTextureID ImU64'.
// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
// To build this on 32-bit systems and support texture changes:
// - [Solution 1] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'ImTextureID=ImU64' (this is what we do in our .vcxproj files)
// - [Solution 2] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'IMGUI_USER_CONFIG="my_imgui_config.h"' and inside 'my_imgui_config.h' add '#define ImTextureID ImU64' and as many other options as you like.
// - [Solution 3] IDE/msbuild: edit imconfig.h and add '#define ImTextureID ImU64' (prefer solution 2 to create your own config file!)
// - [Solution 4] command-line: add '/D ImTextureID=ImU64' to your cl.exe command-line (this is what we do in our batch files)
// The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification. // The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification.
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/ // IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
@ -35,6 +28,9 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2024-10-07: Vulkan: Changed default texture sampler to Clamp instead of Repeat/Wrap.
// 2024-10-07: Vulkan: Expose selected render state in ImGui_ImplVulkan_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
// 2024-10-07: Vulkan: Compiling with '#define ImTextureID=ImU64' is unnecessary now that dear imgui defaults ImTextureID to u64 instead of void*.
// 2024-04-19: Vulkan: Added convenience support for Volk via IMGUI_IMPL_VULKAN_USE_VOLK define (you can also use IMGUI_IMPL_VULKAN_NO_PROTOTYPES + wrap Volk via ImGui_ImplVulkan_LoadFunctions().) // 2024-04-19: Vulkan: Added convenience support for Volk via IMGUI_IMPL_VULKAN_USE_VOLK define (you can also use IMGUI_IMPL_VULKAN_NO_PROTOTYPES + wrap Volk via ImGui_ImplVulkan_LoadFunctions().)
// 2024-02-14: *BREAKING CHANGE*: Moved RenderPass parameter from ImGui_ImplVulkan_Init() function to ImGui_ImplVulkan_InitInfo structure. Not required when using dynamic rendering. // 2024-02-14: *BREAKING CHANGE*: Moved RenderPass parameter from ImGui_ImplVulkan_Init() function to ImGui_ImplVulkan_InitInfo structure. Not required when using dynamic rendering.
// 2024-02-12: *BREAKING CHANGE*: Dynamic rendering now require filling PipelineRenderingCreateInfo structure. // 2024-02-12: *BREAKING CHANGE*: Dynamic rendering now require filling PipelineRenderingCreateInfo structure.
@ -274,8 +270,8 @@ struct ImGui_ImplVulkan_Data
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Forward Declarations // Forward Declarations
static void ImGui_ImplVulkan_InitPlatformInterface(); static void ImGui_ImplVulkan_InitMultiViewportSupport();
static void ImGui_ImplVulkan_ShutdownPlatformInterface(); static void ImGui_ImplVulkan_ShutdownMultiViewportSupport();
// backends/vulkan/glsl_shader.vert, compiled with: // backends/vulkan/glsl_shader.vert, compiled with:
// # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert // # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert
@ -422,7 +418,7 @@ static inline VkDeviceSize AlignBufferSize(VkDeviceSize size, VkDeviceSize align
return (size + alignment - 1) & ~(alignment - 1); return (size + alignment - 1) & ~(alignment - 1);
} }
static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory, VkDeviceSize& buffer_size, size_t new_size, VkBufferUsageFlagBits usage) static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory, VkDeviceSize& buffer_size, VkDeviceSize new_size, VkBufferUsageFlagBits usage)
{ {
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
@ -523,7 +519,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
wrb->Index = 0; wrb->Index = 0;
wrb->Count = v->ImageCount; wrb->Count = v->ImageCount;
wrb->FrameRenderBuffers = (ImGui_ImplVulkan_FrameRenderBuffers*)IM_ALLOC(sizeof(ImGui_ImplVulkan_FrameRenderBuffers) * wrb->Count); wrb->FrameRenderBuffers = (ImGui_ImplVulkan_FrameRenderBuffers*)IM_ALLOC(sizeof(ImGui_ImplVulkan_FrameRenderBuffers) * wrb->Count);
memset(wrb->FrameRenderBuffers, 0, sizeof(ImGui_ImplVulkan_FrameRenderBuffers) * wrb->Count); memset((void*)wrb->FrameRenderBuffers, 0, sizeof(ImGui_ImplVulkan_FrameRenderBuffers) * wrb->Count);
} }
IM_ASSERT(wrb->Count == v->ImageCount); IM_ASSERT(wrb->Count == v->ImageCount);
wrb->Index = (wrb->Index + 1) % wrb->Count; wrb->Index = (wrb->Index + 1) % wrb->Count;
@ -532,8 +528,8 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
if (draw_data->TotalVtxCount > 0) if (draw_data->TotalVtxCount > 0)
{ {
// Create or resize the vertex/index buffers // Create or resize the vertex/index buffers
size_t vertex_size = AlignBufferSize(draw_data->TotalVtxCount * sizeof(ImDrawVert), bd->BufferMemoryAlignment); VkDeviceSize vertex_size = AlignBufferSize(draw_data->TotalVtxCount * sizeof(ImDrawVert), bd->BufferMemoryAlignment);
size_t index_size = AlignBufferSize(draw_data->TotalIdxCount * sizeof(ImDrawIdx), bd->BufferMemoryAlignment); VkDeviceSize index_size = AlignBufferSize(draw_data->TotalIdxCount * sizeof(ImDrawIdx), bd->BufferMemoryAlignment);
if (rb->VertexBuffer == VK_NULL_HANDLE || rb->VertexBufferSize < vertex_size) if (rb->VertexBuffer == VK_NULL_HANDLE || rb->VertexBufferSize < vertex_size)
CreateOrResizeBuffer(rb->VertexBuffer, rb->VertexBufferMemory, rb->VertexBufferSize, vertex_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); CreateOrResizeBuffer(rb->VertexBuffer, rb->VertexBufferMemory, rb->VertexBufferSize, vertex_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
if (rb->IndexBuffer == VK_NULL_HANDLE || rb->IndexBufferSize < index_size) if (rb->IndexBuffer == VK_NULL_HANDLE || rb->IndexBufferSize < index_size)
@ -548,11 +544,11 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
check_vk_result(err); check_vk_result(err);
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* draw_list = draw_data->CmdLists[n];
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
vtx_dst += cmd_list->VtxBuffer.Size; vtx_dst += draw_list->VtxBuffer.Size;
idx_dst += cmd_list->IdxBuffer.Size; idx_dst += draw_list->IdxBuffer.Size;
} }
VkMappedMemoryRange range[2] = {}; VkMappedMemoryRange range[2] = {};
range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
@ -570,6 +566,14 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
// Setup desired Vulkan state // Setup desired Vulkan state
ImGui_ImplVulkan_SetupRenderState(draw_data, pipeline, command_buffer, rb, fb_width, fb_height); ImGui_ImplVulkan_SetupRenderState(draw_data, pipeline, command_buffer, rb, fb_width, fb_height);
// Setup render state structure (for callbacks and custom texture bindings)
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
ImGui_ImplVulkan_RenderState render_state;
render_state.CommandBuffer = command_buffer;
render_state.Pipeline = pipeline;
render_state.PipelineLayout = bd->PipelineLayout;
platform_io.Renderer_RenderState = &render_state;
// Will project scissor/clipping rectangles into framebuffer space // Will project scissor/clipping rectangles into framebuffer space
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2) ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
@ -580,10 +584,10 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
int global_idx_offset = 0; int global_idx_offset = 0;
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* draw_list = draw_data->CmdLists[n];
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
{ {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback != nullptr) if (pcmd->UserCallback != nullptr)
{ {
// User callback, registered via ImDrawList::AddCallback() // User callback, registered via ImDrawList::AddCallback()
@ -591,7 +595,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplVulkan_SetupRenderState(draw_data, pipeline, command_buffer, rb, fb_width, fb_height); ImGui_ImplVulkan_SetupRenderState(draw_data, pipeline, command_buffer, rb, fb_width, fb_height);
else else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(draw_list, pcmd);
} }
else else
{ {
@ -616,11 +620,11 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
vkCmdSetScissor(command_buffer, 0, 1, &scissor); vkCmdSetScissor(command_buffer, 0, 1, &scissor);
// Bind DescriptorSet with font or user texture // Bind DescriptorSet with font or user texture
VkDescriptorSet desc_set[1] = { (VkDescriptorSet)pcmd->TextureId }; VkDescriptorSet desc_set[1] = { (VkDescriptorSet)pcmd->GetTexID() };
if (sizeof(ImTextureID) < sizeof(ImU64)) if (sizeof(ImTextureID) < sizeof(ImU64))
{ {
// We don't support texture switches if ImTextureID hasn't been redefined to be 64-bit. Do a flaky check that other textures haven't been used. // We don't support texture switches if ImTextureID hasn't been redefined to be 64-bit. Do a flaky check that other textures haven't been used.
IM_ASSERT(pcmd->TextureId == (ImTextureID)bd->FontDescriptorSet); IM_ASSERT(pcmd->GetTexID() == (ImTextureID)bd->FontDescriptorSet);
desc_set[0] = bd->FontDescriptorSet; desc_set[0] = bd->FontDescriptorSet;
} }
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bd->PipelineLayout, 0, 1, desc_set, 0, nullptr); vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bd->PipelineLayout, 0, 1, desc_set, 0, nullptr);
@ -629,9 +633,10 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0); vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
} }
} }
global_idx_offset += cmd_list->IdxBuffer.Size; global_idx_offset += draw_list->IdxBuffer.Size;
global_vtx_offset += cmd_list->VtxBuffer.Size; global_vtx_offset += draw_list->VtxBuffer.Size;
} }
platform_io.Renderer_RenderState = NULL;
// Note: at this point both vkCmdSetViewport() and vkCmdSetScissor() have been called. // Note: at this point both vkCmdSetViewport() and vkCmdSetScissor() have been called.
// Our last values will leak into user/application rendering IF: // Our last values will leak into user/application rendering IF:
@ -1011,9 +1016,9 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
info.magFilter = VK_FILTER_LINEAR; info.magFilter = VK_FILTER_LINEAR;
info.minFilter = VK_FILTER_LINEAR; info.minFilter = VK_FILTER_LINEAR;
info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
info.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
info.minLod = -1000; info.minLod = -1000;
info.maxLod = 1000; info.maxLod = 1000;
info.maxAnisotropy = 1.0f; info.maxAnisotropy = 1.0f;
@ -1151,8 +1156,7 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info)
ImGuiViewport* main_viewport = ImGui::GetMainViewport(); ImGuiViewport* main_viewport = ImGui::GetMainViewport();
main_viewport->RendererUserData = IM_NEW(ImGui_ImplVulkan_ViewportData)(); main_viewport->RendererUserData = IM_NEW(ImGui_ImplVulkan_ViewportData)();
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) ImGui_ImplVulkan_InitMultiViewportSupport();
ImGui_ImplVulkan_InitPlatformInterface();
return true; return true;
} }
@ -1173,7 +1177,7 @@ void ImGui_ImplVulkan_Shutdown()
main_viewport->RendererUserData = nullptr; main_viewport->RendererUserData = nullptr;
// Clean up windows // Clean up windows
ImGui_ImplVulkan_ShutdownPlatformInterface(); ImGui_ImplVulkan_ShutdownMultiViewportSupport();
io.BackendRendererName = nullptr; io.BackendRendererName = nullptr;
io.BackendRendererUserData = nullptr; io.BackendRendererUserData = nullptr;
@ -1490,8 +1494,8 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
wd->SemaphoreCount = wd->ImageCount + 1; wd->SemaphoreCount = wd->ImageCount + 1;
wd->Frames = (ImGui_ImplVulkanH_Frame*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_Frame) * wd->ImageCount); wd->Frames = (ImGui_ImplVulkanH_Frame*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_Frame) * wd->ImageCount);
wd->FrameSemaphores = (ImGui_ImplVulkanH_FrameSemaphores*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_FrameSemaphores) * wd->SemaphoreCount); wd->FrameSemaphores = (ImGui_ImplVulkanH_FrameSemaphores*)IM_ALLOC(sizeof(ImGui_ImplVulkanH_FrameSemaphores) * wd->SemaphoreCount);
memset(wd->Frames, 0, sizeof(wd->Frames[0]) * wd->ImageCount); memset((void*)wd->Frames, 0, sizeof(wd->Frames[0]) * wd->ImageCount);
memset(wd->FrameSemaphores, 0, sizeof(wd->FrameSemaphores[0]) * wd->SemaphoreCount); memset((void*)wd->FrameSemaphores, 0, sizeof(wd->FrameSemaphores[0]) * wd->SemaphoreCount);
for (uint32_t i = 0; i < wd->ImageCount; i++) for (uint32_t i = 0; i < wd->ImageCount; i++)
wd->Frames[i].Backbuffer = backbuffers[i]; wd->Frames[i].Backbuffer = backbuffers[i];
} }
@ -1907,7 +1911,7 @@ static void ImGui_ImplVulkan_SwapBuffers(ImGuiViewport* viewport, void*)
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores
} }
void ImGui_ImplVulkan_InitPlatformInterface() void ImGui_ImplVulkan_InitMultiViewportSupport()
{ {
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable) if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
@ -1919,7 +1923,7 @@ void ImGui_ImplVulkan_InitPlatformInterface()
platform_io.Renderer_SwapBuffers = ImGui_ImplVulkan_SwapBuffers; platform_io.Renderer_SwapBuffers = ImGui_ImplVulkan_SwapBuffers;
} }
void ImGui_ImplVulkan_ShutdownPlatformInterface() void ImGui_ImplVulkan_ShutdownMultiViewportSupport()
{ {
ImGui::DestroyPlatformWindows(); ImGui::DestroyPlatformWindows();
} }

View File

@ -4,11 +4,9 @@
// Implemented features: // Implemented features:
// [x] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions. // [x] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions.
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
// [x] Renderer: Multi-viewport / platform windows. With issues (flickering when creating a new viewport). // [x] Renderer: Multi-viewport / platform windows. With issues (flickering when creating a new viewport).
// Important: on 32-bit systems, user texture binding is only supported if your imconfig file has '#define ImTextureID ImU64'.
// See imgui_impl_vulkan.cpp file for details.
// The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification. // The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification.
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/ // IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
@ -100,23 +98,33 @@ struct ImGui_ImplVulkan_InitInfo
}; };
// Follow "Getting Started" link and check examples/ folder to learn about using backends! // Follow "Getting Started" link and check examples/ folder to learn about using backends!
IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info); IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info);
IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown(); IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown();
IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame(); IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame();
IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline = VK_NULL_HANDLE); IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline = VK_NULL_HANDLE);
IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture(); IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture();
IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontsTexture(); IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontsTexture();
IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated) IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated)
// Register a texture (VkDescriptorSet == ImTextureID) // Register a texture (VkDescriptorSet == ImTextureID)
// FIXME: This is experimental in the sense that we are unsure how to best design/tackle this problem // FIXME: This is experimental in the sense that we are unsure how to best design/tackle this problem
// Please post to https://github.com/ocornut/imgui/pull/914 if you have suggestions. // Please post to https://github.com/ocornut/imgui/pull/914 if you have suggestions.
IMGUI_IMPL_API VkDescriptorSet ImGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView image_view, VkImageLayout image_layout); IMGUI_IMPL_API VkDescriptorSet ImGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView image_view, VkImageLayout image_layout);
IMGUI_IMPL_API void ImGui_ImplVulkan_RemoveTexture(VkDescriptorSet descriptor_set); IMGUI_IMPL_API void ImGui_ImplVulkan_RemoveTexture(VkDescriptorSet descriptor_set);
// Optional: load Vulkan functions with a custom function loader // Optional: load Vulkan functions with a custom function loader
// This is only useful with IMGUI_IMPL_VULKAN_NO_PROTOTYPES / VK_NO_PROTOTYPES // This is only useful with IMGUI_IMPL_VULKAN_NO_PROTOTYPES / VK_NO_PROTOTYPES
IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = nullptr); IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = nullptr);
// [BETA] Selected render state data shared with callbacks.
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplVulkan_RenderDrawData() call.
// (Please open an issue if you feel you need access to more data)
struct ImGui_ImplVulkan_RenderState
{
VkCommandBuffer CommandBuffer;
VkPipeline Pipeline;
VkPipelineLayout PipelineLayout;
};
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// Internal / Miscellaneous Vulkan Helpers // Internal / Miscellaneous Vulkan Helpers

View File

@ -5,6 +5,7 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
// Missing features: // Missing features:
// [ ] Renderer: Multi-viewport support (multiple windows). Not meaningful on the web. // [ ] Renderer: Multi-viewport support (multiple windows). Not meaningful on the web.
@ -18,6 +19,9 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2024-10-14: Update Dawn support for change of string usages. (#8082, #8083)
// 2024-10-07: Expose selected render state in ImGui_ImplWGPU_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
// 2024-10-07: Changed default texture sampler to Clamp instead of Repeat/Wrap.
// 2024-09-16: Added support for optional IMGUI_IMPL_WEBGPU_BACKEND_DAWN / IMGUI_IMPL_WEBGPU_BACKEND_WGPU define to handle ever-changing native implementations. (#7977) // 2024-09-16: Added support for optional IMGUI_IMPL_WEBGPU_BACKEND_DAWN / IMGUI_IMPL_WEBGPU_BACKEND_WGPU define to handle ever-changing native implementations. (#7977)
// 2024-01-22: Added configurable PipelineMultisampleState struct. (#7240) // 2024-01-22: Added configurable PipelineMultisampleState struct. (#7240)
// 2024-01-22: (Breaking) ImGui_ImplWGPU_Init() now takes a ImGui_ImplWGPU_InitInfo structure instead of variety of parameters, allowing for easier further changes. // 2024-01-22: (Breaking) ImGui_ImplWGPU_Init() now takes a ImGui_ImplWGPU_InitInfo structure instead of variety of parameters, allowing for easier further changes.
@ -259,20 +263,26 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(const c
{ {
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData(); ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
WGPUShaderModuleWGSLDescriptor wgsl_desc = {};
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN #ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
WGPUShaderSourceWGSL wgsl_desc = {};
wgsl_desc.chain.sType = WGPUSType_ShaderSourceWGSL; wgsl_desc.chain.sType = WGPUSType_ShaderSourceWGSL;
wgsl_desc.code = { wgsl_source, WGPU_STRLEN };
#else #else
WGPUShaderModuleWGSLDescriptor wgsl_desc = {};
wgsl_desc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor; wgsl_desc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor;
wgsl_desc.code = wgsl_source;
#endif #endif
wgsl_desc.code = wgsl_source;
WGPUShaderModuleDescriptor desc = {}; WGPUShaderModuleDescriptor desc = {};
desc.nextInChain = reinterpret_cast<WGPUChainedStruct*>(&wgsl_desc); desc.nextInChain = reinterpret_cast<WGPUChainedStruct*>(&wgsl_desc);
WGPUProgrammableStageDescriptor stage_desc = {}; WGPUProgrammableStageDescriptor stage_desc = {};
stage_desc.module = wgpuDeviceCreateShaderModule(bd->wgpuDevice, &desc); stage_desc.module = wgpuDeviceCreateShaderModule(bd->wgpuDevice, &desc);
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
stage_desc.entryPoint = { "main", WGPU_STRLEN };
#else
stage_desc.entryPoint = "main"; stage_desc.entryPoint = "main";
#endif
return stage_desc; return stage_desc;
} }
@ -385,6 +395,9 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
{ {
nullptr, nullptr,
"Dear ImGui Vertex buffer", "Dear ImGui Vertex buffer",
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
WGPU_STRLEN,
#endif
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex, WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex,
MEMALIGN(fr->VertexBufferSize * sizeof(ImDrawVert), 4), MEMALIGN(fr->VertexBufferSize * sizeof(ImDrawVert), 4),
false false
@ -409,6 +422,9 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
{ {
nullptr, nullptr,
"Dear ImGui Index buffer", "Dear ImGui Index buffer",
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
WGPU_STRLEN,
#endif
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index, WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index,
MEMALIGN(fr->IndexBufferSize * sizeof(ImDrawIdx), 4), MEMALIGN(fr->IndexBufferSize * sizeof(ImDrawIdx), 4),
false false
@ -425,11 +441,11 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
ImDrawIdx* idx_dst = (ImDrawIdx*)fr->IndexBufferHost; ImDrawIdx* idx_dst = (ImDrawIdx*)fr->IndexBufferHost;
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* draw_list = draw_data->CmdLists[n];
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert)); memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx)); memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
vtx_dst += cmd_list->VtxBuffer.Size; vtx_dst += draw_list->VtxBuffer.Size;
idx_dst += cmd_list->IdxBuffer.Size; idx_dst += draw_list->IdxBuffer.Size;
} }
int64_t vb_write_size = MEMALIGN((char*)vtx_dst - (char*)fr->VertexBufferHost, 4); int64_t vb_write_size = MEMALIGN((char*)vtx_dst - (char*)fr->VertexBufferHost, 4);
int64_t ib_write_size = MEMALIGN((char*)idx_dst - (char*)fr->IndexBufferHost, 4); int64_t ib_write_size = MEMALIGN((char*)idx_dst - (char*)fr->IndexBufferHost, 4);
@ -439,6 +455,13 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
// Setup desired render state // Setup desired render state
ImGui_ImplWGPU_SetupRenderState(draw_data, pass_encoder, fr); ImGui_ImplWGPU_SetupRenderState(draw_data, pass_encoder, fr);
// Setup render state structure (for callbacks and custom texture bindings)
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
ImGui_ImplWGPU_RenderState render_state;
render_state.Device = bd->wgpuDevice;
render_state.RenderPassEncoder = pass_encoder;
platform_io.Renderer_RenderState = &render_state;
// Render command lists // Render command lists
// (Because we merged all buffers into a single one, we maintain our own offset into them) // (Because we merged all buffers into a single one, we maintain our own offset into them)
int global_vtx_offset = 0; int global_vtx_offset = 0;
@ -447,10 +470,10 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
ImVec2 clip_off = draw_data->DisplayPos; ImVec2 clip_off = draw_data->DisplayPos;
for (int n = 0; n < draw_data->CmdListsCount; n++) for (int n = 0; n < draw_data->CmdListsCount; n++)
{ {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* draw_list = draw_data->CmdLists[n];
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
{ {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback != nullptr) if (pcmd->UserCallback != nullptr)
{ {
// User callback, registered via ImDrawList::AddCallback() // User callback, registered via ImDrawList::AddCallback()
@ -458,7 +481,7 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplWGPU_SetupRenderState(draw_data, pass_encoder, fr); ImGui_ImplWGPU_SetupRenderState(draw_data, pass_encoder, fr);
else else
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(draw_list, pcmd);
} }
else else
{ {
@ -494,9 +517,10 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
wgpuRenderPassEncoderDrawIndexed(pass_encoder, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0); wgpuRenderPassEncoderDrawIndexed(pass_encoder, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
} }
} }
global_idx_offset += cmd_list->IdxBuffer.Size; global_idx_offset += draw_list->IdxBuffer.Size;
global_vtx_offset += cmd_list->VtxBuffer.Size; global_vtx_offset += draw_list->VtxBuffer.Size;
} }
platform_io.Renderer_RenderState = NULL;
} }
static void ImGui_ImplWGPU_CreateFontsTexture() static void ImGui_ImplWGPU_CreateFontsTexture()
@ -511,7 +535,11 @@ static void ImGui_ImplWGPU_CreateFontsTexture()
// Upload texture to graphics system // Upload texture to graphics system
{ {
WGPUTextureDescriptor tex_desc = {}; WGPUTextureDescriptor tex_desc = {};
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
tex_desc.label = { "Dear ImGui Font Texture", WGPU_STRLEN };
#else
tex_desc.label = "Dear ImGui Font Texture"; tex_desc.label = "Dear ImGui Font Texture";
#endif
tex_desc.dimension = WGPUTextureDimension_2D; tex_desc.dimension = WGPUTextureDimension_2D;
tex_desc.size.width = width; tex_desc.size.width = width;
tex_desc.size.height = height; tex_desc.size.height = height;
@ -555,9 +583,9 @@ static void ImGui_ImplWGPU_CreateFontsTexture()
sampler_desc.minFilter = WGPUFilterMode_Linear; sampler_desc.minFilter = WGPUFilterMode_Linear;
sampler_desc.magFilter = WGPUFilterMode_Linear; sampler_desc.magFilter = WGPUFilterMode_Linear;
sampler_desc.mipmapFilter = WGPUMipmapFilterMode_Linear; sampler_desc.mipmapFilter = WGPUMipmapFilterMode_Linear;
sampler_desc.addressModeU = WGPUAddressMode_Repeat; sampler_desc.addressModeU = WGPUAddressMode_ClampToEdge;
sampler_desc.addressModeV = WGPUAddressMode_Repeat; sampler_desc.addressModeV = WGPUAddressMode_ClampToEdge;
sampler_desc.addressModeW = WGPUAddressMode_Repeat; sampler_desc.addressModeW = WGPUAddressMode_ClampToEdge;
sampler_desc.maxAnisotropy = 1; sampler_desc.maxAnisotropy = 1;
bd->renderResources.Sampler = wgpuDeviceCreateSampler(bd->wgpuDevice, &sampler_desc); bd->renderResources.Sampler = wgpuDeviceCreateSampler(bd->wgpuDevice, &sampler_desc);
} }
@ -574,6 +602,9 @@ static void ImGui_ImplWGPU_CreateUniformBuffer()
{ {
nullptr, nullptr,
"Dear ImGui Uniform buffer", "Dear ImGui Uniform buffer",
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
WGPU_STRLEN,
#endif
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Uniform, WGPUBufferUsage_CopyDst | WGPUBufferUsage_Uniform,
MEMALIGN(sizeof(Uniforms), 16), MEMALIGN(sizeof(Uniforms), 16),
false false

View File

@ -12,6 +12,7 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
// Missing features: // Missing features:
// [ ] Renderer: Multi-viewport support (multiple windows). Not meaningful on the web. // [ ] Renderer: Multi-viewport support (multiple windows). Not meaningful on the web.
@ -53,7 +54,16 @@ IMGUI_IMPL_API void ImGui_ImplWGPU_NewFrame();
IMGUI_IMPL_API void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder); IMGUI_IMPL_API void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder);
// Use if you want to reset your rendering device without losing Dear ImGui state. // Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API void ImGui_ImplWGPU_InvalidateDeviceObjects();
IMGUI_IMPL_API bool ImGui_ImplWGPU_CreateDeviceObjects(); IMGUI_IMPL_API bool ImGui_ImplWGPU_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplWGPU_InvalidateDeviceObjects();
// [BETA] Selected render state data shared with callbacks.
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplWGPU_RenderDrawData() call.
// (Please open an issue if you feel you need access to more data)
struct ImGui_ImplWGPU_RenderState
{
WGPUDevice Device;
WGPURenderPassEncoder RenderPassEncoder;
};
#endif // #ifndef IMGUI_DISABLE #endif // #ifndef IMGUI_DISABLE

View File

@ -4,7 +4,7 @@
// Implemented features: // Implemented features:
// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui) // [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen. // [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values are obsolete since 1.87 and not supported since 1.91.5]
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. // [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
@ -23,6 +23,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2024-10-28: [Docking] Rely on property stored inside HWND to retrieve context/viewport, should facilitate attempt to use this for parallel contexts. (#8069)
// 2024-09-16: [Docking] Inputs: fixed an issue where a viewport destroyed while clicking would hog mouse tracking and temporary lead to incorrect update of HoveredWindow. (#7971) // 2024-09-16: [Docking] Inputs: fixed an issue where a viewport destroyed while clicking would hog mouse tracking and temporary lead to incorrect update of HoveredWindow. (#7971)
// 2024-07-08: Inputs: Fixed ImGuiMod_Super being mapped to VK_APPS instead of VK_LWIN||VK_RWIN. (#7768) // 2024-07-08: Inputs: Fixed ImGuiMod_Super being mapped to VK_APPS instead of VK_LWIN||VK_RWIN. (#7768)
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys, app back/forward keys. // 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys, app back/forward keys.
@ -107,8 +108,8 @@ typedef DWORD(WINAPI* PFN_XInputGetState)(DWORD, XINPUT_STATE*);
#endif #endif
// Forward Declarations // Forward Declarations
static void ImGui_ImplWin32_InitPlatformInterface(bool platform_has_own_dc); static void ImGui_ImplWin32_InitMultiViewportSupport(bool platform_has_own_dc);
static void ImGui_ImplWin32_ShutdownPlatformInterface(); static void ImGui_ImplWin32_ShutdownMultiViewportSupport();
static void ImGui_ImplWin32_UpdateMonitors(); static void ImGui_ImplWin32_UpdateMonitors();
struct ImGui_ImplWin32_Data struct ImGui_ImplWin32_Data
@ -142,12 +143,16 @@ static ImGui_ImplWin32_Data* ImGui_ImplWin32_GetBackendData()
{ {
return ImGui::GetCurrentContext() ? (ImGui_ImplWin32_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr; return ImGui::GetCurrentContext() ? (ImGui_ImplWin32_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr;
} }
static ImGui_ImplWin32_Data* ImGui_ImplWin32_GetBackendData(ImGuiIO& io)
{
return (ImGui_ImplWin32_Data*)io.BackendPlatformUserData;
}
// Functions // Functions
static void ImGui_ImplWin32_UpdateKeyboardCodePage() static void ImGui_ImplWin32_UpdateKeyboardCodePage(ImGuiIO& io)
{ {
// Retrieve keyboard code page, required for handling of non-Unicode Windows. // Retrieve keyboard code page, required for handling of non-Unicode Windows.
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(io);
HKL keyboard_layout = ::GetKeyboardLayout(0); HKL keyboard_layout = ::GetKeyboardLayout(0);
LCID keyboard_lcid = MAKELCID(HIWORD(keyboard_layout), SORT_DEFAULT); LCID keyboard_lcid = MAKELCID(HIWORD(keyboard_layout), SORT_DEFAULT);
if (::GetLocaleInfoA(keyboard_lcid, (LOCALE_RETURN_NUMBER | LOCALE_IDEFAULTANSICODEPAGE), (LPSTR)&bd->KeyboardCodePage, sizeof(bd->KeyboardCodePage)) == 0) if (::GetLocaleInfoA(keyboard_lcid, (LOCALE_RETURN_NUMBER | LOCALE_IDEFAULTANSICODEPAGE), (LPSTR)&bd->KeyboardCodePage, sizeof(bd->KeyboardCodePage)) == 0)
@ -176,17 +181,20 @@ static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc)
io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional) io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional)
bd->hWnd = (HWND)hwnd; bd->hWnd = (HWND)hwnd;
bd->WantUpdateMonitors = true;
bd->TicksPerSecond = perf_frequency; bd->TicksPerSecond = perf_frequency;
bd->Time = perf_counter; bd->Time = perf_counter;
bd->LastMouseCursor = ImGuiMouseCursor_COUNT; bd->LastMouseCursor = ImGuiMouseCursor_COUNT;
ImGui_ImplWin32_UpdateKeyboardCodePage(); ImGui_ImplWin32_UpdateKeyboardCodePage(io);
// Update monitor a first time during init
ImGui_ImplWin32_UpdateMonitors();
// Our mouse update function expect PlatformHandle to be filled for the main viewport // Our mouse update function expect PlatformHandle to be filled for the main viewport
ImGuiViewport* main_viewport = ImGui::GetMainViewport(); ImGuiViewport* main_viewport = ImGui::GetMainViewport();
main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (void*)bd->hWnd; main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (void*)bd->hWnd;
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) ::SetPropA(bd->hWnd, "IMGUI_CONTEXT", ImGui::GetCurrentContext());
ImGui_ImplWin32_InitPlatformInterface(platform_has_own_dc); ::SetPropA(bd->hWnd, "IMGUI_VIEWPORT", main_viewport);
ImGui_ImplWin32_InitMultiViewportSupport(platform_has_own_dc);
// Dynamically load XInput library // Dynamically load XInput library
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
@ -229,7 +237,9 @@ void ImGui_ImplWin32_Shutdown()
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?"); IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGui_ImplWin32_ShutdownPlatformInterface(); ::SetPropA(bd->hWnd, "IMGUI_CONTEXT", nullptr);
::SetPropA(bd->hWnd, "IMGUI_VIEWPORT", nullptr);
ImGui_ImplWin32_ShutdownMultiViewportSupport();
// Unload XInput library // Unload XInput library
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
@ -243,13 +253,11 @@ void ImGui_ImplWin32_Shutdown()
IM_DELETE(bd); IM_DELETE(bd);
} }
static bool ImGui_ImplWin32_UpdateMouseCursor() static bool ImGui_ImplWin32_UpdateMouseCursor(ImGuiIO& io, ImGuiMouseCursor imgui_cursor)
{ {
ImGuiIO& io = ImGui::GetIO();
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
return false; return false;
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor) if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
{ {
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
@ -281,54 +289,59 @@ static bool IsVkDown(int vk)
return (::GetKeyState(vk) & 0x8000) != 0; return (::GetKeyState(vk) & 0x8000) != 0;
} }
static void ImGui_ImplWin32_AddKeyEvent(ImGuiKey key, bool down, int native_keycode, int native_scancode = -1) static void ImGui_ImplWin32_AddKeyEvent(ImGuiIO& io, ImGuiKey key, bool down, int native_keycode, int native_scancode = -1)
{ {
ImGuiIO& io = ImGui::GetIO();
io.AddKeyEvent(key, down); io.AddKeyEvent(key, down);
io.SetKeyEventNativeData(key, native_keycode, native_scancode); // To support legacy indexing (<1.87 user code) io.SetKeyEventNativeData(key, native_keycode, native_scancode); // To support legacy indexing (<1.87 user code)
IM_UNUSED(native_scancode); IM_UNUSED(native_scancode);
} }
static void ImGui_ImplWin32_ProcessKeyEventsWorkarounds() static void ImGui_ImplWin32_ProcessKeyEventsWorkarounds(ImGuiIO& io)
{ {
// Left & right Shift keys: when both are pressed together, Windows tend to not generate the WM_KEYUP event for the first released one. // Left & right Shift keys: when both are pressed together, Windows tend to not generate the WM_KEYUP event for the first released one.
if (ImGui::IsKeyDown(ImGuiKey_LeftShift) && !IsVkDown(VK_LSHIFT)) if (ImGui::IsKeyDown(ImGuiKey_LeftShift) && !IsVkDown(VK_LSHIFT))
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftShift, false, VK_LSHIFT); ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_LeftShift, false, VK_LSHIFT);
if (ImGui::IsKeyDown(ImGuiKey_RightShift) && !IsVkDown(VK_RSHIFT)) if (ImGui::IsKeyDown(ImGuiKey_RightShift) && !IsVkDown(VK_RSHIFT))
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightShift, false, VK_RSHIFT); ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_RightShift, false, VK_RSHIFT);
// Sometimes WM_KEYUP for Win key is not passed down to the app (e.g. for Win+V on some setups, according to GLFW). // Sometimes WM_KEYUP for Win key is not passed down to the app (e.g. for Win+V on some setups, according to GLFW).
if (ImGui::IsKeyDown(ImGuiKey_LeftSuper) && !IsVkDown(VK_LWIN)) if (ImGui::IsKeyDown(ImGuiKey_LeftSuper) && !IsVkDown(VK_LWIN))
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftSuper, false, VK_LWIN); ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_LeftSuper, false, VK_LWIN);
if (ImGui::IsKeyDown(ImGuiKey_RightSuper) && !IsVkDown(VK_RWIN)) if (ImGui::IsKeyDown(ImGuiKey_RightSuper) && !IsVkDown(VK_RWIN))
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightSuper, false, VK_RWIN); ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_RightSuper, false, VK_RWIN);
} }
static void ImGui_ImplWin32_UpdateKeyModifiers() static void ImGui_ImplWin32_UpdateKeyModifiers(ImGuiIO& io)
{ {
ImGuiIO& io = ImGui::GetIO();
io.AddKeyEvent(ImGuiMod_Ctrl, IsVkDown(VK_CONTROL)); io.AddKeyEvent(ImGuiMod_Ctrl, IsVkDown(VK_CONTROL));
io.AddKeyEvent(ImGuiMod_Shift, IsVkDown(VK_SHIFT)); io.AddKeyEvent(ImGuiMod_Shift, IsVkDown(VK_SHIFT));
io.AddKeyEvent(ImGuiMod_Alt, IsVkDown(VK_MENU)); io.AddKeyEvent(ImGuiMod_Alt, IsVkDown(VK_MENU));
io.AddKeyEvent(ImGuiMod_Super, IsVkDown(VK_LWIN) || IsVkDown(VK_RWIN)); io.AddKeyEvent(ImGuiMod_Super, IsVkDown(VK_LWIN) || IsVkDown(VK_RWIN));
} }
static ImGuiViewport* ImGui_ImplWin32_FindViewportByPlatformHandle(HWND hwnd)
{
// We could use ImGui::FindViewportByPlatformHandle() but GetPropA() gets us closer to parallel multi-contexts,
// until we can pass an explicit context to FindViewportByPlatformHandle().
//return ImGui::FindViewportByPlatformHandle((void*)hwnd);
return (ImGuiViewport*)::GetPropA(hwnd, "IMGUI_VIEWPORT");
}
// This code supports multi-viewports (multiple OS Windows mapped into different Dear ImGui viewports) // This code supports multi-viewports (multiple OS Windows mapped into different Dear ImGui viewports)
// Because of that, it is a little more complicated than your typical single-viewport binding code! // Because of that, it is a little more complicated than your typical single-viewport binding code!
static void ImGui_ImplWin32_UpdateMouseData() static void ImGui_ImplWin32_UpdateMouseData(ImGuiIO& io)
{ {
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(io);
ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(bd->hWnd != 0); IM_ASSERT(bd->hWnd != 0);
POINT mouse_screen_pos; POINT mouse_screen_pos;
bool has_mouse_screen_pos = ::GetCursorPos(&mouse_screen_pos) != 0; bool has_mouse_screen_pos = ::GetCursorPos(&mouse_screen_pos) != 0;
HWND focused_window = ::GetForegroundWindow(); HWND focused_window = ::GetForegroundWindow();
const bool is_app_focused = (focused_window && (focused_window == bd->hWnd || ::IsChild(focused_window, bd->hWnd) || ImGui::FindViewportByPlatformHandle((void*)focused_window))); const bool is_app_focused = (focused_window && (focused_window == bd->hWnd || ::IsChild(focused_window, bd->hWnd) || ImGui_ImplWin32_FindViewportByPlatformHandle(focused_window)));
if (is_app_focused) if (is_app_focused)
{ {
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
// When multi-viewports are enabled, all Dear ImGui positions are same as OS positions. // When multi-viewports are enabled, all Dear ImGui positions are same as OS positions.
if (io.WantSetMousePos) if (io.WantSetMousePos)
{ {
@ -363,17 +376,16 @@ static void ImGui_ImplWin32_UpdateMouseData()
ImGuiID mouse_viewport_id = 0; ImGuiID mouse_viewport_id = 0;
if (has_mouse_screen_pos) if (has_mouse_screen_pos)
if (HWND hovered_hwnd = ::WindowFromPoint(mouse_screen_pos)) if (HWND hovered_hwnd = ::WindowFromPoint(mouse_screen_pos))
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)hovered_hwnd)) if (ImGuiViewport* viewport = ImGui_ImplWin32_FindViewportByPlatformHandle(hovered_hwnd))
mouse_viewport_id = viewport->ID; mouse_viewport_id = viewport->ID;
io.AddMouseViewportEvent(mouse_viewport_id); io.AddMouseViewportEvent(mouse_viewport_id);
} }
// Gamepad navigation mapping // Gamepad navigation mapping
static void ImGui_ImplWin32_UpdateGamepads() static void ImGui_ImplWin32_UpdateGamepads(ImGuiIO& io)
{ {
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
ImGuiIO& io = ImGui::GetIO(); ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(io);
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
//if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs. //if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
// return; // return;
@ -422,7 +434,9 @@ static void ImGui_ImplWin32_UpdateGamepads()
MAP_ANALOG(ImGuiKey_GamepadRStickDown, gamepad.sThumbRY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768); MAP_ANALOG(ImGuiKey_GamepadRStickDown, gamepad.sThumbRY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
#undef MAP_BUTTON #undef MAP_BUTTON
#undef MAP_ANALOG #undef MAP_ANALOG
#endif // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD #else // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
IM_UNUSED(io);
#endif
} }
static BOOL CALLBACK ImGui_ImplWin32_UpdateMonitors_EnumFunc(HMONITOR monitor, HDC, LPRECT, LPARAM) static BOOL CALLBACK ImGui_ImplWin32_UpdateMonitors_EnumFunc(HMONITOR monitor, HDC, LPRECT, LPARAM)
@ -476,29 +490,32 @@ void ImGui_ImplWin32_NewFrame()
bd->Time = current_time; bd->Time = current_time;
// Update OS mouse position // Update OS mouse position
ImGui_ImplWin32_UpdateMouseData(); ImGui_ImplWin32_UpdateMouseData(io);
// Process workarounds for known Windows key handling issues // Process workarounds for known Windows key handling issues
ImGui_ImplWin32_ProcessKeyEventsWorkarounds(); ImGui_ImplWin32_ProcessKeyEventsWorkarounds(io);
// Update OS mouse cursor with the cursor requested by imgui // Update OS mouse cursor with the cursor requested by imgui
ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor();
if (bd->LastMouseCursor != mouse_cursor) if (bd->LastMouseCursor != mouse_cursor)
{ {
bd->LastMouseCursor = mouse_cursor; bd->LastMouseCursor = mouse_cursor;
ImGui_ImplWin32_UpdateMouseCursor(); ImGui_ImplWin32_UpdateMouseCursor(io, mouse_cursor);
} }
// Update game controllers (if enabled and available) // Update game controllers (if enabled and available)
ImGui_ImplWin32_UpdateGamepads(); ImGui_ImplWin32_UpdateGamepads(io);
} }
// There is no distinct VK_xxx for keypad enter, instead it is VK_RETURN + KF_EXTENDED, we assign it an arbitrary value to make code more readable (VK_ codes go up to 255)
#define IM_VK_KEYPAD_ENTER (VK_RETURN + 256)
// Map VK_xxx to ImGuiKey_xxx. // Map VK_xxx to ImGuiKey_xxx.
static ImGuiKey ImGui_ImplWin32_VirtualKeyToImGuiKey(WPARAM wParam) // Not static to allow third-party code to use that if they want to (but undocumented)
ImGuiKey ImGui_ImplWin32_KeyEventToImGuiKey(WPARAM wParam, LPARAM lParam);
ImGuiKey ImGui_ImplWin32_KeyEventToImGuiKey(WPARAM wParam, LPARAM lParam)
{ {
// There is no distinct VK_xxx for keypad enter, instead it is VK_RETURN + KF_EXTENDED.
if ((wParam == VK_RETURN) && (HIWORD(lParam) & KF_EXTENDED))
return ImGuiKey_KeypadEnter;
switch (wParam) switch (wParam)
{ {
case VK_TAB: return ImGuiKey_Tab; case VK_TAB: return ImGuiKey_Tab;
@ -547,7 +564,6 @@ static ImGuiKey ImGui_ImplWin32_VirtualKeyToImGuiKey(WPARAM wParam)
case VK_MULTIPLY: return ImGuiKey_KeypadMultiply; case VK_MULTIPLY: return ImGuiKey_KeypadMultiply;
case VK_SUBTRACT: return ImGuiKey_KeypadSubtract; case VK_SUBTRACT: return ImGuiKey_KeypadSubtract;
case VK_ADD: return ImGuiKey_KeypadAdd; case VK_ADD: return ImGuiKey_KeypadAdd;
case IM_VK_KEYPAD_ENTER: return ImGuiKey_KeypadEnter;
case VK_LSHIFT: return ImGuiKey_LeftShift; case VK_LSHIFT: return ImGuiKey_LeftShift;
case VK_LCONTROL: return ImGuiKey_LeftCtrl; case VK_LCONTROL: return ImGuiKey_LeftCtrl;
case VK_LMENU: return ImGuiKey_LeftAlt; case VK_LMENU: return ImGuiKey_LeftAlt;
@ -631,22 +647,10 @@ static ImGuiKey ImGui_ImplWin32_VirtualKeyToImGuiKey(WPARAM wParam)
#define DBT_DEVNODES_CHANGED 0x0007 #define DBT_DEVNODES_CHANGED 0x0007
#endif #endif
// Win32 message handler (process Win32 mouse/keyboard inputs, etc.) // Helper to obtain the source of mouse messages.
// Call from your application's message handler. Keep calling your message handler unless this function returns TRUE.
// When implementing your own backend, you can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if Dear ImGui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
// Generally you may always pass all inputs to Dear ImGui, and hide them from your application based on those two flags.
// PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinates when dragging mouse outside of our window bounds.
// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag.
#if 0
// Copy this line into your .cpp file to forward declare the function.
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
#endif
// See https://learn.microsoft.com/en-us/windows/win32/tablet/system-events-and-mouse-messages // See https://learn.microsoft.com/en-us/windows/win32/tablet/system-events-and-mouse-messages
// Prefer to call this at the top of the message handler to avoid the possibility of other Win32 calls interfering with this. // Prefer to call this at the top of the message handler to avoid the possibility of other Win32 calls interfering with this.
static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo() static ImGuiMouseSource ImGui_ImplWin32_GetMouseSourceFromMessageExtraInfo()
{ {
LPARAM extra_info = ::GetMessageExtraInfo(); LPARAM extra_info = ::GetMessageExtraInfo();
if ((extra_info & 0xFFFFFF80) == 0xFF515700) if ((extra_info & 0xFFFFFF80) == 0xFF515700)
@ -656,22 +660,40 @@ static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
return ImGuiMouseSource_Mouse; return ImGuiMouseSource_Mouse;
} }
// Win32 message handler (process Win32 mouse/keyboard inputs, etc.)
// Call from your application's message handler. Keep calling your message handler unless this function returns TRUE.
// When implementing your own backend, you can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if Dear ImGui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
// Generally you may always pass all inputs to Dear ImGui, and hide them from your application based on those two flags.
// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag.
// Copy either line into your .cpp file to forward declare the function:
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); // Use ImGui::GetCurrentContext()
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandlerEx(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, ImGuiIO& io); // Doesn't use ImGui::GetCurrentContext()
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{ {
// Most backends don't have silent checks like this one, but we need it because WndProc are called early in CreateWindow(). // Most backends don't have silent checks like this one, but we need it because WndProc are called early in CreateWindow().
// We silently allow both context or just only backend data to be nullptr. // We silently allow both context or just only backend data to be nullptr.
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); if (ImGui::GetCurrentContext() == NULL)
if (bd == nullptr)
return 0; return 0;
ImGuiIO& io = ImGui::GetIO(); return ImGui_ImplWin32_WndProcHandlerEx(hwnd, msg, wParam, lParam, ImGui::GetIO());
}
// This version is in theory thread-safe in the sense that no path should access ImGui::GetCurrentContext().
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandlerEx(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, ImGuiIO& io)
{
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(io);
if (bd == NULL)
return 0;
switch (msg) switch (msg)
{ {
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
case WM_NCMOUSEMOVE: case WM_NCMOUSEMOVE:
{ {
// We need to call TrackMouseEvent in order to receive WM_MOUSELEAVE events // We need to call TrackMouseEvent in order to receive WM_MOUSELEAVE events
ImGuiMouseSource mouse_source = GetMouseSourceFromMessageExtraInfo(); ImGuiMouseSource mouse_source = ImGui_ImplWin32_GetMouseSourceFromMessageExtraInfo();
const int area = (msg == WM_MOUSEMOVE) ? 1 : 2; const int area = (msg == WM_MOUSEMOVE) ? 1 : 2;
bd->MouseHwnd = hwnd; bd->MouseHwnd = hwnd;
if (bd->MouseTrackedArea != area) if (bd->MouseTrackedArea != area)
@ -721,14 +743,14 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK:
{ {
ImGuiMouseSource mouse_source = GetMouseSourceFromMessageExtraInfo(); ImGuiMouseSource mouse_source = ImGui_ImplWin32_GetMouseSourceFromMessageExtraInfo();
int button = 0; int button = 0;
if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; } if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; }
if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; } if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; }
if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; } if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; }
if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; } if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
if (bd->MouseButtonsDown == 0 && ::GetCapture() == nullptr) if (bd->MouseButtonsDown == 0 && ::GetCapture() == nullptr)
::SetCapture(hwnd); ::SetCapture(hwnd); // Allow us to read mouse coordinates when dragging mouse outside of our window bounds.
bd->MouseButtonsDown |= 1 << button; bd->MouseButtonsDown |= 1 << button;
io.AddMouseSourceEvent(mouse_source); io.AddMouseSourceEvent(mouse_source);
io.AddMouseButtonEvent(button, true); io.AddMouseButtonEvent(button, true);
@ -739,7 +761,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
case WM_MBUTTONUP: case WM_MBUTTONUP:
case WM_XBUTTONUP: case WM_XBUTTONUP:
{ {
ImGuiMouseSource mouse_source = GetMouseSourceFromMessageExtraInfo(); ImGuiMouseSource mouse_source = ImGui_ImplWin32_GetMouseSourceFromMessageExtraInfo();
int button = 0; int button = 0;
if (msg == WM_LBUTTONUP) { button = 0; } if (msg == WM_LBUTTONUP) { button = 0; }
if (msg == WM_RBUTTONUP) { button = 1; } if (msg == WM_RBUTTONUP) { button = 1; }
@ -767,40 +789,37 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
if (wParam < 256) if (wParam < 256)
{ {
// Submit modifiers // Submit modifiers
ImGui_ImplWin32_UpdateKeyModifiers(); ImGui_ImplWin32_UpdateKeyModifiers(io);
// Obtain virtual key code // Obtain virtual key code and convert to ImGuiKey
// (keypad enter doesn't have its own... VK_RETURN with KF_EXTENDED flag means keypad enter, see IM_VK_KEYPAD_ENTER definition for details, it is mapped to ImGuiKey_KeyPadEnter.) const ImGuiKey key = ImGui_ImplWin32_KeyEventToImGuiKey(wParam, lParam);
int vk = (int)wParam; const int vk = (int)wParam;
if ((wParam == VK_RETURN) && (HIWORD(lParam) & KF_EXTENDED))
vk = IM_VK_KEYPAD_ENTER;
const ImGuiKey key = ImGui_ImplWin32_VirtualKeyToImGuiKey(vk);
const int scancode = (int)LOBYTE(HIWORD(lParam)); const int scancode = (int)LOBYTE(HIWORD(lParam));
// Special behavior for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows doesn't emit the key down event. // Special behavior for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows doesn't emit the key down event.
if (key == ImGuiKey_PrintScreen && !is_key_down) if (key == ImGuiKey_PrintScreen && !is_key_down)
ImGui_ImplWin32_AddKeyEvent(key, true, vk, scancode); ImGui_ImplWin32_AddKeyEvent(io, key, true, vk, scancode);
// Submit key event // Submit key event
if (key != ImGuiKey_None) if (key != ImGuiKey_None)
ImGui_ImplWin32_AddKeyEvent(key, is_key_down, vk, scancode); ImGui_ImplWin32_AddKeyEvent(io, key, is_key_down, vk, scancode);
// Submit individual left/right modifier events // Submit individual left/right modifier events
if (vk == VK_SHIFT) if (vk == VK_SHIFT)
{ {
// Important: Shift keys tend to get stuck when pressed together, missing key-up events are corrected in ImGui_ImplWin32_ProcessKeyEventsWorkarounds() // Important: Shift keys tend to get stuck when pressed together, missing key-up events are corrected in ImGui_ImplWin32_ProcessKeyEventsWorkarounds()
if (IsVkDown(VK_LSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftShift, is_key_down, VK_LSHIFT, scancode); } if (IsVkDown(VK_LSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_LeftShift, is_key_down, VK_LSHIFT, scancode); }
if (IsVkDown(VK_RSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightShift, is_key_down, VK_RSHIFT, scancode); } if (IsVkDown(VK_RSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_RightShift, is_key_down, VK_RSHIFT, scancode); }
} }
else if (vk == VK_CONTROL) else if (vk == VK_CONTROL)
{ {
if (IsVkDown(VK_LCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftCtrl, is_key_down, VK_LCONTROL, scancode); } if (IsVkDown(VK_LCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_LeftCtrl, is_key_down, VK_LCONTROL, scancode); }
if (IsVkDown(VK_RCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightCtrl, is_key_down, VK_RCONTROL, scancode); } if (IsVkDown(VK_RCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_RightCtrl, is_key_down, VK_RCONTROL, scancode); }
} }
else if (vk == VK_MENU) else if (vk == VK_MENU)
{ {
if (IsVkDown(VK_LMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftAlt, is_key_down, VK_LMENU, scancode); } if (IsVkDown(VK_LMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_LeftAlt, is_key_down, VK_LMENU, scancode); }
if (IsVkDown(VK_RMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightAlt, is_key_down, VK_RMENU, scancode); } if (IsVkDown(VK_RMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_RightAlt, is_key_down, VK_RMENU, scancode); }
} }
} }
return 0; return 0;
@ -810,7 +829,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
io.AddFocusEvent(msg == WM_SETFOCUS); io.AddFocusEvent(msg == WM_SETFOCUS);
return 0; return 0;
case WM_INPUTLANGCHANGE: case WM_INPUTLANGCHANGE:
ImGui_ImplWin32_UpdateKeyboardCodePage(); ImGui_ImplWin32_UpdateKeyboardCodePage(io);
return 0; return 0;
case WM_CHAR: case WM_CHAR:
if (::IsWindowUnicode(hwnd)) if (::IsWindowUnicode(hwnd))
@ -828,7 +847,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
return 0; return 0;
case WM_SETCURSOR: case WM_SETCURSOR:
// This is required to restore cursor when transitioning from e.g resize borders to client area. // This is required to restore cursor when transitioning from e.g resize borders to client area.
if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor()) if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor(io, bd->LastMouseCursor))
return 1; return 1;
return 0; return 0;
case WM_DEVICECHANGE: case WM_DEVICECHANGE:
@ -1062,8 +1081,8 @@ static void ImGui_ImplWin32_CreateWindow(ImGuiViewport* viewport)
// Create window // Create window
RECT rect = { (LONG)viewport->Pos.x, (LONG)viewport->Pos.y, (LONG)(viewport->Pos.x + viewport->Size.x), (LONG)(viewport->Pos.y + viewport->Size.y) }; RECT rect = { (LONG)viewport->Pos.x, (LONG)viewport->Pos.y, (LONG)(viewport->Pos.x + viewport->Size.x), (LONG)(viewport->Pos.y + viewport->Size.y) };
::AdjustWindowRectEx(&rect, vd->DwStyle, FALSE, vd->DwExStyle); ::AdjustWindowRectEx(&rect, vd->DwStyle, FALSE, vd->DwExStyle);
vd->Hwnd = ::CreateWindowEx( vd->Hwnd = ::CreateWindowExW(
vd->DwExStyle, _T("ImGui Platform"), _T("Untitled"), vd->DwStyle, // Style, class name, window name vd->DwExStyle, L"ImGui Platform", L"Untitled", vd->DwStyle, // Style, class name, window name
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, // Window area rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, // Window area
vd->HwndParent, nullptr, ::GetModuleHandle(nullptr), nullptr); // Owner window, Menu, Instance, Param vd->HwndParent, nullptr, ::GetModuleHandle(nullptr), nullptr); // Owner window, Menu, Instance, Param
vd->HwndOwned = true; vd->HwndOwned = true;
@ -1072,6 +1091,7 @@ static void ImGui_ImplWin32_CreateWindow(ImGuiViewport* viewport)
// Secondary viewports store their imgui context // Secondary viewports store their imgui context
::SetPropA(vd->Hwnd, "IMGUI_CONTEXT", ImGui::GetCurrentContext()); ::SetPropA(vd->Hwnd, "IMGUI_CONTEXT", ImGui::GetCurrentContext());
::SetPropA(vd->Hwnd, "IMGUI_VIEWPORT", viewport);
} }
static void ImGui_ImplWin32_DestroyWindow(ImGuiViewport* viewport) static void ImGui_ImplWin32_DestroyWindow(ImGuiViewport* viewport)
@ -1283,18 +1303,20 @@ static void ImGui_ImplWin32_OnChangedViewport(ImGuiViewport* viewport)
#endif #endif
} }
namespace ImGui { extern ImGuiIO& GetIOEx(ImGuiContext*); }
static LRESULT CALLBACK ImGui_ImplWin32_WndProcHandler_PlatformWindow(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) static LRESULT CALLBACK ImGui_ImplWin32_WndProcHandler_PlatformWindow(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{ {
// Allow secondary viewport WndProc to be called regardless of current context // Allow secondary viewport WndProc to be called regardless of current context
ImGuiContext* hwnd_ctx = (ImGuiContext*)::GetPropA(hWnd, "IMGUI_CONTEXT"); ImGuiContext* ctx = (ImGuiContext*)::GetPropA(hWnd, "IMGUI_CONTEXT");
ImGuiContext* prev_ctx = ImGui::GetCurrentContext(); if (ctx == NULL)
if (hwnd_ctx != prev_ctx && hwnd_ctx != NULL) return DefWindowProc(hWnd, msg, wParam, lParam); // unlike ImGui_ImplWin32_WndProcHandler() we are called directly by Windows, we can't just return 0.
ImGui::SetCurrentContext(hwnd_ctx);
ImGuiIO& io = ImGui::GetIOEx(ctx);
LRESULT result = 0; LRESULT result = 0;
if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) if (ImGui_ImplWin32_WndProcHandlerEx(hWnd, msg, wParam, lParam, io))
result = true; result = true;
else if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)hWnd)) else if (ImGuiViewport* viewport = ImGui_ImplWin32_FindViewportByPlatformHandle(hWnd))
{ {
switch (msg) switch (msg)
{ {
@ -1323,15 +1345,13 @@ static LRESULT CALLBACK ImGui_ImplWin32_WndProcHandler_PlatformWindow(HWND hWnd,
} }
if (result == 0) if (result == 0)
result = DefWindowProc(hWnd, msg, wParam, lParam); result = DefWindowProc(hWnd, msg, wParam, lParam);
if (hwnd_ctx != prev_ctx && hwnd_ctx != NULL)
ImGui::SetCurrentContext(prev_ctx);
return result; return result;
} }
static void ImGui_ImplWin32_InitPlatformInterface(bool platform_has_own_dc) static void ImGui_ImplWin32_InitMultiViewportSupport(bool platform_has_own_dc)
{ {
WNDCLASSEX wcex; WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX); wcex.cbSize = sizeof(WNDCLASSEXW);
wcex.style = CS_HREDRAW | CS_VREDRAW | (platform_has_own_dc ? CS_OWNDC : 0); wcex.style = CS_HREDRAW | CS_VREDRAW | (platform_has_own_dc ? CS_OWNDC : 0);
wcex.lpfnWndProc = ImGui_ImplWin32_WndProcHandler_PlatformWindow; wcex.lpfnWndProc = ImGui_ImplWin32_WndProcHandler_PlatformWindow;
wcex.cbClsExtra = 0; wcex.cbClsExtra = 0;
@ -1341,9 +1361,9 @@ static void ImGui_ImplWin32_InitPlatformInterface(bool platform_has_own_dc)
wcex.hCursor = nullptr; wcex.hCursor = nullptr;
wcex.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1); wcex.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
wcex.lpszMenuName = nullptr; wcex.lpszMenuName = nullptr;
wcex.lpszClassName = _T("ImGui Platform"); wcex.lpszClassName = L"ImGui Platform";
wcex.hIconSm = nullptr; wcex.hIconSm = nullptr;
::RegisterClassEx(&wcex); ::RegisterClassExW(&wcex);
ImGui_ImplWin32_UpdateMonitors(); ImGui_ImplWin32_UpdateMonitors();
@ -1373,10 +1393,9 @@ static void ImGui_ImplWin32_InitPlatformInterface(bool platform_has_own_dc)
vd->Hwnd = bd->hWnd; vd->Hwnd = bd->hWnd;
vd->HwndOwned = false; vd->HwndOwned = false;
main_viewport->PlatformUserData = vd; main_viewport->PlatformUserData = vd;
main_viewport->PlatformHandle = (void*)bd->hWnd;
} }
static void ImGui_ImplWin32_ShutdownPlatformInterface() static void ImGui_ImplWin32_ShutdownMultiViewportSupport()
{ {
::UnregisterClass(_T("ImGui Platform"), ::GetModuleHandle(nullptr)); ::UnregisterClass(_T("ImGui Platform"), ::GetModuleHandle(nullptr));
ImGui::DestroyPlatformWindows(); ImGui::DestroyPlatformWindows();

View File

@ -4,7 +4,7 @@
// Implemented features: // Implemented features:
// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui) // [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen. // [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set] // [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values are obsolete since 1.87 and not supported since 1.91.5]
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. // [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. // [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'. // [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.

File diff suppressed because it is too large Load Diff

View File

@ -380,8 +380,9 @@ node open/closed state differently. See what makes more sense in your situation!
Short explanation: Short explanation:
- Refer to [Image Loading and Displaying Examples](https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples) on the [Wiki](https://github.com/ocornut/imgui/wiki). - Refer to [Image Loading and Displaying Examples](https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples) on the [Wiki](https://github.com/ocornut/imgui/wiki).
- You may use functions such as `ImGui::Image()`, `ImGui::ImageButton()` or lower-level `ImDrawList::AddImage()` to emit draw calls that will use your own textures. - You may use functions such as `ImGui::Image()`, `ImGui::ImageButton()` or lower-level `ImDrawList::AddImage()` to emit draw calls that will use your own textures.
- Actual textures are identified in a way that is up to the user/engine. Those identifiers are stored and passed as ImTextureID (void*) value. - Actual textures are identified in a way that is up to the user/engine. Those identifiers are stored and passed as an opaque ImTextureID value.
- Loading image files from the disk and turning them into a texture is not within the scope of Dear ImGui (for a good reason). - By default ImTextureID can store up to 64-bits. You may `#define` it to a custom type/structure if you need.
- Loading image files from the disk and turning them into a texture is not within the scope of Dear ImGui (for a good reason), but the examples linked above may be useful references.
**Please read documentations or tutorials on your graphics API to understand how to display textures on the screen before moving onward.** **Please read documentations or tutorials on your graphics API to understand how to display textures on the screen before moving onward.**
@ -389,27 +390,27 @@ Long explanation:
- Dear ImGui's job is to create "meshes", defined in a renderer-agnostic format made of draw commands and vertices. At the end of the frame, those meshes (ImDrawList) will be displayed by your rendering function. They are made up of textured polygons and the code to render them is generally fairly short (a few dozen lines). In the examples/ folder, we provide functions for popular graphics APIs (OpenGL, DirectX, etc.). - Dear ImGui's job is to create "meshes", defined in a renderer-agnostic format made of draw commands and vertices. At the end of the frame, those meshes (ImDrawList) will be displayed by your rendering function. They are made up of textured polygons and the code to render them is generally fairly short (a few dozen lines). In the examples/ folder, we provide functions for popular graphics APIs (OpenGL, DirectX, etc.).
- Each rendering function decides on a data type to represent "textures". The concept of what is a "texture" is entirely tied to your underlying engine/graphics API. - Each rendering function decides on a data type to represent "textures". The concept of what is a "texture" is entirely tied to your underlying engine/graphics API.
We carry the information to identify a "texture" in the ImTextureID type. We carry the information to identify a "texture" in the ImTextureID type.
ImTextureID is nothing more than a void*, aka 4/8 bytes worth of data: just enough to store one pointer or integer of your choice. ImTextureID default to ImU64 aka 8 bytes worth of data: just enough to store one pointer or integer of your choice.
Dear ImGui doesn't know or understand what you are storing in ImTextureID, it merely passes ImTextureID values until they reach your rendering function. Dear ImGui doesn't know or understand what you are storing in ImTextureID, it merely passes ImTextureID values until they reach your rendering function.
- In the [examples/](https://github.com/ocornut/imgui/tree/master/examples) backends, for each graphics API we decided on a type that is likely to be a good representation for specifying an image from the end-user perspective. This is what the _examples_ rendering functions are using: - In the [examples/](https://github.com/ocornut/imgui/tree/master/examples) backends, for each graphics API we decided on a type that is likely to be a good representation for specifying an image from the end-user perspective. This is what the _examples_ rendering functions are using:
```cpp ```cpp
OpenGL: OpenGL:
- ImTextureID = GLuint - ImTextureID should contains 'GLuint' (GL texture identifier).
- See ImGui_ImplOpenGL3_RenderDrawData() function in imgui_impl_opengl3.cpp - See ImGui_ImplOpenGL3_RenderDrawData() function in imgui_impl_opengl3.cpp
``` ```
```cpp ```cpp
DirectX9: DirectX9:
- ImTextureID = LPDIRECT3DTEXTURE9 - ImTextureID should contain a 'LPDIRECT3DTEXTURE9' (pointer).
- See ImGui_ImplDX9_RenderDrawData() function in imgui_impl_dx9.cpp - See ImGui_ImplDX9_RenderDrawData() function in imgui_impl_dx9.cpp
``` ```
```cpp ```cpp
DirectX11: DirectX11:
- ImTextureID = ID3D11ShaderResourceView* - ImTextureID should contain a 'ID3D11ShaderResourceView*' (pointer)
- See ImGui_ImplDX11_RenderDrawData() function in imgui_impl_dx11.cpp - See ImGui_ImplDX11_RenderDrawData() function in imgui_impl_dx11.cpp
``` ```
```cpp ```cpp
DirectX12: DirectX12:
- ImTextureID = D3D12_GPU_DESCRIPTOR_HANDLE - ImTextureID should contain a 'D3D12_GPU_DESCRIPTOR_HANDLE' (always 64-bits)
- See ImGui_ImplDX12_RenderDrawData() function in imgui_impl_dx12.cpp - See ImGui_ImplDX12_RenderDrawData() function in imgui_impl_dx12.cpp
``` ```
For example, in the OpenGL example backend we store raw OpenGL texture identifier (GLuint) inside ImTextureID. For example, in the OpenGL example backend we store raw OpenGL texture identifier (GLuint) inside ImTextureID.
@ -421,14 +422,14 @@ If you are starting with OpenGL or DirectX or Vulkan and haven't built much of a
User code may do: User code may do:
```cpp ```cpp
// Cast our texture type to ImTextureID / void* // Cast our texture type to ImTextureID
MyTexture* texture = g_CoffeeTableTexture; MyTexture* texture = g_CoffeeTableTexture;
ImGui::Image((void*)texture, ImVec2(texture->Width, texture->Height)); ImGui::Image((ImTextureID)(intptr_t)texture, ImVec2(texture->Width, texture->Height));
``` ```
The renderer function called after ImGui::Render() will receive that same value that the user code passed: The renderer function called after ImGui::Render() will receive that same value that the user code passed:
```cpp ```cpp
// Cast ImTextureID / void* stored in the draw command as our texture type // Cast ImTextureID stored in the draw command as our texture type
MyTexture* texture = (MyTexture*)pcmd->GetTexID(); MyTexture* texture = (MyTexture*)(intptr_t)pcmd->GetTexID();
MyEngineBindTexture2D(texture); MyEngineBindTexture2D(texture);
``` ```
Once you understand this design, you will understand that loading image files and turning them into displayable textures is not within the scope of Dear ImGui. Once you understand this design, you will understand that loading image files and turning them into displayable textures is not within the scope of Dear ImGui.
@ -437,19 +438,19 @@ If you want to display an image file (e.g. PNG file) on the screen, please refer
Refer to [Image Loading and Displaying Examples](https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples) on the [Wiki](https://github.com/ocornut/imgui/wiki) to find simplified examples for loading textures with OpenGL, DirectX9 and DirectX11. Refer to [Image Loading and Displaying Examples](https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples) on the [Wiki](https://github.com/ocornut/imgui/wiki) to find simplified examples for loading textures with OpenGL, DirectX9 and DirectX11.
C/C++ tip: a void* is pointer-sized storage. You may safely store any pointer or integer into it by casting your value to ImTextureID / void*, and vice-versa. C/C++ tip: a u64 is 8 bytes. You may safely store any pointer or integer into it by casting your value to ImTextureID, and vice-versa.
Because both end-points (user code and rendering function) are under your control, you know exactly what is stored inside the ImTextureID / void*. Because both end-points (user code and rendering function) are under your control, you know exactly what is stored inside the ImTextureID.
Here are some examples: Here are some examples:
```cpp ```cpp
GLuint my_tex = XXX; GLuint my_tex = XXX;
void* my_void_ptr; ImTextureID my_imtexid;
my_void_ptr = (void*)(intptr_t)my_tex; // cast a GLuint into a void* (we don't take its address! we literally store the value inside the pointer) my_imtexid = (ImTextureID)(intptr_t)my_tex; // cast a GLuint into a ImTextureID (we don't take its address! we just copy the address)
my_tex = (GLuint)(intptr_t)my_void_ptr; // cast a void* into a GLuint my_tex = (GLuint)(intptr_t)my_imtexid; // cast a ImTextureID into a GLuint
ID3D11ShaderResourceView* my_dx11_srv = XXX; ID3D11ShaderResourceView* my_dx11_srv = XXX;
void* my_void_ptr; ImTextureID my_imtexid;
my_void_ptr = (void*)my_dx11_srv; // cast a ID3D11ShaderResourceView* into an opaque void* my_imtexid = (ImTextureID)(intptr_t)my_dx11_srv; // cast a ID3D11ShaderResourceView* into an opaque ImTextureID
my_dx11_srv = (ID3D11ShaderResourceView*)my_void_ptr; // cast a void* into a ID3D11ShaderResourceView* my_dx11_srv = (ID3D11ShaderResourceView*)(intptr_t)_my_imtexid; // cast a ImTextureID into a ID3D11ShaderResourceView*
``` ```
Finally, you may call `ImGui::ShowMetricsWindow()` to explore/visualize/understand how the ImDrawList are generated. Finally, you may call `ImGui::ShowMetricsWindow()` to explore/visualize/understand how the ImDrawList are generated.

View File

@ -196,7 +196,7 @@ Ongoing Dear ImGui development is and has been financially supported by users an
**THANK YOU to all past and present supporters for helping to keep this project alive and thriving!** **THANK YOU to all past and present supporters for helping to keep this project alive and thriving!**
Dear ImGui is using software and services provided free of charge for open source projects: Dear ImGui is using software and services provided free of charge for open source projects:
- [PVS-Studio](https://www.viva64.com/en/b/0570/) for static analysis. - [PVS-Studio](https://pvs-studio.com/en/pvs-studio/?utm_source=website&utm_medium=github&utm_campaign=open_source) for static analysis (supports C/C++/C#/Java).
- [GitHub actions](https://github.com/features/actions) for continuous integration systems. - [GitHub actions](https://github.com/features/actions) for continuous integration systems.
- [OpenCppCoverage](https://github.com/OpenCppCoverage/OpenCppCoverage) for code coverage analysis. - [OpenCppCoverage](https://github.com/OpenCppCoverage/OpenCppCoverage) for code coverage analysis.

View File

@ -9,8 +9,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- doc: add a proper documentation system (maybe relying on automation? #435) - doc: add a proper documentation system (maybe relying on automation? #435)
- doc: checklist app to verify backends/integration of imgui (test inputs, rendering, callback, etc.). - doc: checklist app to verify backends/integration of imgui (test inputs, rendering, callback, etc.).
- doc/tips: tips of the day: website? applet in imgui_club? - doc/tips: tips of the day: website? applet in imgui_club?
- doc/wiki: work on the wiki https://github.com/ocornut/imgui/wiki
- window: preserve/restore relative focus ordering (persistent or not), and e.g. of multiple reappearing windows (#2304) -> also see docking reference to same #. - window: preserve/restore relative focus ordering (persistent or not), and e.g. of multiple reappearing windows (#2304) -> also see docking reference to same #.
- window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis). (#690) - window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis). (#690)
- window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. perhaps a lightweight explicit cleanup pass. - window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. perhaps a lightweight explicit cleanup pass.
@ -44,7 +43,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- drawlist: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). (WIP branch) - drawlist: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). (WIP branch)
- drawlist: make it easier to toggle AA per primitive, so we can use e.g. non-AA fill + AA borders more naturally - drawlist: make it easier to toggle AA per primitive, so we can use e.g. non-AA fill + AA borders more naturally
- drawlist: non-AA strokes have gaps between points (#593, #288), glitch especially on RenderCheckmark() and ColorPicker4(). - drawlist: non-AA strokes have gaps between points (#593, #288), glitch especially on RenderCheckmark() and ColorPicker4().
- drawlist: callback: add an extra void* in ImDrawCallback to allow passing render-local data to the callback (would break API). - drawlist: callback: add an extra void* in ImDrawCallback to expose render state instead of pulling from Renderer_RenderState (would break API).
- drawlist: AddRect vs AddLine position confusing (#2441) - drawlist: AddRect vs AddLine position confusing (#2441)
- drawlist/opt: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding. (#1962) - drawlist/opt: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding. (#1962)
- drawlist/opt: AddRect() axis aligned pixel aligned (no-aa) could use 8 triangles instead of 16 and no normal calculation. - drawlist/opt: AddRect() axis aligned pixel aligned (no-aa) could use 8 triangles instead of 16 and no normal calculation.
@ -303,14 +302,13 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- font/opt: Glyph currently 40 bytes (2+9*4). Consider storing UV as 16-bits integer? (->32 bytes). X0/Y0/X1/Y1 as 16 fixed-point integers? Or X0/Y0 as float and X1/Y1 as fixed8_8? - font/opt: Glyph currently 40 bytes (2+9*4). Consider storing UV as 16-bits integer? (->32 bytes). X0/Y0/X1/Y1 as 16 fixed-point integers? Or X0/Y0 as float and X1/Y1 as fixed8_8?
- nav: some features such as PageUp/Down/Home/End should probably work without ImGuiConfigFlags_NavEnableKeyboard? (where do we draw the line? how about CTRL+Tab) - nav: some features such as PageUp/Down/Home/End should probably work without ImGuiConfigFlags_NavEnableKeyboard? (where do we draw the line? how about CTRL+Tab)
! nav: never clear NavId on some setup (e.g. gamepad centric)
- nav: there's currently no way to completely clear focus with the keyboard. depending on patterns used by the application to dispatch inputs, it may be desirable.
- nav: Home/End behavior when navigable item is not fully visible at the edge of scrolling? should be backtrack to keep item into view? - nav: Home/End behavior when navigable item is not fully visible at the edge of scrolling? should be backtrack to keep item into view?
- nav: NavScrollToBringItemIntoView() with item bigger than view should focus top-right? Repro: using Nav in "About Window" - nav: NavScrollToBringItemIntoView() with item bigger than view should focus top-right? Repro: using Nav in "About Window"
- nav: wrap around logic to allow e.g. grid based layout (pressing NavRight on the right-most element would go to the next row, etc.). see internal's NavMoveRequestTryWrapping(). - nav: expose wrap around flags/logic to allow e.g. grid based layout (pressing NavRight on the right-most element would go to the next row, etc.). see internal's NavMoveRequestTryWrapping().
- nav: patterns to make it possible for arrows key to update selection (see JustMovedTo in range_select branch) - nav: patterns to make it possible for arrows key to update selection (see JustMovedTo in range_select branch)
- nav: restore/find nearest NavId when current one disappear (e.g. pressed a button that disappear, or perhaps auto restoring when current button change name) - nav: restore/find nearest NavId when current one disappear (e.g. pressed a button that disappear, or perhaps auto restoring when current button change name)
- nav: SetItemDefaultFocus() level of priority, so widget like Selectable when inside a popup could claim a low-priority default focus on the first selected iem - nav: SetItemDefaultFocus() level of priority, so widget like Selectable when inside a popup could claim a low-priority default focus on the first selected iem
- nav: holding space to repeat a button doesn't show button activated during hold.
- nav: NavFlattened: init requests don't work properly on flattened siblings. - nav: NavFlattened: init requests don't work properly on flattened siblings.
- nav: NavFlattened: pageup/pagedown/home/end don't work properly on flattened siblings. - nav: NavFlattened: pageup/pagedown/home/end don't work properly on flattened siblings.
- nav: NavFlattened: ESC on a flattened child should select something. - nav: NavFlattened: ESC on a flattened child should select something.

View File

@ -68,7 +68,7 @@ void android_main(struct android_app* app)
struct android_poll_source* out_data; struct android_poll_source* out_data;
// Poll all events. If the app is not visible, this loop blocks until g_Initialized == true. // Poll all events. If the app is not visible, this loop blocks until g_Initialized == true.
while (ALooper_pollAll(g_Initialized ? 0 : -1, nullptr, &out_events, (void**)&out_data) >= 0) while (ALooper_pollOnce(g_Initialized ? 0 : -1, nullptr, &out_events, (void**)&out_data) >= 0)
{ {
// Process one event // Process one event
if (out_data != nullptr) if (out_data != nullptr)

View File

@ -42,4 +42,4 @@ file(GLOB sources *.cpp)
add_executable(example_glfw_vulkan ${sources} ${IMGUI_DIR}/backends/imgui_impl_glfw.cpp ${IMGUI_DIR}/backends/imgui_impl_vulkan.cpp ${IMGUI_DIR}/imgui.cpp ${IMGUI_DIR}/imgui_draw.cpp ${IMGUI_DIR}/imgui_demo.cpp ${IMGUI_DIR}/imgui_tables.cpp ${IMGUI_DIR}/imgui_widgets.cpp) add_executable(example_glfw_vulkan ${sources} ${IMGUI_DIR}/backends/imgui_impl_glfw.cpp ${IMGUI_DIR}/backends/imgui_impl_vulkan.cpp ${IMGUI_DIR}/imgui.cpp ${IMGUI_DIR}/imgui_draw.cpp ${IMGUI_DIR}/imgui_demo.cpp ${IMGUI_DIR}/imgui_tables.cpp ${IMGUI_DIR}/imgui_widgets.cpp)
target_link_libraries(example_glfw_vulkan ${LIBRARIES}) target_link_libraries(example_glfw_vulkan ${LIBRARIES})
target_compile_definitions(example_glfw_vulkan PUBLIC -DImTextureID=ImU64)

View File

@ -7,8 +7,8 @@
@set OUT_DIR=Debug @set OUT_DIR=Debug
mkdir %OUT_DIR% mkdir %OUT_DIR%
cl /nologo /Zi /MD /utf-8 %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
@set OUT_DIR=Release @set OUT_DIR=Release
mkdir %OUT_DIR% mkdir %OUT_DIR%
cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%

View File

@ -1,13 +1,14 @@
@REM Build for Visual Studio compiler. Run your copy of amd64/vcvars32.bat to setup 64-bit command-line compiler. @REM Build for Visual Studio compiler. Run your copy of vcvars64.bat or vcvarsall.bat to setup 64-bit command-line compiler.
@set OUT_EXE=example_glfw_vulkan
@set INCLUDES=/I..\.. /I..\..\backends /I..\libs\glfw\include /I %VULKAN_SDK%\include @set INCLUDES=/I..\.. /I..\..\backends /I..\libs\glfw\include /I %VULKAN_SDK%\include
@set SOURCES=main.cpp ..\..\backends\imgui_impl_vulkan.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\imgui*.cpp @set SOURCES=main.cpp ..\..\backends\imgui_impl_vulkan.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\imgui*.cpp
@set LIBS=/LIBPATH:..\libs\glfw\lib-vc2010-64 /libpath:%VULKAN_SDK%\lib glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib @set LIBS=/LIBPATH:..\libs\glfw\lib-vc2010-64 /libpath:%VULKAN_SDK%\lib glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib
@set OUT_DIR=Debug @set OUT_DIR=Debug
mkdir %OUT_DIR% mkdir %OUT_DIR%
cl /nologo /Zi /MD /utf-8 %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
@set OUT_DIR=Release @set OUT_DIR=Release
mkdir %OUT_DIR% mkdir %OUT_DIR%
cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%

View File

@ -91,7 +91,7 @@
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
@ -107,7 +107,7 @@
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
@ -126,7 +126,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
@ -148,7 +148,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>

View File

@ -7,4 +7,8 @@
@set OUT_DIR=Debug @set OUT_DIR=Debug
mkdir %OUT_DIR% mkdir %OUT_DIR%
cl /nologo /Zi /MD /utf-8 %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console
@set OUT_DIR=Release
@REM mkdir %OUT_DIR%
@REM cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console

View File

@ -0,0 +1,14 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars64.bat or vcvarsall.bat to setup command-line compiler.
@set OUT_EXE=example_sdl2_vulkan
@set INCLUDES=/I..\.. /I..\..\backends /I%SDL2_DIR%\include /I %VULKAN_SDK%\include
@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl2.cpp ..\..\backends\imgui_impl_vulkan.cpp ..\..\imgui*.cpp
@set LIBS=/LIBPATH:%SDL2_DIR%\lib\x64 /libpath:%VULKAN_SDK%\lib SDL2.lib SDL2main.lib shell32.lib vulkan-1.lib
@set OUT_DIR=Debug
mkdir %OUT_DIR%
cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console
@set OUT_DIR=Release
@REM mkdir %OUT_DIR%
@REM cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console

View File

@ -91,7 +91,7 @@
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
@ -107,7 +107,7 @@
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
@ -126,7 +126,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
@ -148,7 +148,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
@ -187,4 +187,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>
</Project> </Project>

View File

@ -1,8 +1,14 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. @REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
@set OUT_DIR=Debug
@set OUT_EXE=example_sdl3_opengl3 @set OUT_EXE=example_sdl3_opengl3
@set INCLUDES=/I..\.. /I..\..\backends /I%SDL3_DIR%\include @set INCLUDES=/I..\.. /I..\..\backends /I%SDL3_DIR%\include
@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl3.cpp ..\..\backends\imgui_impl_opengl3.cpp ..\..\imgui*.cpp @set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl3.cpp ..\..\backends\imgui_impl_opengl3.cpp ..\..\imgui*.cpp
@set LIBS=/LIBPATH:%SDL3_DIR%\lib\x86 SDL3.lib opengl32.lib shell32.lib @set LIBS=/LIBPATH:%SDL3_DIR%\lib\x86 SDL3.lib opengl32.lib shell32.lib
@set OUT_DIR=Debug
mkdir %OUT_DIR% mkdir %OUT_DIR%
cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console
@set OUT_DIR=Release
@REM mkdir %OUT_DIR%
@REM cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console

View File

@ -0,0 +1,14 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars64.bat or vcvarsall.bat to setup command-line compiler.
@set OUT_EXE=example_sdl3_opengl3
@set INCLUDES=/I..\.. /I..\..\backends /I%SDL3_DIR%\include
@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl3.cpp ..\..\backends\imgui_impl_opengl3.cpp ..\..\imgui*.cpp
@set LIBS=/LIBPATH:%SDL3_DIR%\lib\x64 SDL3.lib opengl32.lib shell32.lib
@set OUT_DIR=Debug
mkdir %OUT_DIR%
cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console
@set OUT_DIR=Release
@REM mkdir %OUT_DIR%
@REM cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console

View File

@ -27,7 +27,7 @@
int main(int, char**) int main(int, char**)
{ {
// Setup SDL // Setup SDL
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMEPAD)) if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
{ {
printf("Error: SDL_Init(): %s\n", SDL_GetError()); printf("Error: SDL_Init(): %s\n", SDL_GetError());
return -1; return -1;

View File

@ -25,7 +25,7 @@
int main(int, char**) int main(int, char**)
{ {
// Setup SDL // Setup SDL
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMEPAD)) if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
{ {
printf("Error: SDL_Init(): %s\n", SDL_GetError()); printf("Error: SDL_Init(): %s\n", SDL_GetError());
return -1; return -1;

View File

@ -0,0 +1,14 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
@set OUT_EXE=example_sdl3_vulkan
@set INCLUDES=/I..\.. /I..\..\backends /I%SDL3_DIR%\include /I %VULKAN_SDK%\include
@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl3.cpp ..\..\backends\imgui_impl_vulkan.cpp ..\..\imgui*.cpp
@set LIBS=/LIBPATH:%SDL3_DIR%\lib\x86 /libpath:%VULKAN_SDK%\lib32 SDL3.lib shell32.lib vulkan-1.lib
@set OUT_DIR=Debug
mkdir %OUT_DIR%
cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console
@set OUT_DIR=Release
@REM mkdir %OUT_DIR%
@REM cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console

View File

@ -0,0 +1,14 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars64.bat or vcvarsall.bat to setup command-line compiler.
@set OUT_EXE=example_sdl3_vulkan
@set INCLUDES=/I..\.. /I..\..\backends /I%SDL3_DIR%\include /I %VULKAN_SDK%\include
@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl3.cpp ..\..\backends\imgui_impl_vulkan.cpp ..\..\imgui*.cpp
@set LIBS=/LIBPATH:%SDL3_DIR%\lib\x64 /libpath:%VULKAN_SDK%\lib SDL3.lib shell32.lib vulkan-1.lib
@set OUT_DIR=Debug
mkdir %OUT_DIR%
cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console
@set OUT_DIR=Release
@REM mkdir %OUT_DIR%
@REM cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console

View File

@ -0,0 +1,190 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{663A7E89-1E42-4222-921C-177F5B5910DF}</ProjectGuid>
<RootNamespace>example_sdl3_vulkan</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>%VULKAN_SDK%\lib32;%SDL3_DIR%\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>vulkan-1.lib;SDL3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem>
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>%VULKAN_SDK%\lib;%SDL3_DIR%\lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>vulkan-1.lib;SDL3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem>
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck>
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>%VULKAN_SDK%\lib32;%SDL3_DIR%\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>vulkan-1.lib;SDL3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem>
<IgnoreSpecificDefaultLibraries>
</IgnoreSpecificDefaultLibraries>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BufferSecurityCheck>false</BufferSecurityCheck>
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>%VULKAN_SDK%\lib;%SDL3_DIR%\lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>vulkan-1.lib;SDL3.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Console</SubSystem>
<IgnoreSpecificDefaultLibraries>
</IgnoreSpecificDefaultLibraries>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\imgui.cpp" />
<ClCompile Include="..\..\imgui_demo.cpp" />
<ClCompile Include="..\..\imgui_draw.cpp" />
<ClCompile Include="..\..\imgui_tables.cpp" />
<ClCompile Include="..\..\imgui_widgets.cpp" />
<ClCompile Include="..\..\backends\imgui_impl_sdl3.cpp" />
<ClCompile Include="..\..\backends\imgui_impl_vulkan.cpp" />
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\imconfig.h" />
<ClInclude Include="..\..\imgui.h" />
<ClInclude Include="..\..\imgui_internal.h" />
<ClInclude Include="..\..\backends\imgui_impl_sdl3.h" />
<ClInclude Include="..\..\backends\imgui_impl_vulkan.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\misc\debuggers\imgui.natstepfilter" />
<None Include="..\..\misc\debuggers\imgui.natvis" />
<None Include="..\README.txt" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="imgui">
<UniqueIdentifier>{20b90ce4-7fcb-4731-b9a0-075f875de82d}</UniqueIdentifier>
</Filter>
<Filter Include="sources">
<UniqueIdentifier>{f18ab499-84e1-499f-8eff-9754361e0e52}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\imgui.cpp">
<Filter>imgui</Filter>
</ClCompile>
<ClCompile Include="..\..\imgui_demo.cpp">
<Filter>imgui</Filter>
</ClCompile>
<ClCompile Include="..\..\imgui_draw.cpp">
<Filter>imgui</Filter>
</ClCompile>
<ClCompile Include="..\..\backends\imgui_impl_sdl3.cpp">
<Filter>sources</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>sources</Filter>
</ClCompile>
<ClCompile Include="..\..\backends\imgui_impl_vulkan.cpp">
<Filter>sources</Filter>
</ClCompile>
<ClCompile Include="..\..\imgui_widgets.cpp">
<Filter>imgui</Filter>
</ClCompile>
<ClCompile Include="..\..\imgui_tables.cpp">
<Filter>imgui</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\imconfig.h">
<Filter>imgui</Filter>
</ClInclude>
<ClInclude Include="..\..\imgui.h">
<Filter>imgui</Filter>
</ClInclude>
<ClInclude Include="..\..\imgui_internal.h">
<Filter>imgui</Filter>
</ClInclude>
<ClInclude Include="..\..\backends\imgui_impl_sdl3.h">
<Filter>sources</Filter>
</ClInclude>
<ClInclude Include="..\..\backends\imgui_impl_vulkan.h">
<Filter>sources</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\README.txt" />
<None Include="..\..\misc\debuggers\imgui.natvis">
<Filter>imgui</Filter>
</None>
<None Include="..\..\misc\debuggers\imgui.natstepfilter">
<Filter>imgui</Filter>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,607 @@
// Dear ImGui: standalone example application for SDL3 + Vulkan
// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
// - Getting Started https://dearimgui.com/getting-started
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp
// Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app.
// - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h.
// You will use those if you want to use this rendering backend in your engine/app.
// - Helper ImGui_ImplVulkanH_XXX functions and structures are only used by this example (main.cpp) and by
// the backend itself (imgui_impl_vulkan.cpp), but should PROBABLY NOT be used by your own engine/app code.
// Read comments in imgui_impl_vulkan.h.
#include "imgui.h"
#include "imgui_impl_sdl3.h"
#include "imgui_impl_vulkan.h"
#include <stdio.h> // printf, fprintf
#include <stdlib.h> // abort
#include <SDL3/SDL.h>
#include <SDL3/SDL_vulkan.h>
// This example doesn't compile with Emscripten yet! Awaiting SDL3 support.
#ifdef __EMSCRIPTEN__
#include "../libs/emscripten/emscripten_mainloop_stub.h"
#endif
// Volk headers
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
#define VOLK_IMPLEMENTATION
#include <volk.h>
#endif
//#define APP_USE_UNLIMITED_FRAME_RATE
#ifdef _DEBUG
#define APP_USE_VULKAN_DEBUG_REPORT
#endif
// Data
static VkAllocationCallbacks* g_Allocator = nullptr;
static VkInstance g_Instance = VK_NULL_HANDLE;
static VkPhysicalDevice g_PhysicalDevice = VK_NULL_HANDLE;
static VkDevice g_Device = VK_NULL_HANDLE;
static uint32_t g_QueueFamily = (uint32_t)-1;
static VkQueue g_Queue = VK_NULL_HANDLE;
static VkDebugReportCallbackEXT g_DebugReport = VK_NULL_HANDLE;
static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE;
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
static ImGui_ImplVulkanH_Window g_MainWindowData;
static uint32_t g_MinImageCount = 2;
static bool g_SwapChainRebuild = false;
static void check_vk_result(VkResult err)
{
if (err == 0)
return;
fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err);
if (err < 0)
abort();
}
#ifdef APP_USE_VULKAN_DEBUG_REPORT
static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData)
{
(void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguments
fprintf(stderr, "[vulkan] Debug report from ObjectType: %i\nMessage: %s\n\n", objectType, pMessage);
return VK_FALSE;
}
#endif // APP_USE_VULKAN_DEBUG_REPORT
static bool IsExtensionAvailable(const ImVector<VkExtensionProperties>& properties, const char* extension)
{
for (const VkExtensionProperties& p : properties)
if (strcmp(p.extensionName, extension) == 0)
return true;
return false;
}
static VkPhysicalDevice SetupVulkan_SelectPhysicalDevice()
{
uint32_t gpu_count;
VkResult err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, nullptr);
check_vk_result(err);
IM_ASSERT(gpu_count > 0);
ImVector<VkPhysicalDevice> gpus;
gpus.resize(gpu_count);
err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus.Data);
check_vk_result(err);
// If a number >1 of GPUs got reported, find discrete GPU if present, or use first one available. This covers
// most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple
// dedicated GPUs) is out of scope of this sample.
for (VkPhysicalDevice& device : gpus)
{
VkPhysicalDeviceProperties properties;
vkGetPhysicalDeviceProperties(device, &properties);
if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
return device;
}
// Use first GPU (Integrated) is a Discrete one is not available.
if (gpu_count > 0)
return gpus[0];
return VK_NULL_HANDLE;
}
static void SetupVulkan(ImVector<const char*> instance_extensions)
{
VkResult err;
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
volkInitialize();
#endif
// Create Vulkan Instance
{
VkInstanceCreateInfo create_info = {};
create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
// Enumerate available extensions
uint32_t properties_count;
ImVector<VkExtensionProperties> properties;
vkEnumerateInstanceExtensionProperties(nullptr, &properties_count, nullptr);
properties.resize(properties_count);
err = vkEnumerateInstanceExtensionProperties(nullptr, &properties_count, properties.Data);
check_vk_result(err);
// Enable required extensions
if (IsExtensionAvailable(properties, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME))
instance_extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
#ifdef VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME
if (IsExtensionAvailable(properties, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME))
{
instance_extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
create_info.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
}
#endif
// Enabling validation layers
#ifdef APP_USE_VULKAN_DEBUG_REPORT
const char* layers[] = { "VK_LAYER_KHRONOS_validation" };
create_info.enabledLayerCount = 1;
create_info.ppEnabledLayerNames = layers;
instance_extensions.push_back("VK_EXT_debug_report");
#endif
// Create Vulkan Instance
create_info.enabledExtensionCount = (uint32_t)instance_extensions.Size;
create_info.ppEnabledExtensionNames = instance_extensions.Data;
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
check_vk_result(err);
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
volkLoadInstance(g_Instance);
#endif
// Setup the debug report callback
#ifdef APP_USE_VULKAN_DEBUG_REPORT
auto f_vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
IM_ASSERT(f_vkCreateDebugReportCallbackEXT != nullptr);
VkDebugReportCallbackCreateInfoEXT debug_report_ci = {};
debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
debug_report_ci.pfnCallback = debug_report;
debug_report_ci.pUserData = nullptr;
err = f_vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport);
check_vk_result(err);
#endif
}
// Select Physical Device (GPU)
g_PhysicalDevice = SetupVulkan_SelectPhysicalDevice();
// Select graphics queue family
{
uint32_t count;
vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, nullptr);
VkQueueFamilyProperties* queues = (VkQueueFamilyProperties*)malloc(sizeof(VkQueueFamilyProperties) * count);
vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, queues);
for (uint32_t i = 0; i < count; i++)
if (queues[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
{
g_QueueFamily = i;
break;
}
free(queues);
IM_ASSERT(g_QueueFamily != (uint32_t)-1);
}
// Create Logical Device (with 1 queue)
{
ImVector<const char*> device_extensions;
device_extensions.push_back("VK_KHR_swapchain");
// Enumerate physical device extension
uint32_t properties_count;
ImVector<VkExtensionProperties> properties;
vkEnumerateDeviceExtensionProperties(g_PhysicalDevice, nullptr, &properties_count, nullptr);
properties.resize(properties_count);
vkEnumerateDeviceExtensionProperties(g_PhysicalDevice, nullptr, &properties_count, properties.Data);
#ifdef VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME
if (IsExtensionAvailable(properties, VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME))
device_extensions.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME);
#endif
const float queue_priority[] = { 1.0f };
VkDeviceQueueCreateInfo queue_info[1] = {};
queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queue_info[0].queueFamilyIndex = g_QueueFamily;
queue_info[0].queueCount = 1;
queue_info[0].pQueuePriorities = queue_priority;
VkDeviceCreateInfo create_info = {};
create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
create_info.queueCreateInfoCount = sizeof(queue_info) / sizeof(queue_info[0]);
create_info.pQueueCreateInfos = queue_info;
create_info.enabledExtensionCount = (uint32_t)device_extensions.Size;
create_info.ppEnabledExtensionNames = device_extensions.Data;
err = vkCreateDevice(g_PhysicalDevice, &create_info, g_Allocator, &g_Device);
check_vk_result(err);
vkGetDeviceQueue(g_Device, g_QueueFamily, 0, &g_Queue);
}
// Create Descriptor Pool
// The example only requires a single combined image sampler descriptor for the font image and only uses one descriptor set (for that)
// If you wish to load e.g. additional textures you may need to alter pools sizes.
{
VkDescriptorPoolSize pool_sizes[] =
{
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1 },
};
VkDescriptorPoolCreateInfo pool_info = {};
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
pool_info.maxSets = 1;
pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes);
pool_info.pPoolSizes = pool_sizes;
err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool);
check_vk_result(err);
}
}
// All the ImGui_ImplVulkanH_XXX structures/functions are optional helpers used by the demo.
// Your real engine/app may not use them.
static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface, int width, int height)
{
wd->Surface = surface;
// Check for WSI support
VkBool32 res;
vkGetPhysicalDeviceSurfaceSupportKHR(g_PhysicalDevice, g_QueueFamily, wd->Surface, &res);
if (res != VK_TRUE)
{
fprintf(stderr, "Error no WSI support on physical device 0\n");
exit(-1);
}
// Select Surface Format
const VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM };
const VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(g_PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace);
// Select Present Mode
#ifdef APP_UNLIMITED_FRAME_RATE
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR };
#else
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_FIFO_KHR };
#endif
wd->PresentMode = ImGui_ImplVulkanH_SelectPresentMode(g_PhysicalDevice, wd->Surface, &present_modes[0], IM_ARRAYSIZE(present_modes));
//printf("[vulkan] Selected PresentMode = %d\n", wd->PresentMode);
// Create SwapChain, RenderPass, Framebuffer, etc.
IM_ASSERT(g_MinImageCount >= 2);
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount);
}
static void CleanupVulkan()
{
vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator);
#ifdef APP_USE_VULKAN_DEBUG_REPORT
// Remove the debug report callback
auto f_vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT");
f_vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator);
#endif // APP_USE_VULKAN_DEBUG_REPORT
vkDestroyDevice(g_Device, g_Allocator);
vkDestroyInstance(g_Instance, g_Allocator);
}
static void CleanupVulkanWindow()
{
ImGui_ImplVulkanH_DestroyWindow(g_Instance, g_Device, &g_MainWindowData, g_Allocator);
}
static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
{
VkResult err;
VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore;
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
{
g_SwapChainRebuild = true;
return;
}
check_vk_result(err);
ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex];
{
err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); // wait indefinitely instead of periodically checking
check_vk_result(err);
err = vkResetFences(g_Device, 1, &fd->Fence);
check_vk_result(err);
}
{
err = vkResetCommandPool(g_Device, fd->CommandPool, 0);
check_vk_result(err);
VkCommandBufferBeginInfo info = {};
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
err = vkBeginCommandBuffer(fd->CommandBuffer, &info);
check_vk_result(err);
}
{
VkRenderPassBeginInfo info = {};
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
info.renderPass = wd->RenderPass;
info.framebuffer = fd->Framebuffer;
info.renderArea.extent.width = wd->Width;
info.renderArea.extent.height = wd->Height;
info.clearValueCount = 1;
info.pClearValues = &wd->ClearValue;
vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE);
}
// Record dear imgui primitives into command buffer
ImGui_ImplVulkan_RenderDrawData(draw_data, fd->CommandBuffer);
// Submit command buffer
vkCmdEndRenderPass(fd->CommandBuffer);
{
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkSubmitInfo info = {};
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
info.waitSemaphoreCount = 1;
info.pWaitSemaphores = &image_acquired_semaphore;
info.pWaitDstStageMask = &wait_stage;
info.commandBufferCount = 1;
info.pCommandBuffers = &fd->CommandBuffer;
info.signalSemaphoreCount = 1;
info.pSignalSemaphores = &render_complete_semaphore;
err = vkEndCommandBuffer(fd->CommandBuffer);
check_vk_result(err);
err = vkQueueSubmit(g_Queue, 1, &info, fd->Fence);
check_vk_result(err);
}
}
static void FramePresent(ImGui_ImplVulkanH_Window* wd)
{
if (g_SwapChainRebuild)
return;
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
VkPresentInfoKHR info = {};
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
info.waitSemaphoreCount = 1;
info.pWaitSemaphores = &render_complete_semaphore;
info.swapchainCount = 1;
info.pSwapchains = &wd->Swapchain;
info.pImageIndices = &wd->FrameIndex;
VkResult err = vkQueuePresentKHR(g_Queue, &info);
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
{
g_SwapChainRebuild = true;
return;
}
check_vk_result(err);
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores
}
// Main code
int main(int, char**)
{
// Setup SDL
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD) != 0)
{
printf("Error: SDL_Init(): %s\n", SDL_GetError());
return -1;
}
// Create window with Vulkan graphics context
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_HIDDEN);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+Vulkan example", 1280, 720, window_flags);
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
}
ImVector<const char*> extensions;
{
uint32_t sdl_extensions_count = 0;
const char* const* sdl_extensions = SDL_Vulkan_GetInstanceExtensions(&sdl_extensions_count);
for (uint32_t n = 0; n < sdl_extensions_count; n++)
extensions.push_back(sdl_extensions[n]);
}
SetupVulkan(extensions);
// Create Window Surface
VkSurfaceKHR surface;
VkResult err;
if (SDL_Vulkan_CreateSurface(window, g_Instance, g_Allocator, &surface) == 0)
{
printf("Failed to create Vulkan surface.\n");
return 1;
}
// Create Framebuffers
int w, h;
SDL_GetWindowSize(window, &w, &h);
ImGui_ImplVulkanH_Window* wd = &g_MainWindowData;
SetupVulkanWindow(wd, surface, w, h);
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
SDL_ShowWindow(window);
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
//io.ConfigFlags |= ImGuiConfigFlags_ViewportsNoTaskBarIcons;
//io.ConfigFlags |= ImGuiConfigFlags_ViewportsNoMerge;
// Setup Dear ImGui style
ImGui::StyleColorsDark();
//ImGui::StyleColorsLight();
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
ImGuiStyle& style = ImGui::GetStyle();
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
style.WindowRounding = 0.0f;
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
}
// Setup Platform/Renderer backends
ImGui_ImplSDL3_InitForVulkan(window);
ImGui_ImplVulkan_InitInfo init_info = {};
init_info.Instance = g_Instance;
init_info.PhysicalDevice = g_PhysicalDevice;
init_info.Device = g_Device;
init_info.QueueFamily = g_QueueFamily;
init_info.Queue = g_Queue;
init_info.PipelineCache = g_PipelineCache;
init_info.DescriptorPool = g_DescriptorPool;
init_info.RenderPass = wd->RenderPass;
init_info.Subpass = 0;
init_info.MinImageCount = g_MinImageCount;
init_info.ImageCount = wd->ImageCount;
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
init_info.Allocator = g_Allocator;
init_info.CheckVkResultFn = check_vk_result;
ImGui_ImplVulkan_Init(&init_info);
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
// - Read 'docs/FONTS.md' for more instructions and details.
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
//io.Fonts->AddFontDefault();
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
//IM_ASSERT(font != nullptr);
// Our state
bool show_demo_window = true;
bool show_another_window = false;
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
// Main loop
bool done = false;
while (!done)
{
// Poll and handle events (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
SDL_Event event;
while (SDL_PollEvent(&event))
{
ImGui_ImplSDL3_ProcessEvent(&event);
if (event.type == SDL_EVENT_QUIT)
done = true;
if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window))
done = true;
}
if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)
{
SDL_Delay(10);
continue;
}
// Resize swap chain?
int fb_width, fb_height;
SDL_GetWindowSize(window, &fb_width, &fb_height);
if (fb_width > 0 && fb_height > 0 && (g_SwapChainRebuild || g_MainWindowData.Width != fb_width || g_MainWindowData.Height != fb_height))
{
ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount);
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, fb_width, fb_height, g_MinImageCount);
g_MainWindowData.FrameIndex = 0;
g_SwapChainRebuild = false;
}
// Start the Dear ImGui frame
ImGui_ImplVulkan_NewFrame();
ImGui_ImplSDL3_NewFrame();
ImGui::NewFrame();
// 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).
if (show_demo_window)
ImGui::ShowDemoWindow(&show_demo_window);
// 2. Show a simple window that we create ourselves. We use a Begin/End pair to create a named window.
{
static float f = 0.0f;
static int counter = 0;
ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it.
ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too)
ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state
ImGui::Checkbox("Another Window", &show_another_window);
ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated)
counter++;
ImGui::SameLine();
ImGui::Text("counter = %d", counter);
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
ImGui::End();
}
// 3. Show another simple window.
if (show_another_window)
{
ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
ImGui::Text("Hello from another window!");
if (ImGui::Button("Close Me"))
show_another_window = false;
ImGui::End();
}
// Rendering
ImGui::Render();
ImDrawData* main_draw_data = ImGui::GetDrawData();
const bool main_is_minimized = (main_draw_data->DisplaySize.x <= 0.0f || main_draw_data->DisplaySize.y <= 0.0f);
wd->ClearValue.color.float32[0] = clear_color.x * clear_color.w;
wd->ClearValue.color.float32[1] = clear_color.y * clear_color.w;
wd->ClearValue.color.float32[2] = clear_color.z * clear_color.w;
wd->ClearValue.color.float32[3] = clear_color.w;
if (!main_is_minimized)
FrameRender(wd, main_draw_data);
// Update and Render additional Platform Windows
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault();
}
// Present Main Platform Window
if (!main_is_minimized)
FramePresent(wd);
}
// Cleanup
err = vkDeviceWaitIdle(g_Device);
check_vk_result(err);
ImGui_ImplVulkan_Shutdown();
ImGui_ImplSDL3_Shutdown();
ImGui::DestroyContext();
CleanupVulkanWindow();
CleanupVulkan();
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}

View File

@ -1,9 +1,8 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. @REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
@REM Important: to build on 32-bit systems, the DX12 backends needs '#define ImTextureID ImU64', so we pass it here.
@set OUT_DIR=Debug @set OUT_DIR=Debug
@set OUT_EXE=example_win32_directx12 @set OUT_EXE=example_win32_directx12
@set INCLUDES=/I..\.. /I..\..\backends /I "%WindowsSdkDir%Include\um" /I "%WindowsSdkDir%Include\shared" @set INCLUDES=/I..\.. /I..\..\backends /I "%WindowsSdkDir%Include\um" /I "%WindowsSdkDir%Include\shared"
@set SOURCES=main.cpp ..\..\backends\imgui_impl_dx12.cpp ..\..\backends\imgui_impl_win32.cpp ..\..\imgui*.cpp @set SOURCES=main.cpp ..\..\backends\imgui_impl_dx12.cpp ..\..\backends\imgui_impl_win32.cpp ..\..\imgui*.cpp
@set LIBS=d3d12.lib d3dcompiler.lib dxgi.lib @set LIBS=d3d12.lib d3dcompiler.lib dxgi.lib
mkdir Debug mkdir Debug
cl /nologo /Zi /MD /utf-8 %INCLUDES% /D ImTextureID=ImU64 /D UNICODE /D _UNICODE %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% cl /nologo /Zi /MD /utf-8 %INCLUDES% /D UNICODE /D _UNICODE %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%

View File

@ -21,7 +21,7 @@
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{b4cf9797-519d-4afe-a8f4-5141a6b521d3}</ProjectGuid> <ProjectGuid>{b4cf9797-519d-4afe-a8f4-5141a6b521d3}</ProjectGuid>
<RootNamespace>example_win32_directx12</RootNamespace> <RootNamespace>example_win32_directx12</RootNamespace>
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0.20348.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@ -87,7 +87,7 @@
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>ImTextureID=ImU64;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
@ -102,7 +102,7 @@
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>ImTextureID=ImU64;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
@ -119,7 +119,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>ImTextureID=ImU64;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
@ -138,7 +138,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>ImTextureID=ImU64;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>

View File

@ -6,10 +6,6 @@
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder). // - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
// - Introduction, links and more at the top of imgui.cpp // - Introduction, links and more at the top of imgui.cpp
// Important: to compile on 32-bit systems, the DirectX12 backend requires code to be compiled with '#define ImTextureID ImU64'.
// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
// This define is set in the example .vcxproj file and need to be replicated in your app or by adding it to your imconfig.h file.
#include "imgui.h" #include "imgui.h"
#include "imgui_impl_win32.h" #include "imgui_impl_win32.h"
#include "imgui_impl_dx12.h" #include "imgui_impl_dx12.h"

View File

@ -33,6 +33,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl3_opengl3", "exa
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl3_sdlrenderer3", "example_sdl3_sdlrenderer3\example_sdl3_sdlrenderer3.vcxproj", "{C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl3_sdlrenderer3", "example_sdl3_sdlrenderer3\example_sdl3_sdlrenderer3.vcxproj", "{C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl3_vulkan", "example_sdl3_vulkan\example_sdl3_vulkan.vcxproj", "{663A7E89-1E42-4222-921C-177F5B5910DF}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32
@ -161,6 +163,14 @@ Global
{C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Release|Win32.Build.0 = Release|Win32 {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Release|Win32.Build.0 = Release|Win32
{C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Release|x64.ActiveCfg = Release|x64 {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Release|x64.ActiveCfg = Release|x64
{C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Release|x64.Build.0 = Release|x64 {C0290D21-3AD2-4A35-ABBC-A2F5F48326DA}.Release|x64.Build.0 = Release|x64
{663A7E89-1E42-4222-921C-177F5B5910DF}.Debug|Win32.ActiveCfg = Debug|Win32
{663A7E89-1E42-4222-921C-177F5B5910DF}.Debug|Win32.Build.0 = Debug|Win32
{663A7E89-1E42-4222-921C-177F5B5910DF}.Debug|x64.ActiveCfg = Debug|x64
{663A7E89-1E42-4222-921C-177F5B5910DF}.Debug|x64.Build.0 = Debug|x64
{663A7E89-1E42-4222-921C-177F5B5910DF}.Release|Win32.ActiveCfg = Release|Win32
{663A7E89-1E42-4222-921C-177F5B5910DF}.Release|Win32.Build.0 = Release|Win32
{663A7E89-1E42-4222-921C-177F5B5910DF}.Release|x64.ActiveCfg = Release|x64
{663A7E89-1E42-4222-921C-177F5B5910DF}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -29,7 +29,6 @@
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names. //---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names.
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS //#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
//#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87+ disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This is automatically done by IMGUI_DISABLE_OBSOLETE_FUNCTIONS.
//---- Disable all of Dear ImGui or don't implement standard windows/tools. //---- Disable all of Dear ImGui or don't implement standard windows/tools.
// It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp. // It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp.
@ -83,10 +82,13 @@
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'. // On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
//#define IMGUI_ENABLE_FREETYPE //#define IMGUI_ENABLE_FREETYPE
//---- Use FreeType+lunasvg library to render OpenType SVG fonts (SVGinOT) //---- Use FreeType + plutosvg or lunasvg to render OpenType SVG fonts (SVGinOT)
// Requires lunasvg headers to be available in the include path + program to be linked with the lunasvg library (not provided).
// Only works in combination with IMGUI_ENABLE_FREETYPE. // Only works in combination with IMGUI_ENABLE_FREETYPE.
// (implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement) // - lunasvg is currently easier to acquire/install, as e.g. it is part of vcpkg.
// - plutosvg will support more fonts and may load them faster. It currently requires to be built manually but it is fairly easy. See misc/freetype/README for instructions.
// - Both require headers to be available in the include path + program to be linked with the library code (not provided).
// - (note: lunasvg implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement)
//#define IMGUI_ENABLE_FREETYPE_PLUTOSVG
//#define IMGUI_ENABLE_FREETYPE_LUNASVG //#define IMGUI_ENABLE_FREETYPE_LUNASVG
//---- Use stb_truetype to build and rasterize the font atlas (default) //---- Use stb_truetype to build and rasterize the font atlas (default)

1388
imgui.cpp

File diff suppressed because it is too large Load Diff

255
imgui.h
View File

@ -1,4 +1,4 @@
// dear imgui, v1.91.2 WIP // dear imgui, v1.91.5
// (headers) // (headers)
// Help: // Help:
@ -28,8 +28,8 @@
// Library Version // Library Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
#define IMGUI_VERSION "1.91.2 WIP" #define IMGUI_VERSION "1.91.5"
#define IMGUI_VERSION_NUM 19115 #define IMGUI_VERSION_NUM 19150
#define IMGUI_HAS_TABLE #define IMGUI_HAS_TABLE
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch #define IMGUI_HAS_VIEWPORT // Viewport WIP branch
#define IMGUI_HAS_DOCK // Docking WIP branch #define IMGUI_HAS_DOCK // Docking WIP branch
@ -132,15 +132,16 @@ Index of this file:
#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' #pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx'
#endif #endif
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx' #pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
#pragma clang diagnostic ignored "-Wold-style-cast" #pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe #pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant
#pragma clang diagnostic ignored "-Wreserved-identifier" // warning: identifier '_Xxx' is reserved because it starts with '_' followed by a capital letter #pragma clang diagnostic ignored "-Wreserved-identifier" // warning: identifier '_Xxx' is reserved because it starts with '_' followed by a capital letter
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
#pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type
#elif defined(__GNUC__) #elif defined(__GNUC__)
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead #pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
#endif #endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -254,8 +255,10 @@ typedef int ImGuiWindowFlags; // -> enum ImGuiWindowFlags_ // Flags: f
// ImTexture: user data for renderer backend to identify a texture [Compile-time configurable type] // ImTexture: user data for renderer backend to identify a texture [Compile-time configurable type]
// - To use something else than an opaque void* pointer: override with e.g. '#define ImTextureID MyTextureType*' in your imconfig.h file. // - To use something else than an opaque void* pointer: override with e.g. '#define ImTextureID MyTextureType*' in your imconfig.h file.
// - This can be whatever to you want it to be! read the FAQ about ImTextureID for details. // - This can be whatever to you want it to be! read the FAQ about ImTextureID for details.
// - You can make this a structure with various constructors if you need. You will have to implement ==/!= operators.
// - (note: before v1.91.4 (2024/10/08) the default type for ImTextureID was void*. Use intermediary intptr_t cast and read FAQ if you have casting warnings)
#ifndef ImTextureID #ifndef ImTextureID
typedef void* ImTextureID; // Default: store a pointer or an integer fitting in a pointer (most renderer backends are ok with that) typedef ImU64 ImTextureID; // Default: store a pointer or an integer fitting in a pointer (most renderer backends are ok with that)
#endif #endif
// ImDrawIdx: vertex index. [Compile-time configurable type] // ImDrawIdx: vertex index. [Compile-time configurable type]
@ -587,7 +590,7 @@ namespace ImGui
// the array syntax is just a way to document the number of elements that are expected to be accessible. You can pass address of your first element out of a contiguous set, e.g. &myvector.x // the array syntax is just a way to document the number of elements that are expected to be accessible. You can pass address of your first element out of a contiguous set, e.g. &myvector.x
// - Adjust format string to decorate the value with a prefix, a suffix, or adapt the editing and display precision e.g. "%.3f" -> 1.234; "%5.2f secs" -> 01.23 secs; "Biscuit: %.0f" -> Biscuit: 1; etc. // - Adjust format string to decorate the value with a prefix, a suffix, or adapt the editing and display precision e.g. "%.3f" -> 1.234; "%5.2f secs" -> 01.23 secs; "Biscuit: %.0f" -> Biscuit: 1; etc.
// - Format string may also be set to NULL or use the default format ("%f" or "%d"). // - Format string may also be set to NULL or use the default format ("%f" or "%d").
// - Speed are per-pixel of mouse movement (v_speed=0.2f: mouse needs to move by 5 pixels to increase value by 1). For gamepad/keyboard navigation, minimum speed is Max(v_speed, minimum_step_at_given_precision). // - Speed are per-pixel of mouse movement (v_speed=0.2f: mouse needs to move by 5 pixels to increase value by 1). For keyboard/gamepad navigation, minimum speed is Max(v_speed, minimum_step_at_given_precision).
// - Use v_min < v_max to clamp edits to given limits. Note that CTRL+Click manual input can override those limits if ImGuiSliderFlags_AlwaysClamp is not used. // - Use v_min < v_max to clamp edits to given limits. Note that CTRL+Click manual input can override those limits if ImGuiSliderFlags_AlwaysClamp is not used.
// - Use v_max = FLT_MAX / INT_MAX etc to avoid clamping to a maximum, same with v_min = -FLT_MAX / INT_MIN to avoid clamping to a minimum. // - Use v_max = FLT_MAX / INT_MAX etc to avoid clamping to a maximum, same with v_min = -FLT_MAX / INT_MIN to avoid clamping to a minimum.
// - We use the same sets of flags for DragXXX() and SliderXXX() functions as the features are the same and it makes it easier to swap them. // - We use the same sets of flags for DragXXX() and SliderXXX() functions as the features are the same and it makes it easier to swap them.
@ -916,7 +919,7 @@ namespace ImGui
// - Disable all user interactions and dim items visuals (applying style.DisabledAlpha over current colors) // - Disable all user interactions and dim items visuals (applying style.DisabledAlpha over current colors)
// - Those can be nested but it cannot be used to enable an already disabled section (a single BeginDisabled(true) in the stack is enough to keep everything disabled) // - Those can be nested but it cannot be used to enable an already disabled section (a single BeginDisabled(true) in the stack is enough to keep everything disabled)
// - Tooltips windows by exception are opted out of disabling. // - Tooltips windows by exception are opted out of disabling.
// - BeginDisabled(false) essentially does nothing useful but is provided to facilitate use of boolean expressions. If you can avoid calling BeginDisabled(False)/EndDisabled() best to avoid it. // - BeginDisabled(false)/EndDisabled() essentially does nothing but is provided to facilitate use of boolean expressions (as a micro-optimization: if you have tens of thousands of BeginDisabled(false)/EndDisabled() pairs, you might want to reformulate your code to avoid making those calls)
IMGUI_API void BeginDisabled(bool disabled = true); IMGUI_API void BeginDisabled(bool disabled = true);
IMGUI_API void EndDisabled(); IMGUI_API void EndDisabled();
@ -926,10 +929,12 @@ namespace ImGui
IMGUI_API void PopClipRect(); IMGUI_API void PopClipRect();
// Focus, Activation // Focus, Activation
// - Prefer using "SetItemDefaultFocus()" over "if (IsWindowAppearing()) SetScrollHereY()" when applicable to signify "this is the default item" IMGUI_API void SetItemDefaultFocus(); // make last item the default focused item of of a newly appearing window.
IMGUI_API void SetItemDefaultFocus(); // make last item the default focused item of a window.
IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget. IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget.
// Keyboard/Gamepad Navigation
IMGUI_API void SetNavCursorVisible(bool visible); // alter visibility of keyboard/gamepad cursor. by default: show when using an arrow key, hide when clicking with mouse.
// Overlapping mode // Overlapping mode
IMGUI_API void SetNextItemAllowOverlap(); // allow next item to be overlapped by a subsequent item. Useful with invisible buttons, selectable, treenode covering an area where subsequent items may need to be added. Note that both Selectable() and TreeNode() have dedicated flags doing this. IMGUI_API void SetNextItemAllowOverlap(); // allow next item to be overlapped by a subsequent item. Useful with invisible buttons, selectable, treenode covering an area where subsequent items may need to be added. Note that both Selectable() and TreeNode() have dedicated flags doing this.
@ -985,9 +990,8 @@ namespace ImGui
// Inputs Utilities: Keyboard/Mouse/Gamepad // Inputs Utilities: Keyboard/Mouse/Gamepad
// - the ImGuiKey enum contains all possible keyboard, mouse and gamepad inputs (e.g. ImGuiKey_A, ImGuiKey_MouseLeft, ImGuiKey_GamepadDpadUp...). // - the ImGuiKey enum contains all possible keyboard, mouse and gamepad inputs (e.g. ImGuiKey_A, ImGuiKey_MouseLeft, ImGuiKey_GamepadDpadUp...).
// - before v1.87, we used ImGuiKey to carry native/user indices as defined by each backends. About use of those legacy ImGuiKey values: // - (legacy: before v1.87, we used ImGuiKey to carry native/user indices as defined by each backends. This was obsoleted in 1.87 (2022-02) and completely removed in 1.91.5 (2024-11). See https://github.com/ocornut/imgui/issues/4921)
// - without IMGUI_DISABLE_OBSOLETE_KEYIO (legacy support): you can still use your legacy native/user indices (< 512) according to how your backend/engine stored them in io.KeysDown[], but need to cast them to ImGuiKey. // - (legacy: any use of ImGuiKey will assert when key < 512 to detect passing legacy native/user indices)
// - with IMGUI_DISABLE_OBSOLETE_KEYIO (this is the way forward): any use of ImGuiKey will assert with key < 512. GetKeyIndex() is pass-through and therefore deprecated (gone if IMGUI_DISABLE_OBSOLETE_KEYIO is defined).
IMGUI_API bool IsKeyDown(ImGuiKey key); // is key being held. IMGUI_API bool IsKeyDown(ImGuiKey key); // is key being held.
IMGUI_API bool IsKeyPressed(ImGuiKey key, bool repeat = true); // was key pressed (went from !Down to Down)? if repeat=true, uses io.KeyRepeatDelay / KeyRepeatRate IMGUI_API bool IsKeyPressed(ImGuiKey key, bool repeat = true); // was key pressed (went from !Down to Down)? if repeat=true, uses io.KeyRepeatDelay / KeyRepeatRate
IMGUI_API bool IsKeyReleased(ImGuiKey key); // was key released (went from Down to !Down)? IMGUI_API bool IsKeyReleased(ImGuiKey key); // was key released (went from Down to !Down)?
@ -1022,7 +1026,7 @@ namespace ImGui
// - Many related features are still in imgui_internal.h. For instance, most IsKeyXXX()/IsMouseXXX() functions have an owner-id-aware version. // - Many related features are still in imgui_internal.h. For instance, most IsKeyXXX()/IsMouseXXX() functions have an owner-id-aware version.
IMGUI_API void SetItemKeyOwner(ImGuiKey key); // Set key owner to last item ID if it is hovered or active. Equivalent to 'if (IsItemHovered() || IsItemActive()) { SetKeyOwner(key, GetItemID());'. IMGUI_API void SetItemKeyOwner(ImGuiKey key); // Set key owner to last item ID if it is hovered or active. Equivalent to 'if (IsItemHovered() || IsItemActive()) { SetKeyOwner(key, GetItemID());'.
// Inputs Utilities: Mouse specific // Inputs Utilities: Mouse
// - To refer to a mouse button, you may use named enums in your code e.g. ImGuiMouseButton_Left, ImGuiMouseButton_Right. // - To refer to a mouse button, you may use named enums in your code e.g. ImGuiMouseButton_Left, ImGuiMouseButton_Right.
// - You can also use regular integer: it is forever guaranteed that 0=Left, 1=Right, 2=Middle. // - You can also use regular integer: it is forever guaranteed that 0=Left, 1=Right, 2=Middle.
// - Dragging operations are only reported after mouse has moved a certain distance away from the initial clicking position (see 'lock_threshold' and 'io.MouseDraggingThreshold') // - Dragging operations are only reported after mouse has moved a certain distance away from the initial clicking position (see 'lock_threshold' and 'io.MouseDraggingThreshold')
@ -1113,8 +1117,8 @@ enum ImGuiWindowFlags_
ImGuiWindowFlags_NoBringToFrontOnFocus = 1 << 13, // Disable bringing window to front when taking focus (e.g. clicking on it or programmatically giving it focus) ImGuiWindowFlags_NoBringToFrontOnFocus = 1 << 13, // Disable bringing window to front when taking focus (e.g. clicking on it or programmatically giving it focus)
ImGuiWindowFlags_AlwaysVerticalScrollbar= 1 << 14, // Always show vertical scrollbar (even if ContentSize.y < Size.y) ImGuiWindowFlags_AlwaysVerticalScrollbar= 1 << 14, // Always show vertical scrollbar (even if ContentSize.y < Size.y)
ImGuiWindowFlags_AlwaysHorizontalScrollbar=1<< 15, // Always show horizontal scrollbar (even if ContentSize.x < Size.x) ImGuiWindowFlags_AlwaysHorizontalScrollbar=1<< 15, // Always show horizontal scrollbar (even if ContentSize.x < Size.x)
ImGuiWindowFlags_NoNavInputs = 1 << 16, // No gamepad/keyboard navigation within the window ImGuiWindowFlags_NoNavInputs = 1 << 16, // No keyboard/gamepad navigation within the window
ImGuiWindowFlags_NoNavFocus = 1 << 17, // No focusing toward this window with gamepad/keyboard navigation (e.g. skipped by CTRL+TAB) ImGuiWindowFlags_NoNavFocus = 1 << 17, // No focusing toward this window with keyboard/gamepad navigation (e.g. skipped by CTRL+TAB)
ImGuiWindowFlags_UnsavedDocument = 1 << 18, // Display a dot next to the title. When used in a tab/docking context, tab is selected when clicking the X + closure is not assumed (will wait for user to stop submitting the tab). Otherwise closure is assumed when pressing the X, so if you keep submitting the tab may reappear at end of tab bar. ImGuiWindowFlags_UnsavedDocument = 1 << 18, // Display a dot next to the title. When used in a tab/docking context, tab is selected when clicking the X + closure is not assumed (will wait for user to stop submitting the tab). Otherwise closure is assumed when pressing the X, so if you keep submitting the tab may reappear at end of tab bar.
ImGuiWindowFlags_NoDocking = 1 << 19, // Disable docking of this window ImGuiWindowFlags_NoDocking = 1 << 19, // Disable docking of this window
ImGuiWindowFlags_NoNav = ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus, ImGuiWindowFlags_NoNav = ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus,
@ -1156,7 +1160,7 @@ enum ImGuiChildFlags_
ImGuiChildFlags_AutoResizeY = 1 << 5, // Enable auto-resizing height. Read "IMPORTANT: Size measurement" details above. ImGuiChildFlags_AutoResizeY = 1 << 5, // Enable auto-resizing height. Read "IMPORTANT: Size measurement" details above.
ImGuiChildFlags_AlwaysAutoResize = 1 << 6, // Combined with AutoResizeX/AutoResizeY. Always measure size even when child is hidden, always return true, always disable clipping optimization! NOT RECOMMENDED. ImGuiChildFlags_AlwaysAutoResize = 1 << 6, // Combined with AutoResizeX/AutoResizeY. Always measure size even when child is hidden, always return true, always disable clipping optimization! NOT RECOMMENDED.
ImGuiChildFlags_FrameStyle = 1 << 7, // Style the child window like a framed item: use FrameBg, FrameRounding, FrameBorderSize, FramePadding instead of ChildBg, ChildRounding, ChildBorderSize, WindowPadding. ImGuiChildFlags_FrameStyle = 1 << 7, // Style the child window like a framed item: use FrameBg, FrameRounding, FrameBorderSize, FramePadding instead of ChildBg, ChildRounding, ChildBorderSize, WindowPadding.
ImGuiChildFlags_NavFlattened = 1 << 8, // [BETA] Share focus scope, allow gamepad/keyboard navigation to cross over parent border to this child or between sibling child windows. ImGuiChildFlags_NavFlattened = 1 << 8, // [BETA] Share focus scope, allow keyboard/gamepad navigation to cross over parent border to this child or between sibling child windows.
// Obsolete names // Obsolete names
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
@ -1191,7 +1195,7 @@ enum ImGuiInputTextFlags_
// Inputs // Inputs
ImGuiInputTextFlags_AllowTabInput = 1 << 5, // Pressing TAB input a '\t' character into the text field ImGuiInputTextFlags_AllowTabInput = 1 << 5, // Pressing TAB input a '\t' character into the text field
ImGuiInputTextFlags_EnterReturnsTrue = 1 << 6, // Return 'true' when Enter is pressed (as opposed to every time the value was modified). Consider looking at the IsItemDeactivatedAfterEdit() function. ImGuiInputTextFlags_EnterReturnsTrue = 1 << 6, // Return 'true' when Enter is pressed (as opposed to every time the value was modified). Consider using IsItemDeactivatedAfterEdit() instead!
ImGuiInputTextFlags_EscapeClearsAll = 1 << 7, // Escape key clears content if not empty, and deactivate otherwise (contrast to default behavior of Escape to revert) ImGuiInputTextFlags_EscapeClearsAll = 1 << 7, // Escape key clears content if not empty, and deactivate otherwise (contrast to default behavior of Escape to revert)
ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 8, // In multi-line mode, validate with Enter, add new line with Ctrl+Enter (default is opposite: validate with Ctrl+Enter, add line with Enter). ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 8, // In multi-line mode, validate with Enter, add new line with Ctrl+Enter (default is opposite: validate with Ctrl+Enter, add line with Enter).
@ -1363,7 +1367,7 @@ enum ImGuiHoveredFlags_
ImGuiHoveredFlags_AllowWhenOverlappedByItem = 1 << 8, // IsItemHovered() only: Return true even if the item uses AllowOverlap mode and is overlapped by another hoverable item. ImGuiHoveredFlags_AllowWhenOverlappedByItem = 1 << 8, // IsItemHovered() only: Return true even if the item uses AllowOverlap mode and is overlapped by another hoverable item.
ImGuiHoveredFlags_AllowWhenOverlappedByWindow = 1 << 9, // IsItemHovered() only: Return true even if the position is obstructed or overlapped by another window. ImGuiHoveredFlags_AllowWhenOverlappedByWindow = 1 << 9, // IsItemHovered() only: Return true even if the position is obstructed or overlapped by another window.
ImGuiHoveredFlags_AllowWhenDisabled = 1 << 10, // IsItemHovered() only: Return true even if the item is disabled ImGuiHoveredFlags_AllowWhenDisabled = 1 << 10, // IsItemHovered() only: Return true even if the item is disabled
ImGuiHoveredFlags_NoNavOverride = 1 << 11, // IsItemHovered() only: Disable using gamepad/keyboard navigation state when active, always query mouse ImGuiHoveredFlags_NoNavOverride = 1 << 11, // IsItemHovered() only: Disable using keyboard/gamepad navigation state when active, always query mouse
ImGuiHoveredFlags_AllowWhenOverlapped = ImGuiHoveredFlags_AllowWhenOverlappedByItem | ImGuiHoveredFlags_AllowWhenOverlappedByWindow, ImGuiHoveredFlags_AllowWhenOverlapped = ImGuiHoveredFlags_AllowWhenOverlappedByItem | ImGuiHoveredFlags_AllowWhenOverlappedByWindow,
ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped, ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped,
ImGuiHoveredFlags_RootAndChildWindows = ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows, ImGuiHoveredFlags_RootAndChildWindows = ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows,
@ -1471,21 +1475,18 @@ enum ImGuiSortDirection : ImU8
ImGuiSortDirection_Descending = 2 // Descending = 9->0, Z->A etc. ImGuiSortDirection_Descending = 2 // Descending = 9->0, Z->A etc.
}; };
// Since 1.90, defining IMGUI_DISABLE_OBSOLETE_FUNCTIONS automatically defines IMGUI_DISABLE_OBSOLETE_KEYIO as well.
#if defined(IMGUI_DISABLE_OBSOLETE_FUNCTIONS) && !defined(IMGUI_DISABLE_OBSOLETE_KEYIO)
#define IMGUI_DISABLE_OBSOLETE_KEYIO
#endif
// A key identifier (ImGuiKey_XXX or ImGuiMod_XXX value): can represent Keyboard, Mouse and Gamepad values. // A key identifier (ImGuiKey_XXX or ImGuiMod_XXX value): can represent Keyboard, Mouse and Gamepad values.
// All our named keys are >= 512. Keys value 0 to 511 are left unused as legacy native/opaque key values (< 1.87). // All our named keys are >= 512. Keys value 0 to 511 are left unused and were legacy native/opaque key values (< 1.87).
// Since >= 1.89 we increased typing (went from int to enum), some legacy code may need a cast to ImGuiKey. // Support for legacy keys was completely removed in 1.91.5.
// Read details about the 1.87 and 1.89 transition : https://github.com/ocornut/imgui/issues/4921 // Read details about the 1.87+ transition : https://github.com/ocornut/imgui/issues/4921
// Note that "Keys" related to physical keys and are not the same concept as input "Characters", the later are submitted via io.AddInputCharacter(). // Note that "Keys" related to physical keys and are not the same concept as input "Characters", the later are submitted via io.AddInputCharacter().
// The keyboard key enum values are named after the keys on a standard US keyboard, and on other keyboard types the keys reported may not match the keycaps. // The keyboard key enum values are named after the keys on a standard US keyboard, and on other keyboard types the keys reported may not match the keycaps.
enum ImGuiKey : int enum ImGuiKey : int
{ {
// Keyboard // Keyboard
ImGuiKey_None = 0, ImGuiKey_None = 0,
ImGuiKey_NamedKey_BEGIN = 512, // First valid key value (other than 0)
ImGuiKey_Tab = 512, // == ImGuiKey_NamedKey_BEGIN ImGuiKey_Tab = 512, // == ImGuiKey_NamedKey_BEGIN
ImGuiKey_LeftArrow, ImGuiKey_LeftArrow,
ImGuiKey_RightArrow, ImGuiKey_RightArrow,
@ -1573,7 +1574,7 @@ enum ImGuiKey : int
// [Internal] Reserved for mod storage // [Internal] Reserved for mod storage
ImGuiKey_ReservedForModCtrl, ImGuiKey_ReservedForModShift, ImGuiKey_ReservedForModAlt, ImGuiKey_ReservedForModSuper, ImGuiKey_ReservedForModCtrl, ImGuiKey_ReservedForModShift, ImGuiKey_ReservedForModAlt, ImGuiKey_ReservedForModSuper,
ImGuiKey_COUNT, ImGuiKey_NamedKey_END,
// Keyboard Modifiers (explicitly submitted by backend via AddKeyEvent() calls) // Keyboard Modifiers (explicitly submitted by backend via AddKeyEvent() calls)
// - This is mirroring the data also written to io.KeyCtrl, io.KeyShift, io.KeyAlt, io.KeySuper, in a format allowing // - This is mirroring the data also written to io.KeyCtrl, io.KeyShift, io.KeyAlt, io.KeySuper, in a format allowing
@ -1591,21 +1592,13 @@ enum ImGuiKey : int
ImGuiMod_Super = 1 << 15, // Windows/Super (non-macOS), Ctrl (macOS) ImGuiMod_Super = 1 << 15, // Windows/Super (non-macOS), Ctrl (macOS)
ImGuiMod_Mask_ = 0xF000, // 4-bits ImGuiMod_Mask_ = 0xF000, // 4-bits
// [Internal] Prior to 1.87 we required user to fill io.KeysDown[512] using their own native index + the io.KeyMap[] array. // [Internal] If you need to iterate all keys (for e.g. an input mapper) you may use ImGuiKey_NamedKey_BEGIN..ImGuiKey_NamedKey_END.
// We are ditching this method but keeping a legacy path for user code doing e.g. IsKeyPressed(MY_NATIVE_KEY_CODE)
// If you need to iterate all keys (for e.g. an input mapper) you may use ImGuiKey_NamedKey_BEGIN..ImGuiKey_NamedKey_END.
ImGuiKey_NamedKey_BEGIN = 512,
ImGuiKey_NamedKey_END = ImGuiKey_COUNT,
ImGuiKey_NamedKey_COUNT = ImGuiKey_NamedKey_END - ImGuiKey_NamedKey_BEGIN, ImGuiKey_NamedKey_COUNT = ImGuiKey_NamedKey_END - ImGuiKey_NamedKey_BEGIN,
#ifdef IMGUI_DISABLE_OBSOLETE_KEYIO //ImGuiKey_KeysData_SIZE = ImGuiKey_NamedKey_COUNT, // Size of KeysData[]: only hold named keys
ImGuiKey_KeysData_SIZE = ImGuiKey_NamedKey_COUNT, // Size of KeysData[]: only hold named keys //ImGuiKey_KeysData_OFFSET = ImGuiKey_NamedKey_BEGIN, // Accesses to io.KeysData[] must use (key - ImGuiKey_NamedKey_BEGIN) index.
ImGuiKey_KeysData_OFFSET = ImGuiKey_NamedKey_BEGIN, // Accesses to io.KeysData[] must use (key - ImGuiKey_KeysData_OFFSET) index.
#else
ImGuiKey_KeysData_SIZE = ImGuiKey_COUNT, // Size of KeysData[]: hold legacy 0..512 keycodes + named keys
ImGuiKey_KeysData_OFFSET = 0, // Accesses to io.KeysData[] must use (key - ImGuiKey_KeysData_OFFSET) index.
#endif
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
ImGuiKey_COUNT = ImGuiKey_NamedKey_END, // Obsoleted in 1.91.5 because it was extremely misleading (since named keys don't start at 0 anymore)
ImGuiMod_Shortcut = ImGuiMod_Ctrl, // Removed in 1.90.7, you can now simply use ImGuiMod_Ctrl ImGuiMod_Shortcut = ImGuiMod_Ctrl, // Removed in 1.90.7, you can now simply use ImGuiMod_Ctrl
ImGuiKey_ModCtrl = ImGuiMod_Ctrl, ImGuiKey_ModShift = ImGuiMod_Shift, ImGuiKey_ModAlt = ImGuiMod_Alt, ImGuiKey_ModSuper = ImGuiMod_Super, // Renamed in 1.89 ImGuiKey_ModCtrl = ImGuiMod_Ctrl, ImGuiKey_ModShift = ImGuiMod_Shift, ImGuiKey_ModAlt = ImGuiMod_Alt, ImGuiKey_ModSuper = ImGuiMod_Super, // Renamed in 1.89
//ImGuiKey_KeyPadEnter = ImGuiKey_KeypadEnter, // Renamed in 1.87 //ImGuiKey_KeyPadEnter = ImGuiKey_KeypadEnter, // Renamed in 1.87
@ -1637,26 +1630,12 @@ enum ImGuiInputFlags_
ImGuiInputFlags_Tooltip = 1 << 18, // Automatically display a tooltip when hovering item [BETA] Unsure of right api (opt-in/opt-out) ImGuiInputFlags_Tooltip = 1 << 18, // Automatically display a tooltip when hovering item [BETA] Unsure of right api (opt-in/opt-out)
}; };
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
// OBSOLETED in 1.88 (from July 2022): ImGuiNavInput and io.NavInputs[].
// Official backends between 1.60 and 1.86: will keep working and feed gamepad inputs as long as IMGUI_DISABLE_OBSOLETE_KEYIO is not set.
// Custom backends: feed gamepad inputs via io.AddKeyEvent() and ImGuiKey_GamepadXXX enums.
enum ImGuiNavInput
{
ImGuiNavInput_Activate, ImGuiNavInput_Cancel, ImGuiNavInput_Input, ImGuiNavInput_Menu, ImGuiNavInput_DpadLeft, ImGuiNavInput_DpadRight, ImGuiNavInput_DpadUp, ImGuiNavInput_DpadDown,
ImGuiNavInput_LStickLeft, ImGuiNavInput_LStickRight, ImGuiNavInput_LStickUp, ImGuiNavInput_LStickDown, ImGuiNavInput_FocusPrev, ImGuiNavInput_FocusNext, ImGuiNavInput_TweakSlow, ImGuiNavInput_TweakFast,
ImGuiNavInput_COUNT,
};
#endif
// Configuration flags stored in io.ConfigFlags. Set by user/application. // Configuration flags stored in io.ConfigFlags. Set by user/application.
enum ImGuiConfigFlags_ enum ImGuiConfigFlags_
{ {
ImGuiConfigFlags_None = 0, ImGuiConfigFlags_None = 0,
ImGuiConfigFlags_NavEnableKeyboard = 1 << 0, // Master keyboard navigation enable flag. Enable full Tabbing + directional arrows + space/enter to activate. ImGuiConfigFlags_NavEnableKeyboard = 1 << 0, // Master keyboard navigation enable flag. Enable full Tabbing + directional arrows + space/enter to activate.
ImGuiConfigFlags_NavEnableGamepad = 1 << 1, // Master gamepad navigation enable flag. Backend also needs to set ImGuiBackendFlags_HasGamepad. ImGuiConfigFlags_NavEnableGamepad = 1 << 1, // Master gamepad navigation enable flag. Backend also needs to set ImGuiBackendFlags_HasGamepad.
ImGuiConfigFlags_NavEnableSetMousePos = 1 << 2, // Instruct navigation to move the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is awkward. Will update io.MousePos and set io.WantSetMousePos=true. If enabled you MUST honor io.WantSetMousePos requests in your backend, otherwise ImGui will react as if the mouse is jumping around back and forth.
ImGuiConfigFlags_NavNoCaptureKeyboard = 1 << 3, // Instruct navigation to not set the io.WantCaptureKeyboard flag when io.NavActive is set.
ImGuiConfigFlags_NoMouse = 1 << 4, // Instruct dear imgui to disable mouse inputs and interactions. ImGuiConfigFlags_NoMouse = 1 << 4, // Instruct dear imgui to disable mouse inputs and interactions.
ImGuiConfigFlags_NoMouseCursorChange = 1 << 5, // Instruct backend to not alter mouse cursor shape and visibility. Use if the backend cursor changes are interfering with yours and you don't want to use SetMouseCursor() to change mouse cursor. You may want to honor requests from imgui by reading GetMouseCursor() yourself instead. ImGuiConfigFlags_NoMouseCursorChange = 1 << 5, // Instruct backend to not alter mouse cursor shape and visibility. Use if the backend cursor changes are interfering with yours and you don't want to use SetMouseCursor() to change mouse cursor. You may want to honor requests from imgui by reading GetMouseCursor() yourself instead.
ImGuiConfigFlags_NoKeyboard = 1 << 6, // Instruct dear imgui to disable keyboard inputs and interactions. This is done by ignoring keyboard events and clearing existing states. ImGuiConfigFlags_NoKeyboard = 1 << 6, // Instruct dear imgui to disable keyboard inputs and interactions. This is done by ignoring keyboard events and clearing existing states.
@ -1673,6 +1652,11 @@ enum ImGuiConfigFlags_
// User storage (to allow your backend/engine to communicate to code that may be shared between multiple projects. Those flags are NOT used by core Dear ImGui) // User storage (to allow your backend/engine to communicate to code that may be shared between multiple projects. Those flags are NOT used by core Dear ImGui)
ImGuiConfigFlags_IsSRGB = 1 << 20, // Application is SRGB-aware. ImGuiConfigFlags_IsSRGB = 1 << 20, // Application is SRGB-aware.
ImGuiConfigFlags_IsTouchScreen = 1 << 21, // Application is using a touch screen instead of a mouse. ImGuiConfigFlags_IsTouchScreen = 1 << 21, // Application is using a touch screen instead of a mouse.
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
ImGuiConfigFlags_NavEnableSetMousePos = 1 << 2, // [moved/renamed in 1.91.4] -> use bool io.ConfigNavMoveSetMousePos
ImGuiConfigFlags_NavNoCaptureKeyboard = 1 << 3, // [moved/renamed in 1.91.4] -> use bool io.ConfigNavCaptureKeyboard
#endif
}; };
// Backend capabilities flags stored in io.BackendFlags. Set by imgui_impl_xxx or custom backend. // Backend capabilities flags stored in io.BackendFlags. Set by imgui_impl_xxx or custom backend.
@ -1681,7 +1665,7 @@ enum ImGuiBackendFlags_
ImGuiBackendFlags_None = 0, ImGuiBackendFlags_None = 0,
ImGuiBackendFlags_HasGamepad = 1 << 0, // Backend Platform supports gamepad and currently has one connected. ImGuiBackendFlags_HasGamepad = 1 << 0, // Backend Platform supports gamepad and currently has one connected.
ImGuiBackendFlags_HasMouseCursors = 1 << 1, // Backend Platform supports honoring GetMouseCursor() value to change the OS cursor shape. ImGuiBackendFlags_HasMouseCursors = 1 << 1, // Backend Platform supports honoring GetMouseCursor() value to change the OS cursor shape.
ImGuiBackendFlags_HasSetMousePos = 1 << 2, // Backend Platform supports io.WantSetMousePos requests to reposition the OS mouse position (only used if ImGuiConfigFlags_NavEnableSetMousePos is set). ImGuiBackendFlags_HasSetMousePos = 1 << 2, // Backend Platform supports io.WantSetMousePos requests to reposition the OS mouse position (only used if io.ConfigNavMoveSetMousePos is set).
ImGuiBackendFlags_RendererHasVtxOffset = 1 << 3, // Backend Renderer supports ImDrawCmd::VtxOffset. This enables output of large meshes (64K+ vertices) while still using 16-bit indices. ImGuiBackendFlags_RendererHasVtxOffset = 1 << 3, // Backend Renderer supports ImDrawCmd::VtxOffset. This enables output of large meshes (64K+ vertices) while still using 16-bit indices.
// [BETA] Viewports // [BETA] Viewports
@ -1747,7 +1731,7 @@ enum ImGuiCol_
ImGuiCol_TextLink, // Hyperlink color ImGuiCol_TextLink, // Hyperlink color
ImGuiCol_TextSelectedBg, ImGuiCol_TextSelectedBg,
ImGuiCol_DragDropTarget, // Rectangle highlighting a drop target ImGuiCol_DragDropTarget, // Rectangle highlighting a drop target
ImGuiCol_NavHighlight, // Gamepad/keyboard: current highlighted item ImGuiCol_NavCursor, // Color of keyboard/gamepad navigation cursor/rectangle, when visible
ImGuiCol_NavWindowingHighlight, // Highlight window when using CTRL+TAB ImGuiCol_NavWindowingHighlight, // Highlight window when using CTRL+TAB
ImGuiCol_NavWindowingDimBg, // Darken/colorize entire screen behind the CTRL+TAB window list, when active ImGuiCol_NavWindowingDimBg, // Darken/colorize entire screen behind the CTRL+TAB window list, when active
ImGuiCol_ModalWindowDimBg, // Darken/colorize entire screen behind a modal window, when one is active ImGuiCol_ModalWindowDimBg, // Darken/colorize entire screen behind a modal window, when one is active
@ -1757,6 +1741,7 @@ enum ImGuiCol_
ImGuiCol_TabActive = ImGuiCol_TabSelected, // [renamed in 1.90.9] ImGuiCol_TabActive = ImGuiCol_TabSelected, // [renamed in 1.90.9]
ImGuiCol_TabUnfocused = ImGuiCol_TabDimmed, // [renamed in 1.90.9] ImGuiCol_TabUnfocused = ImGuiCol_TabDimmed, // [renamed in 1.90.9]
ImGuiCol_TabUnfocusedActive = ImGuiCol_TabDimmedSelected, // [renamed in 1.90.9] ImGuiCol_TabUnfocusedActive = ImGuiCol_TabDimmedSelected, // [renamed in 1.90.9]
ImGuiCol_NavHighlight = ImGuiCol_NavCursor, // [renamed in 1.91.4]
#endif #endif
}; };
@ -1816,7 +1801,7 @@ enum ImGuiButtonFlags_
ImGuiButtonFlags_MouseButtonRight = 1 << 1, // React on right mouse button ImGuiButtonFlags_MouseButtonRight = 1 << 1, // React on right mouse button
ImGuiButtonFlags_MouseButtonMiddle = 1 << 2, // React on center mouse button ImGuiButtonFlags_MouseButtonMiddle = 1 << 2, // React on center mouse button
ImGuiButtonFlags_MouseButtonMask_ = ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle, // [Internal] ImGuiButtonFlags_MouseButtonMask_ = ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle, // [Internal]
//ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft, ImGuiButtonFlags_EnableNav = 1 << 3, // InvisibleButton(): do not disable navigation/tabbing. Otherwise disabled by default.
}; };
// Flags for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() / ColorButton() // Flags for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() / ColorButton()
@ -1865,19 +1850,18 @@ enum ImGuiColorEditFlags_
// Flags for DragFloat(), DragInt(), SliderFloat(), SliderInt() etc. // Flags for DragFloat(), DragInt(), SliderFloat(), SliderInt() etc.
// We use the same sets of flags for DragXXX() and SliderXXX() functions as the features are the same and it makes it easier to swap them. // We use the same sets of flags for DragXXX() and SliderXXX() functions as the features are the same and it makes it easier to swap them.
// (Those are per-item flags. There are shared flags in ImGuiIO: io.ConfigDragClickToInputText) // (Those are per-item flags. There is shared behavior flag too: ImGuiIO: io.ConfigDragClickToInputText)
enum ImGuiSliderFlags_ enum ImGuiSliderFlags_
{ {
ImGuiSliderFlags_None = 0, ImGuiSliderFlags_None = 0,
ImGuiSliderFlags_AlwaysClamp = 1 << 4, // Clamp value to min/max bounds when input manually with CTRL+Click. By default CTRL+Click allows going out of bounds. ImGuiSliderFlags_Logarithmic = 1 << 5, // Make the widget logarithmic (linear otherwise). Consider using ImGuiSliderFlags_NoRoundToFormat with this if using a format-string with small amount of digits.
ImGuiSliderFlags_Logarithmic = 1 << 5, // Make the widget logarithmic (linear otherwise). Consider using ImGuiSliderFlags_NoRoundToFormat with this if using a format-string with small amount of digits. ImGuiSliderFlags_NoRoundToFormat = 1 << 6, // Disable rounding underlying value to match precision of the display format string (e.g. %.3f values are rounded to those 3 digits).
ImGuiSliderFlags_NoRoundToFormat = 1 << 6, // Disable rounding underlying value to match precision of the display format string (e.g. %.3f values are rounded to those 3 digits). ImGuiSliderFlags_NoInput = 1 << 7, // Disable CTRL+Click or Enter key allowing to input text directly into the widget.
ImGuiSliderFlags_NoInput = 1 << 7, // Disable CTRL+Click or Enter key allowing to input text directly into the widget. ImGuiSliderFlags_WrapAround = 1 << 8, // Enable wrapping around from max to min and from min to max. Only supported by DragXXX() functions for now.
ImGuiSliderFlags_WrapAround = 1 << 8, // Enable wrapping around from max to min and from min to max (only supported by DragXXX() functions for now. ImGuiSliderFlags_ClampOnInput = 1 << 9, // Clamp value to min/max bounds when input manually with CTRL+Click. By default CTRL+Click allows going out of bounds.
ImGuiSliderFlags_InvalidMask_ = 0x7000000F, // [Internal] We treat using those bits as being potentially a 'float power' argument from the previous API that has got miscast to this enum, and will trigger an assert if needed. ImGuiSliderFlags_ClampZeroRange = 1 << 10, // Clamp even if min==max==0.0f. Otherwise due to legacy reason DragXXX functions don't clamp with those values. When your clamping limits are dynamic you almost always want to use it.
ImGuiSliderFlags_AlwaysClamp = ImGuiSliderFlags_ClampOnInput | ImGuiSliderFlags_ClampZeroRange,
// Obsolete names ImGuiSliderFlags_InvalidMask_ = 0x7000000F, // [Internal] We treat using those bits as being potentially a 'float power' argument from the previous API that has got miscast to this enum, and will trigger an assert if needed.
//ImGuiSliderFlags_ClampOnInput = ImGuiSliderFlags_AlwaysClamp, // [renamed in 1.79]
}; };
// Identify a mouse button. // Identify a mouse button.
@ -2301,7 +2285,7 @@ struct ImGuiIO
// Configuration // Default value // Configuration // Default value
//------------------------------------------------------------------ //------------------------------------------------------------------
ImGuiConfigFlags ConfigFlags; // = 0 // See ImGuiConfigFlags_ enum. Set by user/application. Gamepad/keyboard navigation options, etc. ImGuiConfigFlags ConfigFlags; // = 0 // See ImGuiConfigFlags_ enum. Set by user/application. Keyboard/Gamepad navigation options, etc.
ImGuiBackendFlags BackendFlags; // = 0 // See ImGuiBackendFlags_ enum. Set by backend (imgui_impl_xxx files or custom backend) to communicate features supported by the backend. ImGuiBackendFlags BackendFlags; // = 0 // See ImGuiBackendFlags_ enum. Set by backend (imgui_impl_xxx files or custom backend) to communicate features supported by the backend.
ImVec2 DisplaySize; // <unset> // Main display size, in pixels (generally == GetMainViewport()->Size). May change every frame. ImVec2 DisplaySize; // <unset> // Main display size, in pixels (generally == GetMainViewport()->Size). May change every frame.
float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds. May change every frame. float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds. May change every frame.
@ -2313,10 +2297,19 @@ struct ImGuiIO
// Font system // Font system
ImFontAtlas*Fonts; // <auto> // Font atlas: load, rasterize and pack one or more fonts into a single texture. ImFontAtlas*Fonts; // <auto> // Font atlas: load, rasterize and pack one or more fonts into a single texture.
float FontGlobalScale; // = 1.0f // Global scale all fonts float FontGlobalScale; // = 1.0f // Global scale all fonts
bool FontAllowUserScaling; // = false // Allow user scaling text of individual window with CTRL+Wheel. bool FontAllowUserScaling; // = false // [OBSOLETE] Allow user scaling text of individual window with CTRL+Wheel.
ImFont* FontDefault; // = NULL // Font to use on NewFrame(). Use NULL to uses Fonts->Fonts[0]. ImFont* FontDefault; // = NULL // Font to use on NewFrame(). Use NULL to uses Fonts->Fonts[0].
ImVec2 DisplayFramebufferScale; // = (1, 1) // For retina display or other situations where window coordinates are different from framebuffer coordinates. This generally ends up in ImDrawData::FramebufferScale. ImVec2 DisplayFramebufferScale; // = (1, 1) // For retina display or other situations where window coordinates are different from framebuffer coordinates. This generally ends up in ImDrawData::FramebufferScale.
// Keyboard/Gamepad Navigation options
bool ConfigNavSwapGamepadButtons; // = false // Swap Activate<>Cancel (A<>B) buttons, matching typical "Nintendo/Japanese style" gamepad layout.
bool ConfigNavMoveSetMousePos; // = false // Directional/tabbing navigation teleports the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is difficult. Will update io.MousePos and set io.WantSetMousePos=true.
bool ConfigNavCaptureKeyboard; // = true // Sets io.WantCaptureKeyboard when io.NavActive is set.
bool ConfigNavEscapeClearFocusItem; // = true // Pressing Escape can clear focused item + navigation id/highlight. Set to false if you want to always keep highlight on.
bool ConfigNavEscapeClearFocusWindow;// = false // Pressing Escape can clear focused window as well (super set of io.ConfigNavEscapeClearFocusItem).
bool ConfigNavCursorVisibleAuto; // = true // Using directional navigation key makes the cursor visible. Mouse click hides the cursor.
bool ConfigNavCursorVisibleAlways; // = false // Navigation cursor is always visible.
// Docking options (when ImGuiConfigFlags_DockingEnable is set) // Docking options (when ImGuiConfigFlags_DockingEnable is set)
bool ConfigDockingNoSplit; // = false // Simplified docking mode: disable window splitting, so docking is limited to merging multiple windows together into tab-bars. bool ConfigDockingNoSplit; // = false // Simplified docking mode: disable window splitting, so docking is limited to merging multiple windows together into tab-bars.
bool ConfigDockingWithShift; // = false // Enable docking with holding Shift key (reduce visual noise, allows dropping in wider space) bool ConfigDockingWithShift; // = false // Enable docking with holding Shift key (reduce visual noise, allows dropping in wider space)
@ -2333,13 +2326,14 @@ struct ImGuiIO
// (you can visualize and interact with all options in 'Demo->Configuration') // (you can visualize and interact with all options in 'Demo->Configuration')
bool MouseDrawCursor; // = false // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). Cannot be easily renamed to 'io.ConfigXXX' because this is frequently used by backend implementations. bool MouseDrawCursor; // = false // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). Cannot be easily renamed to 'io.ConfigXXX' because this is frequently used by backend implementations.
bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // Swap Cmd<>Ctrl keys + OS X style text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl. bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // Swap Cmd<>Ctrl keys + OS X style text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl.
bool ConfigNavSwapGamepadButtons; // = false // Swap Activate<>Cancel (A<>B) buttons, matching typical "Nintendo/Japanese style" gamepad layout.
bool ConfigInputTrickleEventQueue; // = true // Enable input queue trickling: some types of events submitted during the same frame (e.g. button down + up) will be spread over multiple frames, improving interactions with low framerates. bool ConfigInputTrickleEventQueue; // = true // Enable input queue trickling: some types of events submitted during the same frame (e.g. button down + up) will be spread over multiple frames, improving interactions with low framerates.
bool ConfigInputTextCursorBlink; // = true // Enable blinking cursor (optional as some users consider it to be distracting). bool ConfigInputTextCursorBlink; // = true // Enable blinking cursor (optional as some users consider it to be distracting).
bool ConfigInputTextEnterKeepActive; // = false // [BETA] Pressing Enter will keep item active and select contents (single-line only). bool ConfigInputTextEnterKeepActive; // = false // [BETA] Pressing Enter will keep item active and select contents (single-line only).
bool ConfigDragClickToInputText; // = false // [BETA] Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving). Not desirable on devices without a keyboard. bool ConfigDragClickToInputText; // = false // [BETA] Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving). Not desirable on devices without a keyboard.
bool ConfigWindowsResizeFromEdges; // = true // Enable resizing of windows from their edges and from the lower-left corner. This requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback. (This used to be a per-window ImGuiWindowFlags_ResizeFromAnySide flag) bool ConfigWindowsResizeFromEdges; // = true // Enable resizing of windows from their edges and from the lower-left corner. This requires ImGuiBackendFlags_HasMouseCursors for better mouse cursor feedback. (This used to be a per-window ImGuiWindowFlags_ResizeFromAnySide flag)
bool ConfigWindowsMoveFromTitleBarOnly; // = false // Enable allowing to move windows only when clicking on their title bar. Does not apply to windows without a title bar. bool ConfigWindowsMoveFromTitleBarOnly; // = false // Enable allowing to move windows only when clicking on their title bar. Does not apply to windows without a title bar.
bool ConfigWindowsCopyContentsWithCtrlC; // = false // [EXPERIMENTAL] CTRL+C copy the contents of focused window into the clipboard. Experimental because: (1) has known issues with nested Begin/End pairs (2) text output quality varies (3) text output is in submission order rather than spatial order.
bool ConfigScrollbarScrollByPage; // = true // Enable scrolling page by page when clicking outside the scrollbar grab. When disabled, always scroll to clicked location. When enabled, Shift+Click scrolls to clicked location.
float ConfigMemoryCompactTimer; // = 60.0f // Timer (in seconds) to free transient windows/tables memory buffers when unused. Set to -1.0f to disable. float ConfigMemoryCompactTimer; // = 60.0f // Timer (in seconds) to free transient windows/tables memory buffers when unused. Set to -1.0f to disable.
// Inputs Behaviors // Inputs Behaviors
@ -2354,6 +2348,25 @@ struct ImGuiIO
// Debug options // Debug options
//------------------------------------------------------------------ //------------------------------------------------------------------
// Options to configure Error Handling and how we handle recoverable errors [EXPERIMENTAL]
// - Error recovery is provided as a way to facilitate:
// - Recovery after a programming error (native code or scripting language - the later tends to facilitate iterating on code while running).
// - Recovery after running an exception handler or any error processing which may skip code after an error has been detected.
// - Error recovery is not perfect nor guaranteed! It is a feature to ease development.
// You not are not supposed to rely on it in the course of a normal application run.
// - Functions that support error recovery are using IM_ASSERT_USER_ERROR() instead of IM_ASSERT().
// - By design, we do NOT allow error recovery to be 100% silent. One of the three options needs to be checked!
// - Always ensure that on programmers seats you have at minimum Asserts or Tooltips enabled when making direct imgui API calls!
// Otherwise it would severely hinder your ability to catch and correct mistakes!
// Read https://github.com/ocornut/imgui/wiki/Error-Handling for details.
// - Programmer seats: keep asserts (default), or disable asserts and keep error tooltips (new and nice!)
// - Non-programmer seats: maybe disable asserts, but make sure errors are resurfaced (tooltips, visible log entries, use callback etc.)
// - Recovery after error/exception: record stack sizes with ErrorRecoveryStoreState(), disable assert, set log callback (to e.g. trigger high-level breakpoint), recover with ErrorRecoveryTryToRecoverState(), restore settings.
bool ConfigErrorRecovery; // = true // Enable error recovery support. Some errors won't be detected and lead to direct crashes if recovery is disabled.
bool ConfigErrorRecoveryEnableAssert; // = true // Enable asserts on recoverable error. By default call IM_ASSERT() when returning from a failing IM_ASSERT_USER_ERROR()
bool ConfigErrorRecoveryEnableDebugLog; // = true // Enable debug log output on recoverable errors.
bool ConfigErrorRecoveryEnableTooltip; // = true // Enable tooltip on recoverable errors. The tooltip include a way to enable asserts if they were disabled.
// Option to enable various debug tools showing buttons that will call the IM_DEBUG_BREAK() macro. // Option to enable various debug tools showing buttons that will call the IM_DEBUG_BREAK() macro.
// - The Item Picker tool will be available regardless of this being enabled, in order to maximize its discoverability. // - The Item Picker tool will be available regardless of this being enabled, in order to maximize its discoverability.
// - Requires a debugger being attached, otherwise IM_DEBUG_BREAK() options will appear to crash your application. // - Requires a debugger being attached, otherwise IM_DEBUG_BREAK() options will appear to crash your application.
@ -2382,7 +2395,7 @@ struct ImGuiIO
bool ConfigDebugIniSettings; // = false // Save .ini data with extra comments (particularly helpful for Docking, but makes saving slower) bool ConfigDebugIniSettings; // = false // Save .ini data with extra comments (particularly helpful for Docking, but makes saving slower)
//------------------------------------------------------------------ //------------------------------------------------------------------
// Platform Functions // Platform Identifiers
// (the imgui_impl_xxxx backend files are setting those up for you) // (the imgui_impl_xxxx backend files are setting those up for you)
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -2428,10 +2441,10 @@ struct ImGuiIO
bool WantCaptureMouse; // Set when Dear ImGui will use mouse inputs, in this case do not dispatch them to your main game/application (either way, always pass on mouse inputs to imgui). (e.g. unclicked mouse is hovering over an imgui window, widget is active, mouse was clicked over an imgui window, etc.). bool WantCaptureMouse; // Set when Dear ImGui will use mouse inputs, in this case do not dispatch them to your main game/application (either way, always pass on mouse inputs to imgui). (e.g. unclicked mouse is hovering over an imgui window, widget is active, mouse was clicked over an imgui window, etc.).
bool WantCaptureKeyboard; // Set when Dear ImGui will use keyboard inputs, in this case do not dispatch them to your main game/application (either way, always pass keyboard inputs to imgui). (e.g. InputText active, or an imgui window is focused and navigation is enabled, etc.). bool WantCaptureKeyboard; // Set when Dear ImGui will use keyboard inputs, in this case do not dispatch them to your main game/application (either way, always pass keyboard inputs to imgui). (e.g. InputText active, or an imgui window is focused and navigation is enabled, etc.).
bool WantTextInput; // Mobile/console: when set, you may display an on-screen keyboard. This is set by Dear ImGui when it wants textual keyboard input to happen (e.g. when a InputText widget is active). bool WantTextInput; // Mobile/console: when set, you may display an on-screen keyboard. This is set by Dear ImGui when it wants textual keyboard input to happen (e.g. when a InputText widget is active).
bool WantSetMousePos; // MousePos has been altered, backend should reposition mouse on next frame. Rarely used! Set only when ImGuiConfigFlags_NavEnableSetMousePos flag is enabled. bool WantSetMousePos; // MousePos has been altered, backend should reposition mouse on next frame. Rarely used! Set only when io.ConfigNavMoveSetMousePos is enabled.
bool WantSaveIniSettings; // When manual .ini load/save is active (io.IniFilename == NULL), this will be set to notify your application that you can call SaveIniSettingsToMemory() and save yourself. Important: clear io.WantSaveIniSettings yourself after saving! bool WantSaveIniSettings; // When manual .ini load/save is active (io.IniFilename == NULL), this will be set to notify your application that you can call SaveIniSettingsToMemory() and save yourself. Important: clear io.WantSaveIniSettings yourself after saving!
bool NavActive; // Keyboard/Gamepad navigation is currently allowed (will handle ImGuiKey_NavXXX events) = a window is focused and it doesn't use the ImGuiWindowFlags_NoNavInputs flag. bool NavActive; // Keyboard/Gamepad navigation is currently allowed (will handle ImGuiKey_NavXXX events) = a window is focused and it doesn't use the ImGuiWindowFlags_NoNavInputs flag.
bool NavVisible; // Keyboard/Gamepad navigation is visible and allowed (will handle ImGuiKey_NavXXX events). bool NavVisible; // Keyboard/Gamepad navigation highlight is visible and allowed (will handle ImGuiKey_NavXXX events).
float Framerate; // Estimate of application framerate (rolling average over 60 frames, based on io.DeltaTime), in frame per second. Solely for convenience. Slow applications may not want to use a moving average or may want to reset underlying buffers occasionally. float Framerate; // Estimate of application framerate (rolling average over 60 frames, based on io.DeltaTime), in frame per second. Solely for convenience. Slow applications may not want to use a moving average or may want to reset underlying buffers occasionally.
int MetricsRenderVertices; // Vertices output during last call to Render() int MetricsRenderVertices; // Vertices output during last call to Render()
int MetricsRenderIndices; // Indices output during last call to Render() = number of triangles * 3 int MetricsRenderIndices; // Indices output during last call to Render() = number of triangles * 3
@ -2461,7 +2474,7 @@ struct ImGuiIO
// Other state maintained from data above + IO function calls // Other state maintained from data above + IO function calls
ImGuiKeyChord KeyMods; // Key mods flags (any of ImGuiMod_Ctrl/ImGuiMod_Shift/ImGuiMod_Alt/ImGuiMod_Super flags, same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags. Read-only, updated by NewFrame() ImGuiKeyChord KeyMods; // Key mods flags (any of ImGuiMod_Ctrl/ImGuiMod_Shift/ImGuiMod_Alt/ImGuiMod_Super flags, same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags. Read-only, updated by NewFrame()
ImGuiKeyData KeysData[ImGuiKey_KeysData_SIZE]; // Key state for all known keys. Use IsKeyXXX() functions to access this. ImGuiKeyData KeysData[ImGuiKey_NamedKey_COUNT];// Key state for all known keys. Use IsKeyXXX() functions to access this.
bool WantCaptureMouseUnlessPopupClose; // Alternative to WantCaptureMouse: (WantCaptureMouse == true && WantCaptureMouseUnlessPopupClose == false) when a click over void is expected to close a popup. bool WantCaptureMouseUnlessPopupClose; // Alternative to WantCaptureMouse: (WantCaptureMouse == true && WantCaptureMouseUnlessPopupClose == false) when a click over void is expected to close a popup.
ImVec2 MousePosPrev; // Previous mouse position (note that MouseDelta is not necessary == MousePos-MousePosPrev, in case either position is invalid) ImVec2 MousePosPrev; // Previous mouse position (note that MouseDelta is not necessary == MousePos-MousePosPrev, in case either position is invalid)
ImVec2 MouseClickedPos[5]; // Position at time of clicking ImVec2 MouseClickedPos[5]; // Position at time of clicking
@ -2482,20 +2495,18 @@ struct ImGuiIO
float PenPressure; // Touch/Pen pressure (0.0f to 1.0f, should be >0.0f only when MouseDown[0] == true). Helper storage currently unused by Dear ImGui. float PenPressure; // Touch/Pen pressure (0.0f to 1.0f, should be >0.0f only when MouseDown[0] == true). Helper storage currently unused by Dear ImGui.
bool AppFocusLost; // Only modify via AddFocusEvent() bool AppFocusLost; // Only modify via AddFocusEvent()
bool AppAcceptingEvents; // Only modify via SetAppAcceptingEvents() bool AppAcceptingEvents; // Only modify via SetAppAcceptingEvents()
ImS8 BackendUsingLegacyKeyArrays; // -1: unknown, 0: using AddKeyEvent(), 1: using legacy io.KeysDown[]
bool BackendUsingLegacyNavInputArray; // 0: using AddKeyAnalogEvent(), 1: writing to legacy io.NavInputs[] directly
ImWchar16 InputQueueSurrogate; // For AddInputCharacterUTF16() ImWchar16 InputQueueSurrogate; // For AddInputCharacterUTF16()
ImVector<ImWchar> InputQueueCharacters; // Queue of _characters_ input (obtained by platform backend). Fill using AddInputCharacter() helper. ImVector<ImWchar> InputQueueCharacters; // Queue of _characters_ input (obtained by platform backend). Fill using AddInputCharacter() helper.
// Legacy: before 1.87, we required backend to fill io.KeyMap[] (imgui->native map) during initialization and io.KeysDown[] (native indices) every frame. // Legacy: before 1.87, we required backend to fill io.KeyMap[] (imgui->native map) during initialization and io.KeysDown[] (native indices) every frame.
// This is still temporarily supported as a legacy feature. However the new preferred scheme is for backend to call io.AddKeyEvent(). // This is still temporarily supported as a legacy feature. However the new preferred scheme is for backend to call io.AddKeyEvent().
// Old (<1.87): ImGui::IsKeyPressed(ImGui::GetIO().KeyMap[ImGuiKey_Space]) --> New (1.87+) ImGui::IsKeyPressed(ImGuiKey_Space) // Old (<1.87): ImGui::IsKeyPressed(ImGui::GetIO().KeyMap[ImGuiKey_Space]) --> New (1.87+) ImGui::IsKeyPressed(ImGuiKey_Space)
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO // Old (<1.87): ImGui::IsKeyPressed(MYPLATFORM_KEY_SPACE) --> New (1.87+) ImGui::IsKeyPressed(ImGuiKey_Space)
int KeyMap[ImGuiKey_COUNT]; // [LEGACY] Input: map of indices into the KeysDown[512] entries array which represent your "native" keyboard state. The first 512 are now unused and should be kept zero. Legacy backend will write into KeyMap[] using ImGuiKey_ indices which are always >512. // Read https://github.com/ocornut/imgui/issues/4921 for details.
bool KeysDown[ImGuiKey_COUNT]; // [LEGACY] Input: Keyboard keys that are pressed (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys). This used to be [512] sized. It is now ImGuiKey_COUNT to allow legacy io.KeysDown[GetKeyIndex(...)] to work without an overflow. //int KeyMap[ImGuiKey_COUNT]; // [LEGACY] Input: map of indices into the KeysDown[512] entries array which represent your "native" keyboard state. The first 512 are now unused and should be kept zero. Legacy backend will write into KeyMap[] using ImGuiKey_ indices which are always >512.
float NavInputs[ImGuiNavInput_COUNT]; // [LEGACY] Since 1.88, NavInputs[] was removed. Backends from 1.60 to 1.86 won't build. Feed gamepad inputs via io.AddKeyEvent() and ImGuiKey_GamepadXXX enums. //bool KeysDown[ImGuiKey_COUNT]; // [LEGACY] Input: Keyboard keys that are pressed (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys). This used to be [512] sized. It is now ImGuiKey_COUNT to allow legacy io.KeysDown[GetKeyIndex(...)] to work without an overflow.
//float NavInputs[ImGuiNavInput_COUNT]; // [LEGACY] Since 1.88, NavInputs[] was removed. Backends from 1.60 to 1.86 won't build. Feed gamepad inputs via io.AddKeyEvent() and ImGuiKey_GamepadXXX enums.
//void* ImeWindowHandle; // [Obsoleted in 1.87] Set ImGuiViewport::PlatformHandleRaw instead. Set this to your HWND to get automatic IME cursor positioning. //void* ImeWindowHandle; // [Obsoleted in 1.87] Set ImGuiViewport::PlatformHandleRaw instead. Set this to your HWND to get automatic IME cursor positioning.
#endif
// Legacy: before 1.91.1, clipboard functions were stored in ImGuiIO instead of ImGuiPlatformIO. // Legacy: before 1.91.1, clipboard functions were stored in ImGuiIO instead of ImGuiPlatformIO.
// As this is will affect all users of custom engines/backends, we are providing proper legacy redirection (will obsolete). // As this is will affect all users of custom engines/backends, we are providing proper legacy redirection (will obsolete).
@ -3047,9 +3058,11 @@ struct ImDrawCmd
unsigned int IdxOffset; // 4 // Start offset in index buffer. unsigned int IdxOffset; // 4 // Start offset in index buffer.
unsigned int ElemCount; // 4 // Number of indices (multiple of 3) to be rendered as triangles. Vertices are stored in the callee ImDrawList's vtx_buffer[] array, indices in idx_buffer[]. unsigned int ElemCount; // 4 // Number of indices (multiple of 3) to be rendered as triangles. Vertices are stored in the callee ImDrawList's vtx_buffer[] array, indices in idx_buffer[].
ImDrawCallback UserCallback; // 4-8 // If != NULL, call the function instead of rendering the vertices. clip_rect and texture_id will be set normally. ImDrawCallback UserCallback; // 4-8 // If != NULL, call the function instead of rendering the vertices. clip_rect and texture_id will be set normally.
void* UserCallbackData; // 4-8 // The draw callback code can access this. void* UserCallbackData; // 4-8 // Callback user data (when UserCallback != NULL). If called AddCallback() with size == 0, this is a copy of the AddCallback() argument. If called AddCallback() with size > 0, this is pointing to a buffer where data is stored.
int UserCallbackDataSize; // 4 // Size of callback user data when using storage, otherwise 0.
int UserCallbackDataOffset;// 4 // [Internal] Offset of callback user data when using storage, otherwise -1.
ImDrawCmd() { memset(this, 0, sizeof(*this)); } // Also ensure our padding fields are zeroed ImDrawCmd() { memset(this, 0, sizeof(*this)); } // Also ensure our padding fields are zeroed
// Since 1.83: returns ImTextureID associated with this draw call. Warning: DO NOT assume this is always same as 'TextureId' (we will change this function for an upcoming feature) // Since 1.83: returns ImTextureID associated with this draw call. Warning: DO NOT assume this is always same as 'TextureId' (we will change this function for an upcoming feature)
inline ImTextureID GetTexID() const { return TextureId; } inline ImTextureID GetTexID() const { return TextureId; }
@ -3142,7 +3155,7 @@ enum ImDrawListFlags_
// access the current window draw list and draw custom primitives. // access the current window draw list and draw custom primitives.
// You can interleave normal ImGui:: calls and adding primitives to the current draw list. // You can interleave normal ImGui:: calls and adding primitives to the current draw list.
// In single viewport mode, top-left is == GetMainViewport()->Pos (generally 0,0), bottom-right is == GetMainViewport()->Pos+Size (generally io.DisplaySize). // In single viewport mode, top-left is == GetMainViewport()->Pos (generally 0,0), bottom-right is == GetMainViewport()->Pos+Size (generally io.DisplaySize).
// You are totally free to apply whatever transformation matrix to want to the data (depending on the use of the transformation you may want to apply it to ClipRect as well!) // You are totally free to apply whatever transformation matrix you want to the data (depending on the use of the transformation you may want to apply it to ClipRect as well!)
// Important: Primitives are always added to the list and not culled (culling is done at higher-level by ImGui:: functions), if you use this API a lot consider coarse culling your drawn objects. // Important: Primitives are always added to the list and not culled (culling is done at higher-level by ImGui:: functions), if you use this API a lot consider coarse culling your drawn objects.
struct ImDrawList struct ImDrawList
{ {
@ -3162,6 +3175,7 @@ struct ImDrawList
ImDrawListSplitter _Splitter; // [Internal] for channels api (note: prefer using your own persistent instance of ImDrawListSplitter!) ImDrawListSplitter _Splitter; // [Internal] for channels api (note: prefer using your own persistent instance of ImDrawListSplitter!)
ImVector<ImVec4> _ClipRectStack; // [Internal] ImVector<ImVec4> _ClipRectStack; // [Internal]
ImVector<ImTextureID> _TextureIdStack; // [Internal] ImVector<ImTextureID> _TextureIdStack; // [Internal]
ImVector<ImU8> _CallbacksDataBuf; // [Internal]
float _FringeScale; // [Internal] anti-alias fringe is scaled by this value, this helps to keep things sharp while zooming at vertex buffer content float _FringeScale; // [Internal] anti-alias fringe is scaled by this value, this helps to keep things sharp while zooming at vertex buffer content
const char* _OwnerName; // Pointer to owner window's name for debugging const char* _OwnerName; // Pointer to owner window's name for debugging
@ -3199,7 +3213,7 @@ struct ImDrawList
IMGUI_API void AddEllipse(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot = 0.0f, int num_segments = 0, float thickness = 1.0f); IMGUI_API void AddEllipse(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot = 0.0f, int num_segments = 0, float thickness = 1.0f);
IMGUI_API void AddEllipseFilled(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot = 0.0f, int num_segments = 0); IMGUI_API void AddEllipseFilled(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot = 0.0f, int num_segments = 0);
IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL); IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL);
IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL); IMGUI_API void AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL);
IMGUI_API void AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0); // Cubic Bezier (4 control points) IMGUI_API void AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0); // Cubic Bezier (4 control points)
IMGUI_API void AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness, int num_segments = 0); // Quadratic Bezier (3 control points) IMGUI_API void AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness, int num_segments = 0); // Quadratic Bezier (3 control points)
@ -3234,8 +3248,18 @@ struct ImDrawList
IMGUI_API void PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, int num_segments = 0); // Quadratic Bezier (3 control points) IMGUI_API void PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, int num_segments = 0); // Quadratic Bezier (3 control points)
IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, ImDrawFlags flags = 0); IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, ImDrawFlags flags = 0);
// Advanced // Advanced: Draw Callbacks
IMGUI_API void AddCallback(ImDrawCallback callback, void* callback_data); // Your rendering function must check for 'UserCallback' in ImDrawCmd and call the function instead of rendering triangles. // - May be used to alter render state (change sampler, blending, current shader). May be used to emit custom rendering commands (difficult to do correctly, but possible).
// - Use special ImDrawCallback_ResetRenderState callback to instruct backend to reset its render state to the default.
// - Your rendering loop must check for 'UserCallback' in ImDrawCmd and call the function instead of rendering triangles. All standard backends are honoring this.
// - For some backends, the callback may access selected render-states exposed by the backend in a ImGui_ImplXXXX_RenderState structure pointed to by platform_io.Renderer_RenderState.
// - IMPORTANT: please be mindful of the different level of indirection between using size==0 (copying argument) and using size>0 (copying pointed data into a buffer).
// - If userdata_size == 0: we copy/store the 'userdata' argument as-is. It will be available unmodified in ImDrawCmd::UserCallbackData during render.
// - If userdata_size > 0, we copy/store 'userdata_size' bytes pointed to by 'userdata'. We store them in a buffer stored inside the drawlist. ImDrawCmd::UserCallbackData will point inside that buffer so you have to retrieve data from there. Your callback may need to use ImDrawCmd::UserCallbackDataSize if you expect dynamically-sized data.
// - Support for userdata_size > 0 was added in v1.91.4, October 2024. So earlier code always only allowed to copy/store a simple void*.
IMGUI_API void AddCallback(ImDrawCallback callback, void* userdata, size_t userdata_size = 0);
// Advanced: Miscellaneous
IMGUI_API void AddDrawCmd(); // This is useful if you need to forcefully create a new draw call (to allow for dependent rendering / blending). Otherwise primitives are merged into the same draw-call as much as possible IMGUI_API void AddDrawCmd(); // This is useful if you need to forcefully create a new draw call (to allow for dependent rendering / blending). Otherwise primitives are merged into the same draw-call as much as possible
IMGUI_API ImDrawList* CloneOutput() const; // Create a clone of the CmdBuffer/IdxBuffer/VtxBuffer. IMGUI_API ImDrawList* CloneOutput() const; // Create a clone of the CmdBuffer/IdxBuffer/VtxBuffer.
@ -3265,8 +3289,8 @@ struct ImDrawList
//inline void AddEllipse(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0, float thickness = 1.0f) { AddEllipse(center, ImVec2(radius_x, radius_y), col, rot, num_segments, thickness); } // OBSOLETED in 1.90.5 (Mar 2024) //inline void AddEllipse(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0, float thickness = 1.0f) { AddEllipse(center, ImVec2(radius_x, radius_y), col, rot, num_segments, thickness); } // OBSOLETED in 1.90.5 (Mar 2024)
//inline void AddEllipseFilled(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0) { AddEllipseFilled(center, ImVec2(radius_x, radius_y), col, rot, num_segments); } // OBSOLETED in 1.90.5 (Mar 2024) //inline void AddEllipseFilled(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0) { AddEllipseFilled(center, ImVec2(radius_x, radius_y), col, rot, num_segments); } // OBSOLETED in 1.90.5 (Mar 2024)
//inline void PathEllipticalArcTo(const ImVec2& center, float radius_x, float radius_y, float rot, float a_min, float a_max, int num_segments = 0) { PathEllipticalArcTo(center, ImVec2(radius_x, radius_y), rot, a_min, a_max, num_segments); } // OBSOLETED in 1.90.5 (Mar 2024) //inline void PathEllipticalArcTo(const ImVec2& center, float radius_x, float radius_y, float rot, float a_min, float a_max, int num_segments = 0) { PathEllipticalArcTo(center, ImVec2(radius_x, radius_y), rot, a_min, a_max, num_segments); } // OBSOLETED in 1.90.5 (Mar 2024)
//inline void AddBezierCurve(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0) { AddBezierCubic(p1, p2, p3, p4, col, thickness, num_segments); } // OBSOLETED in 1.80 (Jan 2021) //inline void AddBezierCurve(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0) { AddBezierCubic(p1, p2, p3, p4, col, thickness, num_segments); } // OBSOLETED in 1.80 (Jan 2021)
//inline void PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0) { PathBezierCubicCurveTo(p2, p3, p4, num_segments); } // OBSOLETED in 1.80 (Jan 2021) //inline void PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0) { PathBezierCubicCurveTo(p2, p3, p4, num_segments); } // OBSOLETED in 1.80 (Jan 2021)
// [Internal helpers] // [Internal helpers]
IMGUI_API void _ResetForNewFrame(); IMGUI_API void _ResetForNewFrame();
@ -3370,11 +3394,12 @@ struct ImFontAtlasCustomRect
{ {
unsigned short Width, Height; // Input // Desired rectangle dimension unsigned short Width, Height; // Input // Desired rectangle dimension
unsigned short X, Y; // Output // Packed position in Atlas unsigned short X, Y; // Output // Packed position in Atlas
unsigned int GlyphID; // Input // For custom font glyphs only (ID < 0x110000) unsigned int GlyphID : 31; // Input // For custom font glyphs only (ID < 0x110000)
unsigned int GlyphColored : 1; // Input // For custom font glyphs only: glyph is colored, removed tinting.
float GlyphAdvanceX; // Input // For custom font glyphs only: glyph xadvance float GlyphAdvanceX; // Input // For custom font glyphs only: glyph xadvance
ImVec2 GlyphOffset; // Input // For custom font glyphs only: glyph display offset ImVec2 GlyphOffset; // Input // For custom font glyphs only: glyph display offset
ImFont* Font; // Input // For custom font glyphs only: target font ImFont* Font; // Input // For custom font glyphs only: target font
ImFontAtlasCustomRect() { Width = Height = 0; X = Y = 0xFFFF; GlyphID = 0; GlyphAdvanceX = 0.0f; GlyphOffset = ImVec2(0, 0); Font = NULL; } ImFontAtlasCustomRect() { Width = Height = 0; X = Y = 0xFFFF; GlyphID = 0; GlyphColored = 0; GlyphAdvanceX = 0.0f; GlyphOffset = ImVec2(0, 0); Font = NULL; }
bool IsPacked() const { return X != 0xFFFF; } bool IsPacked() const { return X != 0xFFFF; }
}; };
@ -3538,18 +3563,18 @@ struct ImFont
// Methods // Methods
IMGUI_API ImFont(); IMGUI_API ImFont();
IMGUI_API ~ImFont(); IMGUI_API ~ImFont();
IMGUI_API const ImFontGlyph*FindGlyph(ImWchar c) const; IMGUI_API const ImFontGlyph*FindGlyph(ImWchar c);
IMGUI_API const ImFontGlyph*FindGlyphNoFallback(ImWchar c) const; IMGUI_API const ImFontGlyph*FindGlyphNoFallback(ImWchar c);
float GetCharAdvance(ImWchar c) const { return ((int)c < IndexAdvanceX.Size) ? IndexAdvanceX[(int)c] : FallbackAdvanceX; } float GetCharAdvance(ImWchar c) { return ((int)c < IndexAdvanceX.Size) ? IndexAdvanceX[(int)c] : FallbackAdvanceX; }
bool IsLoaded() const { return ContainerAtlas != NULL; } bool IsLoaded() const { return ContainerAtlas != NULL; }
const char* GetDebugName() const { return ConfigData ? ConfigData->Name : "<unknown>"; } const char* GetDebugName() const { return ConfigData ? ConfigData->Name : "<unknown>"; }
// 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable. // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.
// 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable. // 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.
IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8 IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL); // utf8
IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const; IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width);
IMGUI_API void RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c) const; IMGUI_API void RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c);
IMGUI_API void RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false) const; IMGUI_API void RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false);
// [Internal] Don't use! // [Internal] Don't use!
IMGUI_API void BuildLookupTable(); IMGUI_API void BuildLookupTable();
@ -3684,7 +3709,7 @@ struct ImGuiPlatformIO
IMGUI_API ImGuiPlatformIO(); IMGUI_API ImGuiPlatformIO();
//------------------------------------------------------------------ //------------------------------------------------------------------
// Input - Interface with OS/backends (basic) // Interface with OS and Platform backend (basic)
//------------------------------------------------------------------ //------------------------------------------------------------------
// Optional: Access OS clipboard // Optional: Access OS clipboard
@ -3708,6 +3733,13 @@ struct ImGuiPlatformIO
// [Experimental] Configure decimal point e.g. '.' or ',' useful for some languages (e.g. German), generally pulled from *localeconv()->decimal_point // [Experimental] Configure decimal point e.g. '.' or ',' useful for some languages (e.g. German), generally pulled from *localeconv()->decimal_point
ImWchar Platform_LocaleDecimalPoint; // '.' ImWchar Platform_LocaleDecimalPoint; // '.'
//------------------------------------------------------------------
// Interface with Renderer Backend
//------------------------------------------------------------------
// Written by some backends during ImGui_ImplXXXX_RenderDrawData() call to point backend_specific ImGui_ImplXXXX_RenderState* structure.
void* Renderer_RenderState;
//------------------------------------------------------------------ //------------------------------------------------------------------
// Input - Interface with OS/backends (Multi-Viewport support!) // Input - Interface with OS/backends (Multi-Viewport support!)
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -3817,16 +3849,16 @@ namespace ImGui
// OBSOLETED in 1.89.4 (from March 2023) // OBSOLETED in 1.89.4 (from March 2023)
static inline void PushAllowKeyboardFocus(bool tab_stop) { PushItemFlag(ImGuiItemFlags_NoTabStop, !tab_stop); } static inline void PushAllowKeyboardFocus(bool tab_stop) { PushItemFlag(ImGuiItemFlags_NoTabStop, !tab_stop); }
static inline void PopAllowKeyboardFocus() { PopItemFlag(); } static inline void PopAllowKeyboardFocus() { PopItemFlag(); }
// OBSOLETED in 1.87 (from February 2022 but more formally obsoleted April 2024)
IMGUI_API ImGuiKey GetKeyIndex(ImGuiKey key); // Map ImGuiKey_* values into legacy native key index. == io.KeyMap[key]. When using a 1.87+ backend using io.AddKeyEvent(), calling GetKeyIndex() with ANY ImGuiKey_XXXX values will return the same value!
//static inline ImGuiKey GetKeyIndex(ImGuiKey key) { IM_ASSERT(key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END); return key; }
// Some of the older obsolete names along with their replacement (commented out so they are not reported in IDE) // Some of the older obsolete names along with their replacement (commented out so they are not reported in IDE)
//-- OBSOLETED in 1.89 (from August 2022) //-- OBSOLETED in 1.89 (from August 2022)
//IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1)); // --> Use new ImageButton() signature (explicit item id, regular FramePadding). Refer to code in 1.91 if you want to grab a copy of this version. //IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1)); // --> Use new ImageButton() signature (explicit item id, regular FramePadding). Refer to code in 1.91 if you want to grab a copy of this version.
//-- OBSOLETED in 1.88 (from May 2022) //-- OBSOLETED in 1.88 (from May 2022)
//static inline void CaptureKeyboardFromApp(bool want_capture_keyboard = true) { SetNextFrameWantCaptureKeyboard(want_capture_keyboard); } // Renamed as name was misleading + removed default value. //static inline void CaptureKeyboardFromApp(bool want_capture_keyboard = true) { SetNextFrameWantCaptureKeyboard(want_capture_keyboard); } // Renamed as name was misleading + removed default value.
//static inline void CaptureMouseFromApp(bool want_capture_mouse = true) { SetNextFrameWantCaptureMouse(want_capture_mouse); } // Renamed as name was misleading + removed default value. //static inline void CaptureMouseFromApp(bool want_capture_mouse = true) { SetNextFrameWantCaptureMouse(want_capture_mouse); } // Renamed as name was misleading + removed default value.
//-- OBSOLETED in 1.87 (from February 2022, more formally obsoleted April 2024)
//IMGUI_API ImGuiKey GetKeyIndex(ImGuiKey key); { IM_ASSERT(key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END); const ImGuiKeyData* key_data = GetKeyData(key); return (ImGuiKey)(key_data - g.IO.KeysData); } // Map ImGuiKey_* values into legacy native key index. == io.KeyMap[key]. When using a 1.87+ backend using io.AddKeyEvent(), calling GetKeyIndex() with ANY ImGuiKey_XXXX values will return the same value!
//static inline ImGuiKey GetKeyIndex(ImGuiKey key) { IM_ASSERT(key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END); return key; }
//-- OBSOLETED in 1.86 (from November 2021) //-- OBSOLETED in 1.86 (from November 2021)
//IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // Code removed, see 1.90 for last version of the code. Calculate range of visible items for large list of evenly sized items. Prefer using ImGuiListClipper. //IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // Code removed, see 1.90 for last version of the code. Calculate range of visible items for large list of evenly sized items. Prefer using ImGuiListClipper.
//-- OBSOLETED in 1.85 (from August 2021) //-- OBSOLETED in 1.85 (from August 2021)
@ -3909,10 +3941,7 @@ namespace ImGui
#endif // #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #endif // #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
// RENAMED IMGUI_DISABLE_METRICS_WINDOW > IMGUI_DISABLE_DEBUG_TOOLS in 1.88 (from June 2022) // RENAMED IMGUI_DISABLE_METRICS_WINDOW > IMGUI_DISABLE_DEBUG_TOOLS in 1.88 (from June 2022)
#if defined(IMGUI_DISABLE_METRICS_WINDOW) && !defined(IMGUI_DISABLE_OBSOLETE_FUNCTIONS) && !defined(IMGUI_DISABLE_DEBUG_TOOLS) #ifdef IMGUI_DISABLE_METRICS_WINDOW
#define IMGUI_DISABLE_DEBUG_TOOLS
#endif
#if defined(IMGUI_DISABLE_METRICS_WINDOW) && defined(IMGUI_DISABLE_OBSOLETE_FUNCTIONS)
#error IMGUI_DISABLE_METRICS_WINDOW was renamed to IMGUI_DISABLE_DEBUG_TOOLS, please use new name. #error IMGUI_DISABLE_METRICS_WINDOW was renamed to IMGUI_DISABLE_DEBUG_TOOLS, please use new name.
#endif #endif

View File

@ -1,4 +1,4 @@
// dear imgui, v1.91.2 WIP // dear imgui, v1.91.5
// (demo code) // (demo code)
// Help: // Help:
@ -146,12 +146,12 @@ Index of this file:
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
#elif defined(__GNUC__) #elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size
#pragma GCC diagnostic ignored "-Wformat-security" // warning: format string is not a string literal (potentially insecure) #pragma GCC diagnostic ignored "-Wformat-security" // warning: format string is not a string literal (potentially insecure)
#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function #pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value #pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value
#pragma GCC diagnostic ignored "-Wmisleading-indentation" // [__GNUC__ >= 6] warning: this 'if' clause does not guard this statement // GCC 6.0+ only. See #883 on GitHub. #pragma GCC diagnostic ignored "-Wmisleading-indentation" // [__GNUC__ >= 6] warning: this 'if' clause does not guard this statement // GCC 6.0+ only. See #883 on GitHub.
#endif #endif
// Play it nice with Windows users (Update: May 2018, Notepad now supports Unix-style carriage returns!) // Play it nice with Windows users (Update: May 2018, Notepad now supports Unix-style carriage returns!)
@ -517,8 +517,6 @@ void ImGui::ShowDemoWindow(bool* p_open)
ImGui::SameLine(); HelpMarker("Enable keyboard controls."); ImGui::SameLine(); HelpMarker("Enable keyboard controls.");
ImGui::CheckboxFlags("io.ConfigFlags: NavEnableGamepad", &io.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad); ImGui::CheckboxFlags("io.ConfigFlags: NavEnableGamepad", &io.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad);
ImGui::SameLine(); HelpMarker("Enable gamepad controls. Require backend to set io.BackendFlags |= ImGuiBackendFlags_HasGamepad.\n\nRead instructions in imgui.cpp for details."); ImGui::SameLine(); HelpMarker("Enable gamepad controls. Require backend to set io.BackendFlags |= ImGuiBackendFlags_HasGamepad.\n\nRead instructions in imgui.cpp for details.");
ImGui::CheckboxFlags("io.ConfigFlags: NavEnableSetMousePos", &io.ConfigFlags, ImGuiConfigFlags_NavEnableSetMousePos);
ImGui::SameLine(); HelpMarker("Instruct navigation to move the mouse cursor. See comment for ImGuiConfigFlags_NavEnableSetMousePos.");
ImGui::CheckboxFlags("io.ConfigFlags: NoMouse", &io.ConfigFlags, ImGuiConfigFlags_NoMouse); ImGui::CheckboxFlags("io.ConfigFlags: NoMouse", &io.ConfigFlags, ImGuiConfigFlags_NoMouse);
ImGui::SameLine(); HelpMarker("Instruct dear imgui to disable mouse inputs and interactions."); ImGui::SameLine(); HelpMarker("Instruct dear imgui to disable mouse inputs and interactions.");
@ -545,6 +543,20 @@ void ImGui::ShowDemoWindow(bool* p_open)
ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor); ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor);
ImGui::SameLine(); HelpMarker("Instruct Dear ImGui to render a mouse cursor itself. Note that a mouse cursor rendered via your application GPU rendering path will feel more laggy than hardware cursor, but will be more in sync with your other visuals.\n\nSome desktop applications may use both kinds of cursors (e.g. enable software cursor only when resizing/dragging something)."); ImGui::SameLine(); HelpMarker("Instruct Dear ImGui to render a mouse cursor itself. Note that a mouse cursor rendered via your application GPU rendering path will feel more laggy than hardware cursor, but will be more in sync with your other visuals.\n\nSome desktop applications may use both kinds of cursors (e.g. enable software cursor only when resizing/dragging something).");
ImGui::SeparatorText("Keyboard/Gamepad Navigation");
ImGui::Checkbox("io.ConfigNavSwapGamepadButtons", &io.ConfigNavSwapGamepadButtons);
ImGui::Checkbox("io.ConfigNavMoveSetMousePos", &io.ConfigNavMoveSetMousePos);
ImGui::SameLine(); HelpMarker("Directional/tabbing navigation teleports the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is difficult");
ImGui::Checkbox("io.ConfigNavCaptureKeyboard", &io.ConfigNavCaptureKeyboard);
ImGui::Checkbox("io.ConfigNavEscapeClearFocusItem", &io.ConfigNavEscapeClearFocusItem);
ImGui::SameLine(); HelpMarker("Pressing Escape clears focused item.");
ImGui::Checkbox("io.ConfigNavEscapeClearFocusWindow", &io.ConfigNavEscapeClearFocusWindow);
ImGui::SameLine(); HelpMarker("Pressing Escape clears focused window.");
ImGui::Checkbox("io.ConfigNavCursorVisibleAuto", &io.ConfigNavCursorVisibleAuto);
ImGui::SameLine(); HelpMarker("Using directional navigation key makes the cursor visible. Mouse click hides the cursor.");
ImGui::Checkbox("io.ConfigNavCursorVisibleAlways", &io.ConfigNavCursorVisibleAlways);
ImGui::SameLine(); HelpMarker("Navigation cursor is always visible.");
ImGui::SeparatorText("Docking"); ImGui::SeparatorText("Docking");
ImGui::CheckboxFlags("io.ConfigFlags: DockingEnable", &io.ConfigFlags, ImGuiConfigFlags_DockingEnable); ImGui::CheckboxFlags("io.ConfigFlags: DockingEnable", &io.ConfigFlags, ImGuiConfigFlags_DockingEnable);
ImGui::SameLine(); ImGui::SameLine();
@ -583,6 +595,15 @@ void ImGui::ShowDemoWindow(bool* p_open)
ImGui::Unindent(); ImGui::Unindent();
} }
ImGui::SeparatorText("Windows");
ImGui::Checkbox("io.ConfigWindowsResizeFromEdges", &io.ConfigWindowsResizeFromEdges);
ImGui::SameLine(); HelpMarker("Enable resizing of windows from their edges and from the lower-left corner.\nThis requires ImGuiBackendFlags_HasMouseCursors for better mouse cursor feedback.");
ImGui::Checkbox("io.ConfigWindowsMoveFromTitleBarOnly", &io.ConfigWindowsMoveFromTitleBarOnly);
ImGui::Checkbox("io.ConfigWindowsCopyContentsWithCtrlC", &io.ConfigWindowsCopyContentsWithCtrlC); // [EXPERIMENTAL]
ImGui::SameLine(); HelpMarker("*EXPERIMENTAL* CTRL+C copy the contents of focused window into the clipboard.\n\nExperimental because:\n- (1) has known issues with nested Begin/End pairs.\n- (2) text output quality varies.\n- (3) text output is in submission order rather than spatial order.");
ImGui::Checkbox("io.ConfigScrollbarScrollByPage", &io.ConfigScrollbarScrollByPage);
ImGui::SameLine(); HelpMarker("Enable scrolling page by page when clicking outside the scrollbar grab.\nWhen disabled, always scroll to clicked location.\nWhen enabled, Shift+Click scrolls to clicked location.");
ImGui::SeparatorText("Widgets"); ImGui::SeparatorText("Widgets");
ImGui::Checkbox("io.ConfigInputTextCursorBlink", &io.ConfigInputTextCursorBlink); ImGui::Checkbox("io.ConfigInputTextCursorBlink", &io.ConfigInputTextCursorBlink);
ImGui::SameLine(); HelpMarker("Enable blinking cursor (optional as some users consider it to be distracting)."); ImGui::SameLine(); HelpMarker("Enable blinking cursor (optional as some users consider it to be distracting).");
@ -590,13 +611,28 @@ void ImGui::ShowDemoWindow(bool* p_open)
ImGui::SameLine(); HelpMarker("Pressing Enter will keep item active and select contents (single-line only)."); ImGui::SameLine(); HelpMarker("Pressing Enter will keep item active and select contents (single-line only).");
ImGui::Checkbox("io.ConfigDragClickToInputText", &io.ConfigDragClickToInputText); ImGui::Checkbox("io.ConfigDragClickToInputText", &io.ConfigDragClickToInputText);
ImGui::SameLine(); HelpMarker("Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving)."); ImGui::SameLine(); HelpMarker("Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving).");
ImGui::Checkbox("io.ConfigWindowsResizeFromEdges", &io.ConfigWindowsResizeFromEdges);
ImGui::SameLine(); HelpMarker("Enable resizing of windows from their edges and from the lower-left corner.\nThis requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback.");
ImGui::Checkbox("io.ConfigWindowsMoveFromTitleBarOnly", &io.ConfigWindowsMoveFromTitleBarOnly);
ImGui::Checkbox("io.ConfigMacOSXBehaviors", &io.ConfigMacOSXBehaviors); ImGui::Checkbox("io.ConfigMacOSXBehaviors", &io.ConfigMacOSXBehaviors);
ImGui::SameLine(); HelpMarker("Swap Cmd<>Ctrl keys, enable various MacOS style behaviors."); ImGui::SameLine(); HelpMarker("Swap Cmd<>Ctrl keys, enable various MacOS style behaviors.");
ImGui::Text("Also see Style->Rendering for rendering options."); ImGui::Text("Also see Style->Rendering for rendering options.");
// Also read: https://github.com/ocornut/imgui/wiki/Error-Handling
ImGui::SeparatorText("Error Handling");
ImGui::Checkbox("io.ConfigErrorRecovery", &io.ConfigErrorRecovery);
ImGui::SameLine(); HelpMarker(
"Options to configure how we handle recoverable errors.\n"
"- Error recovery is not perfect nor guaranteed! It is a feature to ease development.\n"
"- You not are not supposed to rely on it in the course of a normal application run.\n"
"- Possible usage: facilitate recovery from errors triggered from a scripting language or after specific exceptions handlers.\n"
"- Always ensure that on programmers seat you have at minimum Asserts or Tooltips enabled when making direct imgui API call!"
"Otherwise it would severely hinder your ability to catch and correct mistakes!");
ImGui::Checkbox("io.ConfigErrorRecoveryEnableAssert", &io.ConfigErrorRecoveryEnableAssert);
ImGui::Checkbox("io.ConfigErrorRecoveryEnableDebugLog", &io.ConfigErrorRecoveryEnableDebugLog);
ImGui::Checkbox("io.ConfigErrorRecoveryEnableTooltip", &io.ConfigErrorRecoveryEnableTooltip);
if (!io.ConfigErrorRecoveryEnableAssert && !io.ConfigErrorRecoveryEnableDebugLog && !io.ConfigErrorRecoveryEnableTooltip)
io.ConfigErrorRecoveryEnableAssert = io.ConfigErrorRecoveryEnableDebugLog = io.ConfigErrorRecoveryEnableTooltip = true;
// Also read: https://github.com/ocornut/imgui/wiki/Debug-Tools
ImGui::SeparatorText("Debug"); ImGui::SeparatorText("Debug");
ImGui::Checkbox("io.ConfigDebugIsDebuggerPresent", &io.ConfigDebugIsDebuggerPresent); ImGui::Checkbox("io.ConfigDebugIsDebuggerPresent", &io.ConfigDebugIsDebuggerPresent);
ImGui::SameLine(); HelpMarker("Enable various tools calling IM_DEBUG_BREAK().\n\nRequires a debugger being attached, otherwise IM_DEBUG_BREAK() options will appear to crash your application."); ImGui::SameLine(); HelpMarker("Enable various tools calling IM_DEBUG_BREAK().\n\nRequires a debugger being attached, otherwise IM_DEBUG_BREAK() options will appear to crash your application.");
@ -635,6 +671,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
ImGui::CheckboxFlags("io.BackendFlags: RendererHasVtxOffset", &io.BackendFlags, ImGuiBackendFlags_RendererHasVtxOffset); ImGui::CheckboxFlags("io.BackendFlags: RendererHasVtxOffset", &io.BackendFlags, ImGuiBackendFlags_RendererHasVtxOffset);
ImGui::CheckboxFlags("io.BackendFlags: RendererHasViewports", &io.BackendFlags, ImGuiBackendFlags_RendererHasViewports); ImGui::CheckboxFlags("io.BackendFlags: RendererHasViewports", &io.BackendFlags, ImGuiBackendFlags_RendererHasViewports);
ImGui::EndDisabled(); ImGui::EndDisabled();
ImGui::TreePop(); ImGui::TreePop();
ImGui::Spacing(); ImGui::Spacing();
} }
@ -1043,7 +1080,7 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
// The following examples are passed for documentation purpose but may not be useful to most users. // The following examples are passed for documentation purpose but may not be useful to most users.
// Passing ImGuiHoveredFlags_ForTooltip to IsItemHovered() will pull ImGuiHoveredFlags flags values from // Passing ImGuiHoveredFlags_ForTooltip to IsItemHovered() will pull ImGuiHoveredFlags flags values from
// 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav' depending on whether mouse or gamepad/keyboard is being used. // 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav' depending on whether mouse or keyboard/gamepad is being used.
// With default settings, ImGuiHoveredFlags_ForTooltip is equivalent to ImGuiHoveredFlags_DelayShort + ImGuiHoveredFlags_Stationary. // With default settings, ImGuiHoveredFlags_ForTooltip is equivalent to ImGuiHoveredFlags_DelayShort + ImGuiHoveredFlags_Stationary.
ImGui::Button("Manual", sz); ImGui::Button("Manual", sz);
if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip)) if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip))
@ -2304,7 +2341,10 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
// Demonstrate using advanced flags for DragXXX and SliderXXX functions. Note that the flags are the same! // Demonstrate using advanced flags for DragXXX and SliderXXX functions. Note that the flags are the same!
static ImGuiSliderFlags flags = ImGuiSliderFlags_None; static ImGuiSliderFlags flags = ImGuiSliderFlags_None;
ImGui::CheckboxFlags("ImGuiSliderFlags_AlwaysClamp", &flags, ImGuiSliderFlags_AlwaysClamp); ImGui::CheckboxFlags("ImGuiSliderFlags_AlwaysClamp", &flags, ImGuiSliderFlags_AlwaysClamp);
ImGui::SameLine(); HelpMarker("Always clamp value to min/max bounds (if any) when input manually with CTRL+Click."); ImGui::CheckboxFlags("ImGuiSliderFlags_ClampOnInput", &flags, ImGuiSliderFlags_ClampOnInput);
ImGui::SameLine(); HelpMarker("Clamp value to min/max bounds when input manually with CTRL+Click. By default CTRL+Click allows going out of bounds.");
ImGui::CheckboxFlags("ImGuiSliderFlags_ClampZeroRange", &flags, ImGuiSliderFlags_ClampZeroRange);
ImGui::SameLine(); HelpMarker("Clamp even if min==max==0.0f. Otherwise DragXXX functions don't clamp.");
ImGui::CheckboxFlags("ImGuiSliderFlags_Logarithmic", &flags, ImGuiSliderFlags_Logarithmic); ImGui::CheckboxFlags("ImGuiSliderFlags_Logarithmic", &flags, ImGuiSliderFlags_Logarithmic);
ImGui::SameLine(); HelpMarker("Enable logarithmic editing (more precision for small values)."); ImGui::SameLine(); HelpMarker("Enable logarithmic editing (more precision for small values).");
ImGui::CheckboxFlags("ImGuiSliderFlags_NoRoundToFormat", &flags, ImGuiSliderFlags_NoRoundToFormat); ImGui::CheckboxFlags("ImGuiSliderFlags_NoRoundToFormat", &flags, ImGuiSliderFlags_NoRoundToFormat);
@ -2322,6 +2362,8 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
ImGui::DragFloat("DragFloat (0 -> +inf)", &drag_f, 0.005f, 0.0f, FLT_MAX, "%.3f", flags); ImGui::DragFloat("DragFloat (0 -> +inf)", &drag_f, 0.005f, 0.0f, FLT_MAX, "%.3f", flags);
ImGui::DragFloat("DragFloat (-inf -> 1)", &drag_f, 0.005f, -FLT_MAX, 1.0f, "%.3f", flags); ImGui::DragFloat("DragFloat (-inf -> 1)", &drag_f, 0.005f, -FLT_MAX, 1.0f, "%.3f", flags);
ImGui::DragFloat("DragFloat (-inf -> +inf)", &drag_f, 0.005f, -FLT_MAX, +FLT_MAX, "%.3f", flags); ImGui::DragFloat("DragFloat (-inf -> +inf)", &drag_f, 0.005f, -FLT_MAX, +FLT_MAX, "%.3f", flags);
//ImGui::DragFloat("DragFloat (0 -> 0)", &drag_f, 0.005f, 0.0f, 0.0f, "%.3f", flags); // To test ClampZeroRange
//ImGui::DragFloat("DragFloat (100 -> 100)", &drag_f, 0.005f, 100.0f, 100.0f, "%.3f", flags);
ImGui::DragInt("DragInt (0 -> 100)", &drag_i, 0.5f, 0, 100, "%d", flags); ImGui::DragInt("DragInt (0 -> 100)", &drag_i, 0.5f, 0, 100, "%d", flags);
// Sliders // Sliders
@ -4004,6 +4046,9 @@ static void ShowDemoWindowLayout()
ImGui::SeparatorText("Manual-resize"); ImGui::SeparatorText("Manual-resize");
{ {
HelpMarker("Drag bottom border to resize. Double-click bottom border to auto-fit to vertical contents."); HelpMarker("Drag bottom border to resize. Double-click bottom border to auto-fit to vertical contents.");
//if (ImGui::Button("Set Height to 200"))
// ImGui::SetNextWindowSize(ImVec2(-FLT_MIN, 200.0f));
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetStyleColorVec4(ImGuiCol_FrameBg)); ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetStyleColorVec4(ImGuiCol_FrameBg));
if (ImGui::BeginChild("ResizableChild", ImVec2(-FLT_MIN, ImGui::GetTextLineHeightWithSpacing() * 8), ImGuiChildFlags_Borders | ImGuiChildFlags_ResizeY)) if (ImGui::BeginChild("ResizableChild", ImVec2(-FLT_MIN, ImGui::GetTextLineHeightWithSpacing() * 8), ImGuiChildFlags_Borders | ImGuiChildFlags_ResizeY))
for (int n = 0; n < 10; n++) for (int n = 0; n < 10; n++)
@ -7400,13 +7445,8 @@ static void ShowDemoWindowInputs()
// displaying the data for old/new backends. // displaying the data for old/new backends.
// User code should never have to go through such hoops! // User code should never have to go through such hoops!
// You can generally iterate between ImGuiKey_NamedKey_BEGIN and ImGuiKey_NamedKey_END. // You can generally iterate between ImGuiKey_NamedKey_BEGIN and ImGuiKey_NamedKey_END.
#ifdef IMGUI_DISABLE_OBSOLETE_KEYIO
struct funcs { static bool IsLegacyNativeDupe(ImGuiKey) { return false; } }; struct funcs { static bool IsLegacyNativeDupe(ImGuiKey) { return false; } };
ImGuiKey start_key = ImGuiKey_NamedKey_BEGIN; ImGuiKey start_key = ImGuiKey_NamedKey_BEGIN;
#else
struct funcs { static bool IsLegacyNativeDupe(ImGuiKey key) { return key >= 0 && key < 512 && ImGui::GetIO().KeyMap[key] != -1; } }; // Hide Native<>ImGuiKey duplicates when both exists in the array
ImGuiKey start_key = (ImGuiKey)0;
#endif
ImGui::Text("Keys down:"); for (ImGuiKey key = start_key; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1)) { if (funcs::IsLegacyNativeDupe(key) || !ImGui::IsKeyDown(key)) continue; ImGui::SameLine(); ImGui::Text((key < ImGuiKey_NamedKey_BEGIN) ? "\"%s\"" : "\"%s\" %d", ImGui::GetKeyName(key), key); } ImGui::Text("Keys down:"); for (ImGuiKey key = start_key; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1)) { if (funcs::IsLegacyNativeDupe(key) || !ImGui::IsKeyDown(key)) continue; ImGui::SameLine(); ImGui::Text((key < ImGuiKey_NamedKey_BEGIN) ? "\"%s\"" : "\"%s\" %d", ImGui::GetKeyName(key), key); }
ImGui::Text("Keys mods: %s%s%s%s", io.KeyCtrl ? "CTRL " : "", io.KeyShift ? "SHIFT " : "", io.KeyAlt ? "ALT " : "", io.KeySuper ? "SUPER " : ""); ImGui::Text("Keys mods: %s%s%s%s", io.KeyCtrl ? "CTRL " : "", io.KeyShift ? "SHIFT " : "", io.KeyAlt ? "ALT " : "", io.KeySuper ? "SUPER " : "");
ImGui::Text("Chars queue:"); for (int i = 0; i < io.InputQueueCharacters.Size; i++) { ImWchar c = io.InputQueueCharacters[i]; ImGui::SameLine(); ImGui::Text("\'%c\' (0x%04X)", (c > ' ' && c <= 255) ? (char)c : '?', c); } // FIXME: We should convert 'c' to UTF-8 here but the functions are not public. ImGui::Text("Chars queue:"); for (int i = 0; i < io.InputQueueCharacters.Size; i++) { ImWchar c = io.InputQueueCharacters[i]; ImGui::SameLine(); ImGui::Text("\'%c\' (0x%04X)", (c > ' ' && c <= 255) ? (char)c : '?', c); } // FIXME: We should convert 'c' to UTF-8 here but the functions are not public.
@ -7729,9 +7769,6 @@ void ImGui::ShowAboutWindow(bool* p_open)
#ifdef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifdef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
ImGui::Text("define: IMGUI_DISABLE_OBSOLETE_FUNCTIONS"); ImGui::Text("define: IMGUI_DISABLE_OBSOLETE_FUNCTIONS");
#endif #endif
#ifdef IMGUI_DISABLE_OBSOLETE_KEYIO
ImGui::Text("define: IMGUI_DISABLE_OBSOLETE_KEYIO");
#endif
#ifdef IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS #ifdef IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS
ImGui::Text("define: IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS"); ImGui::Text("define: IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS");
#endif #endif
@ -7805,10 +7842,9 @@ void ImGui::ShowAboutWindow(bool* p_open)
ImGui::Text("io.ConfigFlags: 0x%08X", io.ConfigFlags); ImGui::Text("io.ConfigFlags: 0x%08X", io.ConfigFlags);
if (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) ImGui::Text(" NavEnableKeyboard"); if (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) ImGui::Text(" NavEnableKeyboard");
if (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) ImGui::Text(" NavEnableGamepad"); if (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) ImGui::Text(" NavEnableGamepad");
if (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) ImGui::Text(" NavEnableSetMousePos");
if (io.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard) ImGui::Text(" NavNoCaptureKeyboard");
if (io.ConfigFlags & ImGuiConfigFlags_NoMouse) ImGui::Text(" NoMouse"); if (io.ConfigFlags & ImGuiConfigFlags_NoMouse) ImGui::Text(" NoMouse");
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) ImGui::Text(" NoMouseCursorChange"); if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) ImGui::Text(" NoMouseCursorChange");
if (io.ConfigFlags & ImGuiConfigFlags_NoKeyboard) ImGui::Text(" NoKeyboard");
if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable) ImGui::Text(" DockingEnable"); if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable) ImGui::Text(" DockingEnable");
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) ImGui::Text(" ViewportsEnable"); if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) ImGui::Text(" ViewportsEnable");
if (io.ConfigFlags & ImGuiConfigFlags_DpiEnableScaleViewports) ImGui::Text(" DpiEnableScaleViewports"); if (io.ConfigFlags & ImGuiConfigFlags_DpiEnableScaleViewports) ImGui::Text(" DpiEnableScaleViewports");
@ -7823,6 +7859,8 @@ void ImGui::ShowAboutWindow(bool* p_open)
if (io.ConfigDockingAlwaysTabBar) ImGui::Text("io.ConfigDockingAlwaysTabBar"); if (io.ConfigDockingAlwaysTabBar) ImGui::Text("io.ConfigDockingAlwaysTabBar");
if (io.ConfigDockingTransparentPayload) ImGui::Text("io.ConfigDockingTransparentPayload"); if (io.ConfigDockingTransparentPayload) ImGui::Text("io.ConfigDockingTransparentPayload");
if (io.ConfigMacOSXBehaviors) ImGui::Text("io.ConfigMacOSXBehaviors"); if (io.ConfigMacOSXBehaviors) ImGui::Text("io.ConfigMacOSXBehaviors");
if (io.ConfigNavMoveSetMousePos) ImGui::Text("io.ConfigNavMoveSetMousePos");
if (io.ConfigNavCaptureKeyboard) ImGui::Text("io.ConfigNavCaptureKeyboard");
if (io.ConfigInputTextCursorBlink) ImGui::Text("io.ConfigInputTextCursorBlink"); if (io.ConfigInputTextCursorBlink) ImGui::Text("io.ConfigInputTextCursorBlink");
if (io.ConfigWindowsResizeFromEdges) ImGui::Text("io.ConfigWindowsResizeFromEdges"); if (io.ConfigWindowsResizeFromEdges) ImGui::Text("io.ConfigWindowsResizeFromEdges");
if (io.ConfigWindowsMoveFromTitleBarOnly) ImGui::Text("io.ConfigWindowsMoveFromTitleBarOnly"); if (io.ConfigWindowsMoveFromTitleBarOnly) ImGui::Text("io.ConfigWindowsMoveFromTitleBarOnly");
@ -10476,7 +10514,7 @@ struct ExampleAssetsBrowser
// Rendering parameters // Rendering parameters
const ImU32 icon_type_overlay_colors[3] = { 0, IM_COL32(200, 70, 70, 255), IM_COL32(70, 170, 70, 255) }; const ImU32 icon_type_overlay_colors[3] = { 0, IM_COL32(200, 70, 70, 255), IM_COL32(70, 170, 70, 255) };
const ImU32 icon_bg_color = ImGui::GetColorU32(ImGuiCol_MenuBarBg); const ImU32 icon_bg_color = ImGui::GetColorU32(IM_COL32(35, 35, 35, 220));
const ImVec2 icon_type_overlay_size = ImVec2(4.0f, 4.0f); const ImVec2 icon_type_overlay_size = ImVec2(4.0f, 4.0f);
const bool display_label = (LayoutItemSize.x >= ImGui::CalcTextSize("999").x); const bool display_label = (LayoutItemSize.x >= ImGui::CalcTextSize("999").x);

View File

@ -1,4 +1,4 @@
// dear imgui, v1.91.2 WIP // dear imgui, v1.91.5
// (drawing and font code) // (drawing and font code)
/* /*
@ -66,13 +66,14 @@ Index of this file:
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
#pragma clang diagnostic ignored "-Wreserved-identifier" // warning: identifier '_Xxx' is reserved because it starts with '_' followed by a capital letter #pragma clang diagnostic ignored "-Wreserved-identifier" // warning: identifier '_Xxx' is reserved because it starts with '_' followed by a capital letter
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
#pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type
#elif defined(__GNUC__) #elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used #pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function #pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value #pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value
#pragma GCC diagnostic ignored "-Wstack-protector" // warning: stack protector not protecting local variables: variable length buffer #pragma GCC diagnostic ignored "-Wstack-protector" // warning: stack protector not protecting local variables: variable length buffer
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead #pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
#endif #endif
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -101,7 +102,7 @@ namespace IMGUI_STB_NAMESPACE
#if defined(__clang__) #if defined(__clang__)
#pragma clang diagnostic push #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-function" #pragma clang diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
#pragma clang diagnostic ignored "-Wmissing-prototypes" #pragma clang diagnostic ignored "-Wmissing-prototypes"
#pragma clang diagnostic ignored "-Wimplicit-fallthrough" #pragma clang diagnostic ignored "-Wimplicit-fallthrough"
#pragma clang diagnostic ignored "-Wcast-qual" // warning: cast from 'const xxxx *' to 'xxx *' drops const qualifier #pragma clang diagnostic ignored "-Wcast-qual" // warning: cast from 'const xxxx *' to 'xxx *' drops const qualifier
@ -217,7 +218,7 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst)
colors[ImGuiCol_TabSelectedOverline] = colors[ImGuiCol_HeaderActive]; colors[ImGuiCol_TabSelectedOverline] = colors[ImGuiCol_HeaderActive];
colors[ImGuiCol_TabDimmed] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f); colors[ImGuiCol_TabDimmed] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f);
colors[ImGuiCol_TabDimmedSelected] = ImLerp(colors[ImGuiCol_TabSelected], colors[ImGuiCol_TitleBg], 0.40f); colors[ImGuiCol_TabDimmedSelected] = ImLerp(colors[ImGuiCol_TabSelected], colors[ImGuiCol_TitleBg], 0.40f);
colors[ImGuiCol_TabDimmedSelectedOverline] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); colors[ImGuiCol_TabDimmedSelectedOverline] = ImVec4(0.50f, 0.50f, 0.50f, 0.00f);
colors[ImGuiCol_DockingPreview] = colors[ImGuiCol_HeaderActive] * ImVec4(1.0f, 1.0f, 1.0f, 0.7f); colors[ImGuiCol_DockingPreview] = colors[ImGuiCol_HeaderActive] * ImVec4(1.0f, 1.0f, 1.0f, 0.7f);
colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f); colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);
colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f);
@ -232,7 +233,7 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst)
colors[ImGuiCol_TextLink] = colors[ImGuiCol_HeaderActive]; colors[ImGuiCol_TextLink] = colors[ImGuiCol_HeaderActive];
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f);
colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
colors[ImGuiCol_NavHighlight] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); colors[ImGuiCol_NavCursor] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f); colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f); colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f);
@ -282,7 +283,7 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst)
colors[ImGuiCol_TabSelectedOverline] = colors[ImGuiCol_HeaderActive]; colors[ImGuiCol_TabSelectedOverline] = colors[ImGuiCol_HeaderActive];
colors[ImGuiCol_TabDimmed] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f); colors[ImGuiCol_TabDimmed] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f);
colors[ImGuiCol_TabDimmedSelected] = ImLerp(colors[ImGuiCol_TabSelected], colors[ImGuiCol_TitleBg], 0.40f); colors[ImGuiCol_TabDimmedSelected] = ImLerp(colors[ImGuiCol_TabSelected], colors[ImGuiCol_TitleBg], 0.40f);
colors[ImGuiCol_TabDimmedSelectedOverline] = colors[ImGuiCol_HeaderActive]; colors[ImGuiCol_TabDimmedSelectedOverline] = ImVec4(0.53f, 0.53f, 0.87f, 0.00f);
colors[ImGuiCol_DockingPreview] = colors[ImGuiCol_Header] * ImVec4(1.0f, 1.0f, 1.0f, 0.7f); colors[ImGuiCol_DockingPreview] = colors[ImGuiCol_Header] * ImVec4(1.0f, 1.0f, 1.0f, 0.7f);
colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f); colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);
colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
@ -297,7 +298,7 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst)
colors[ImGuiCol_TextLink] = colors[ImGuiCol_HeaderActive]; colors[ImGuiCol_TextLink] = colors[ImGuiCol_HeaderActive];
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f); colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f);
colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
colors[ImGuiCol_NavHighlight] = colors[ImGuiCol_HeaderHovered]; colors[ImGuiCol_NavCursor] = colors[ImGuiCol_HeaderHovered];
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f); colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f);
@ -348,7 +349,7 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
colors[ImGuiCol_TabSelectedOverline] = colors[ImGuiCol_HeaderActive]; colors[ImGuiCol_TabSelectedOverline] = colors[ImGuiCol_HeaderActive];
colors[ImGuiCol_TabDimmed] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f); colors[ImGuiCol_TabDimmed] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f);
colors[ImGuiCol_TabDimmedSelected] = ImLerp(colors[ImGuiCol_TabSelected], colors[ImGuiCol_TitleBg], 0.40f); colors[ImGuiCol_TabDimmedSelected] = ImLerp(colors[ImGuiCol_TabSelected], colors[ImGuiCol_TitleBg], 0.40f);
colors[ImGuiCol_TabDimmedSelectedOverline] = ImVec4(0.26f, 0.59f, 1.00f, 1.00f); colors[ImGuiCol_TabDimmedSelectedOverline] = ImVec4(0.26f, 0.59f, 1.00f, 0.00f);
colors[ImGuiCol_DockingPreview] = colors[ImGuiCol_Header] * ImVec4(1.0f, 1.0f, 1.0f, 0.7f); colors[ImGuiCol_DockingPreview] = colors[ImGuiCol_Header] * ImVec4(1.0f, 1.0f, 1.0f, 0.7f);
colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f); colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);
colors[ImGuiCol_PlotLines] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f); colors[ImGuiCol_PlotLines] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f);
@ -363,7 +364,7 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
colors[ImGuiCol_TextLink] = colors[ImGuiCol_HeaderActive]; colors[ImGuiCol_TextLink] = colors[ImGuiCol_HeaderActive];
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f);
colors[ImGuiCol_DragDropTarget] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); colors[ImGuiCol_DragDropTarget] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
colors[ImGuiCol_NavHighlight] = colors[ImGuiCol_HeaderHovered]; colors[ImGuiCol_NavCursor] = colors[ImGuiCol_HeaderHovered];
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(0.70f, 0.70f, 0.70f, 0.70f); colors[ImGuiCol_NavWindowingHighlight] = ImVec4(0.70f, 0.70f, 0.70f, 0.70f);
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.20f); colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.20f);
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f);
@ -420,6 +421,7 @@ void ImDrawList::_ResetForNewFrame()
_IdxWritePtr = NULL; _IdxWritePtr = NULL;
_ClipRectStack.resize(0); _ClipRectStack.resize(0);
_TextureIdStack.resize(0); _TextureIdStack.resize(0);
_CallbacksDataBuf.resize(0);
_Path.resize(0); _Path.resize(0);
_Splitter.Clear(); _Splitter.Clear();
CmdBuffer.push_back(ImDrawCmd()); CmdBuffer.push_back(ImDrawCmd());
@ -437,6 +439,7 @@ void ImDrawList::_ClearFreeMemory()
_IdxWritePtr = NULL; _IdxWritePtr = NULL;
_ClipRectStack.clear(); _ClipRectStack.clear();
_TextureIdStack.clear(); _TextureIdStack.clear();
_CallbacksDataBuf.clear();
_Path.clear(); _Path.clear();
_Splitter.ClearFreeMemory(); _Splitter.ClearFreeMemory();
} }
@ -476,7 +479,7 @@ void ImDrawList::_PopUnusedDrawCmd()
} }
} }
void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data) void ImDrawList::AddCallback(ImDrawCallback callback, void* userdata, size_t userdata_size)
{ {
IM_ASSERT_PARANOID(CmdBuffer.Size > 0); IM_ASSERT_PARANOID(CmdBuffer.Size > 0);
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
@ -486,8 +489,26 @@ void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data)
AddDrawCmd(); AddDrawCmd();
curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
} }
curr_cmd->UserCallback = callback; curr_cmd->UserCallback = callback;
curr_cmd->UserCallbackData = callback_data; if (userdata_size == 0)
{
// Store user data directly in command (no indirection)
curr_cmd->UserCallbackData = userdata;
curr_cmd->UserCallbackDataSize = 0;
curr_cmd->UserCallbackDataOffset = -1;
}
else
{
// Copy and store user data in a buffer
IM_ASSERT(userdata != NULL);
IM_ASSERT(userdata_size < (1u << 31));
curr_cmd->UserCallbackData = NULL; // Will be resolved during Render()
curr_cmd->UserCallbackDataSize = (int)userdata_size;
curr_cmd->UserCallbackDataOffset = _CallbacksDataBuf.Size;
_CallbacksDataBuf.resize(_CallbacksDataBuf.Size + (int)userdata_size);
memcpy(_CallbacksDataBuf.Data + (size_t)curr_cmd->UserCallbackDataOffset, userdata, userdata_size);
}
AddDrawCmd(); // Force a new command after us (see comment below) AddDrawCmd(); // Force a new command after us (see comment below)
} }
@ -1632,7 +1653,7 @@ void ImDrawList::AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const Im
PathStroke(col, 0, thickness); PathStroke(col, 0, thickness);
} }
void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec4* cpu_fine_clip_rect) void ImDrawList::AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec4* cpu_fine_clip_rect)
{ {
if ((col & IM_COL32_A_MASK) == 0) if ((col & IM_COL32_A_MASK) == 0)
return; return;
@ -2228,6 +2249,12 @@ void ImGui::AddDrawListToDrawDataEx(ImDrawData* draw_data, ImVector<ImDrawList*>
if (sizeof(ImDrawIdx) == 2) if (sizeof(ImDrawIdx) == 2)
IM_ASSERT(draw_list->_VtxCurrentIdx < (1 << 16) && "Too many vertices in ImDrawList using 16-bit indices. Read comment above"); IM_ASSERT(draw_list->_VtxCurrentIdx < (1 << 16) && "Too many vertices in ImDrawList using 16-bit indices. Read comment above");
// Resolve callback data pointers
if (draw_list->_CallbacksDataBuf.Size > 0)
for (ImDrawCmd& cmd : draw_list->CmdBuffer)
if (cmd.UserCallback != NULL && cmd.UserCallbackDataOffset != -1 && cmd.UserCallbackDataSize > 0)
cmd.UserCallbackData = draw_list->_CallbacksDataBuf.Data + cmd.UserCallbackDataOffset;
// Add to output list + records state in ImDrawData // Add to output list + records state in ImDrawData
out_list->push_back(draw_list); out_list->push_back(draw_list);
draw_data->CmdListsCount++; draw_data->CmdListsCount++;
@ -2655,6 +2682,7 @@ int ImFontAtlas::AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int
r.Width = (unsigned short)width; r.Width = (unsigned short)width;
r.Height = (unsigned short)height; r.Height = (unsigned short)height;
r.GlyphID = id; r.GlyphID = id;
r.GlyphColored = 0; // Set to 1 manually to mark glyph as colored // FIXME: No official API for that (#8133)
r.GlyphAdvanceX = advance_x; r.GlyphAdvanceX = advance_x;
r.GlyphOffset = offset; r.GlyphOffset = offset;
r.Font = font; r.Font = font;
@ -3265,6 +3293,8 @@ void ImFontAtlasBuildFinish(ImFontAtlas* atlas)
ImVec2 uv0, uv1; ImVec2 uv0, uv1;
atlas->CalcCustomRectUV(r, &uv0, &uv1); atlas->CalcCustomRectUV(r, &uv0, &uv1);
r->Font->AddGlyph(NULL, (ImWchar)r->GlyphID, r->GlyphOffset.x, r->GlyphOffset.y, r->GlyphOffset.x + r->Width, r->GlyphOffset.y + r->Height, uv0.x, uv0.y, uv1.x, uv1.y, r->GlyphAdvanceX); r->Font->AddGlyph(NULL, (ImWchar)r->GlyphID, r->GlyphOffset.x, r->GlyphOffset.y, r->GlyphOffset.x + r->Width, r->GlyphOffset.y + r->Height, uv0.x, uv0.y, uv1.x, uv1.y, r->GlyphAdvanceX);
if (r->GlyphColored)
r->Font->Glyphs.back().Colored = 1;
} }
// Build all fonts lookup tables // Build all fonts lookup tables
@ -3618,6 +3648,7 @@ void ImFont::ClearOutputData()
DirtyLookupTables = true; DirtyLookupTables = true;
Ascent = Descent = 0.0f; Ascent = Descent = 0.0f;
MetricsTotalSurface = 0; MetricsTotalSurface = 0;
memset(Used4kPagesMap, 0, sizeof(Used4kPagesMap));
} }
static ImWchar FindFirstExistingGlyph(ImFont* font, const ImWchar* candidate_chars, int candidate_chars_count) static ImWchar FindFirstExistingGlyph(ImFont* font, const ImWchar* candidate_chars, int candidate_chars_count)
@ -3802,7 +3833,7 @@ void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst)
IndexAdvanceX[dst] = (src < index_size) ? IndexAdvanceX.Data[src] : 1.0f; IndexAdvanceX[dst] = (src < index_size) ? IndexAdvanceX.Data[src] : 1.0f;
} }
const ImFontGlyph* ImFont::FindGlyph(ImWchar c) const const ImFontGlyph* ImFont::FindGlyph(ImWchar c)
{ {
if (c >= (size_t)IndexLookup.Size) if (c >= (size_t)IndexLookup.Size)
return FallbackGlyph; return FallbackGlyph;
@ -3812,7 +3843,7 @@ const ImFontGlyph* ImFont::FindGlyph(ImWchar c) const
return &Glyphs.Data[i]; return &Glyphs.Data[i];
} }
const ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c) const const ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c)
{ {
if (c >= (size_t)IndexLookup.Size) if (c >= (size_t)IndexLookup.Size)
return NULL; return NULL;
@ -3822,7 +3853,7 @@ const ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c) const
return &Glyphs.Data[i]; return &Glyphs.Data[i];
} }
// Wrapping skips upcoming blanks // Trim trailing space and find beginning of next line
static inline const char* CalcWordWrapNextLineStartA(const char* text, const char* text_end) static inline const char* CalcWordWrapNextLineStartA(const char* text, const char* text_end)
{ {
while (text < text_end && ImCharIsBlankA(*text)) while (text < text_end && ImCharIsBlankA(*text))
@ -3832,10 +3863,12 @@ static inline const char* CalcWordWrapNextLineStartA(const char* text, const cha
return text; return text;
} }
#define ImFontGetCharAdvanceX(_FONT, _CH) ((int)(_CH) < (_FONT)->IndexAdvanceX.Size ? (_FONT)->IndexAdvanceX.Data[_CH] : (_FONT)->FallbackAdvanceX)
// Simple word-wrapping for English, not full-featured. Please submit failing cases! // Simple word-wrapping for English, not full-featured. Please submit failing cases!
// This will return the next location to wrap from. If no wrapping if necessary, this will fast-forward to e.g. text_end. // This will return the next location to wrap from. If no wrapping if necessary, this will fast-forward to e.g. text_end.
// FIXME: Much possible improvements (don't cut things like "word !", "word!!!" but cut within "word,,,,", more sensible support for punctuations, support for Unicode punctuations, etc.) // FIXME: Much possible improvements (don't cut things like "word !", "word!!!" but cut within "word,,,,", more sensible support for punctuations, support for Unicode punctuations, etc.)
const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width)
{ {
// For references, possible wrap point marked with ^ // For references, possible wrap point marked with ^
// "aaa bbb, ccc,ddd. eee fff. ggg!" // "aaa bbb, ccc,ddd. eee fff. ggg!"
@ -3884,7 +3917,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
} }
} }
const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX.Data[c] : FallbackAdvanceX); const float char_width = ImFontGetCharAdvanceX(this, c);
if (ImCharIsBlankW(c)) if (ImCharIsBlankW(c))
{ {
if (inside_word) if (inside_word)
@ -3933,7 +3966,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
return s; return s;
} }
ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining) const ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining)
{ {
if (!text_end) if (!text_end)
text_end = text_begin + strlen(text_begin); // FIXME-OPT: Need to avoid this. text_end = text_begin + strlen(text_begin); // FIXME-OPT: Need to avoid this.
@ -3989,7 +4022,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
continue; continue;
} }
const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX.Data[c] : FallbackAdvanceX) * scale; const float char_width = ImFontGetCharAdvanceX(this, c) * scale;
if (line_width + char_width >= max_width) if (line_width + char_width >= max_width)
{ {
s = prev_s; s = prev_s;
@ -4012,7 +4045,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
} }
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound. // Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c) const void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c)
{ {
const ImFontGlyph* glyph = FindGlyph(c); const ImFontGlyph* glyph = FindGlyph(c);
if (!glyph || !glyph->Visible) if (!glyph || !glyph->Visible)
@ -4027,7 +4060,7 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, Im
} }
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound. // Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip) const void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip)
{ {
if (!text_end) if (!text_end)
text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls. text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
@ -4038,9 +4071,9 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
if (y > clip_rect.w) if (y > clip_rect.w)
return; return;
const float start_x = x;
const float scale = size / FontSize; const float scale = size / FontSize;
const float line_height = FontSize * scale; const float line_height = FontSize * scale;
const float origin_x = x;
const bool word_wrap_enabled = (wrap_width > 0.0f); const bool word_wrap_enabled = (wrap_width > 0.0f);
// Fast-forward to first visible line // Fast-forward to first visible line
@ -4099,11 +4132,11 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
{ {
// Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature. // Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature.
if (!word_wrap_eol) if (!word_wrap_eol)
word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - (x - start_x)); word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - (x - origin_x));
if (s >= word_wrap_eol) if (s >= word_wrap_eol)
{ {
x = start_x; x = origin_x;
y += line_height; y += line_height;
if (y > clip_rect.w) if (y > clip_rect.w)
break; // break out of main loop break; // break out of main loop
@ -4124,7 +4157,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
{ {
if (c == '\n') if (c == '\n')
{ {
x = start_x; x = origin_x;
y += line_height; y += line_height;
if (y > clip_rect.w) if (y > clip_rect.w)
break; // break out of main loop break; // break out of main loop

View File

@ -1,4 +1,4 @@
// dear imgui, v1.91.2 WIP // dear imgui, v1.91.5
// (internal structures/api) // (internal structures/api)
// You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility. // You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility.
@ -28,6 +28,7 @@ Index of this file:
// [SECTION] Viewport support // [SECTION] Viewport support
// [SECTION] Settings support // [SECTION] Settings support
// [SECTION] Localization support // [SECTION] Localization support
// [SECTION] Error handling, State recovery support
// [SECTION] Metrics, Debug tools // [SECTION] Metrics, Debug tools
// [SECTION] Generic context hooks // [SECTION] Generic context hooks
// [SECTION] ImGuiContext (main imgui context) // [SECTION] ImGuiContext (main imgui context)
@ -81,15 +82,14 @@ Index of this file:
#endif #endif
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx' #pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants ok, for ImFloor() #pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants ok, for ImFloor()
#pragma clang diagnostic ignored "-Wunused-function" // for stb_textedit.h #pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast
#pragma clang diagnostic ignored "-Wmissing-prototypes" // for stb_textedit.h #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant
#pragma clang diagnostic ignored "-Wold-style-cast" #pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
#pragma clang diagnostic ignored "-Wdouble-promotion"
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
#pragma clang diagnostic ignored "-Wmissing-noreturn" // warning: function 'xxx' could be declared with attribute 'noreturn' #pragma clang diagnostic ignored "-Wmissing-noreturn" // warning: function 'xxx' could be declared with attribute 'noreturn'
#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"// warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated #pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"// warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
#pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type
#elif defined(__GNUC__) #elif defined(__GNUC__)
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
@ -135,6 +135,7 @@ struct ImGuiDockContext; // Docking system context
struct ImGuiDockRequest; // Docking system dock/undock queued request struct ImGuiDockRequest; // Docking system dock/undock queued request
struct ImGuiDockNode; // Docking system node (hold a list of Windows OR two child dock nodes) struct ImGuiDockNode; // Docking system node (hold a list of Windows OR two child dock nodes)
struct ImGuiDockNodeSettings; // Storage for a dock node in .ini file (we preserve those even if the associated dock node isn't active during the session) struct ImGuiDockNodeSettings; // Storage for a dock node in .ini file (we preserve those even if the associated dock node isn't active during the session)
struct ImGuiErrorRecoveryState; // Storage of stack sizes for error handling and recovery
struct ImGuiGroupData; // Stacked storage data for BeginGroup()/EndGroup() struct ImGuiGroupData; // Stacked storage data for BeginGroup()/EndGroup()
struct ImGuiInputTextState; // Internal state of the currently focused/edited text input box struct ImGuiInputTextState; // Internal state of the currently focused/edited text input box
struct ImGuiInputTextDeactivateData;// Short term storage to backup text of a deactivating InputText() while another is stealing active id struct ImGuiInputTextDeactivateData;// Short term storage to backup text of a deactivating InputText() while another is stealing active id
@ -143,7 +144,7 @@ struct ImGuiLocEntry; // A localization entry.
struct ImGuiMenuColumns; // Simple column measurement, currently used for MenuItem() only struct ImGuiMenuColumns; // Simple column measurement, currently used for MenuItem() only
struct ImGuiMultiSelectState; // Multi-selection persistent state (for focused selection). struct ImGuiMultiSelectState; // Multi-selection persistent state (for focused selection).
struct ImGuiMultiSelectTempData; // Multi-selection temporary state (while traversing). struct ImGuiMultiSelectTempData; // Multi-selection temporary state (while traversing).
struct ImGuiNavItemData; // Result of a gamepad/keyboard directional navigation move query result struct ImGuiNavItemData; // Result of a keyboard/gamepad directional navigation move query result
struct ImGuiMetricsConfig; // Storage for ShowMetricsWindow() and DebugNodeXXX() functions struct ImGuiMetricsConfig; // Storage for ShowMetricsWindow() and DebugNodeXXX() functions
struct ImGuiNextWindowData; // Storage for SetNextWindow** functions struct ImGuiNextWindowData; // Storage for SetNextWindow** functions
struct ImGuiNextItemData; // Storage for SetNextItem** functions struct ImGuiNextItemData; // Storage for SetNextItem** functions
@ -151,7 +152,6 @@ struct ImGuiOldColumnData; // Storage data for a single column for lega
struct ImGuiOldColumns; // Storage data for a columns set for legacy Columns() api struct ImGuiOldColumns; // Storage data for a columns set for legacy Columns() api
struct ImGuiPopupData; // Storage for current popup stack struct ImGuiPopupData; // Storage for current popup stack
struct ImGuiSettingsHandler; // Storage for one type registered in the .ini file struct ImGuiSettingsHandler; // Storage for one type registered in the .ini file
struct ImGuiStackSizes; // Storage of stack sizes for debugging/asserting
struct ImGuiStyleMod; // Stacked style modifier, backup of modified data so we can restore it struct ImGuiStyleMod; // Stacked style modifier, backup of modified data so we can restore it
struct ImGuiTabBar; // Storage for a tab bar struct ImGuiTabBar; // Storage for a tab bar
struct ImGuiTabItem; // Storage for a tab item (within a tab bar) struct ImGuiTabItem; // Storage for a tab item (within a tab bar)
@ -179,10 +179,11 @@ typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // E
// Flags // Flags
typedef int ImGuiActivateFlags; // -> enum ImGuiActivateFlags_ // Flags: for navigation/focus function (will be for ActivateItem() later) typedef int ImGuiActivateFlags; // -> enum ImGuiActivateFlags_ // Flags: for navigation/focus function (will be for ActivateItem() later)
typedef int ImGuiDebugLogFlags; // -> enum ImGuiDebugLogFlags_ // Flags: for ShowDebugLogWindow(), g.DebugLogFlags typedef int ImGuiDebugLogFlags; // -> enum ImGuiDebugLogFlags_ // Flags: for ShowDebugLogWindow(), g.DebugLogFlags
typedef int ImGuiFocusRequestFlags; // -> enum ImGuiFocusRequestFlags_ // Flags: for FocusWindow(); typedef int ImGuiFocusRequestFlags; // -> enum ImGuiFocusRequestFlags_ // Flags: for FocusWindow()
typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for g.LastItemData.StatusFlags typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for g.LastItemData.StatusFlags
typedef int ImGuiOldColumnFlags; // -> enum ImGuiOldColumnFlags_ // Flags: for BeginColumns() typedef int ImGuiOldColumnFlags; // -> enum ImGuiOldColumnFlags_ // Flags: for BeginColumns()
typedef int ImGuiNavHighlightFlags; // -> enum ImGuiNavHighlightFlags_ // Flags: for RenderNavHighlight() typedef int ImGuiLogFlags; // -> enum ImGuiLogFlags_ // Flags: for LogBegin() text capturing function
typedef int ImGuiNavRenderCursorFlags; // -> enum ImGuiNavRenderCursorFlags_//Flags: for RenderNavCursor()
typedef int ImGuiNavMoveFlags; // -> enum ImGuiNavMoveFlags_ // Flags: for navigation requests typedef int ImGuiNavMoveFlags; // -> enum ImGuiNavMoveFlags_ // Flags: for navigation requests
typedef int ImGuiNextItemDataFlags; // -> enum ImGuiNextItemDataFlags_ // Flags: for SetNextItemXXX() functions typedef int ImGuiNextItemDataFlags; // -> enum ImGuiNextItemDataFlags_ // Flags: for SetNextItemXXX() functions
typedef int ImGuiNextWindowDataFlags; // -> enum ImGuiNextWindowDataFlags_// Flags: for SetNextWindowXXX() functions typedef int ImGuiNextWindowDataFlags; // -> enum ImGuiNextWindowDataFlags_// Flags: for SetNextWindowXXX() functions
@ -193,8 +194,6 @@ typedef int ImGuiTooltipFlags; // -> enum ImGuiTooltipFlags_ // F
typedef int ImGuiTypingSelectFlags; // -> enum ImGuiTypingSelectFlags_ // Flags: for GetTypingSelectRequest() typedef int ImGuiTypingSelectFlags; // -> enum ImGuiTypingSelectFlags_ // Flags: for GetTypingSelectRequest()
typedef int ImGuiWindowRefreshFlags; // -> enum ImGuiWindowRefreshFlags_ // Flags: for SetNextWindowRefreshPolicy() typedef int ImGuiWindowRefreshFlags; // -> enum ImGuiWindowRefreshFlags_ // Flags: for SetNextWindowRefreshPolicy()
typedef void (*ImGuiErrorLogCallback)(void* user_data, const char* fmt, ...);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] Context pointer // [SECTION] Context pointer
// See implementation of this variable in imgui.cpp for comments and details. // See implementation of this variable in imgui.cpp for comments and details.
@ -227,6 +226,7 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
#else #else
#define IMGUI_DEBUG_LOG(...) ((void)0) #define IMGUI_DEBUG_LOG(...) ((void)0)
#endif #endif
#define IMGUI_DEBUG_LOG_ERROR(...) do { ImGuiContext& g2 = *GImGui; if (g2.DebugLogFlags & ImGuiDebugLogFlags_EventError) IMGUI_DEBUG_LOG(__VA_ARGS__); else g2.DebugLogSkippedErrors++; } while (0)
#define IMGUI_DEBUG_LOG_ACTIVEID(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventActiveId) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) #define IMGUI_DEBUG_LOG_ACTIVEID(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventActiveId) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
#define IMGUI_DEBUG_LOG_FOCUS(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventFocus) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) #define IMGUI_DEBUG_LOG_FOCUS(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventFocus) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
#define IMGUI_DEBUG_LOG_POPUP(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventPopup) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) #define IMGUI_DEBUG_LOG_POPUP(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventPopup) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
@ -250,12 +250,6 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
#define IM_ASSERT_PARANOID(_EXPR) #define IM_ASSERT_PARANOID(_EXPR)
#endif #endif
// Error handling
// Down the line in some frameworks/languages we would like to have a way to redirect those to the programmer and recover from more faults.
#ifndef IM_ASSERT_USER_ERROR
#define IM_ASSERT_USER_ERROR(_EXP,_MSG) IM_ASSERT((_EXP) && _MSG) // Recoverable User Error
#endif
// Misc Macros // Misc Macros
#define IM_PI 3.14159265358979323846f #define IM_PI 3.14159265358979323846f
#ifdef _WIN32 #ifdef _WIN32
@ -277,6 +271,15 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
#define IM_FLOOR IM_TRUNC #define IM_FLOOR IM_TRUNC
#endif #endif
// Hint for branch prediction
#if (defined(__cplusplus) && (__cplusplus >= 202002L)) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 202002L))
#define IM_LIKELY [[likely]]
#define IM_UNLIKELY [[unlikely]]
#else
#define IM_LIKELY
#define IM_UNLIKELY
#endif
// Enforce cdecl calling convention for functions called by the standard library, in case compilation settings changed the default to e.g. __vectorcall // Enforce cdecl calling convention for functions called by the standard library, in case compilation settings changed the default to e.g. __vectorcall
#ifdef _MSC_VER #ifdef _MSC_VER
#define IMGUI_CDECL __cdecl #define IMGUI_CDECL __cdecl
@ -840,16 +843,18 @@ enum ImGuiDataTypePrivate_
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Extend ImGuiItemFlags // Extend ImGuiItemFlags
// - input: PushItemFlag() manipulates g.CurrentItemFlags, ItemAdd() calls may add extra flags. // - input: PushItemFlag() manipulates g.CurrentItemFlags, g.NextItemData.ItemFlags, ItemAdd() calls may add extra flags too.
// - output: stored in g.LastItemData.InFlags // - output: stored in g.LastItemData.ItemFlags
enum ImGuiItemFlagsPrivate_ enum ImGuiItemFlagsPrivate_
{ {
// Controlled by user // Controlled by user
ImGuiItemFlags_Disabled = 1 << 10, // false // Disable interactions (DOES NOT affect visuals, see BeginDisabled()/EndDisabled() for full disable feature, and github #211). ImGuiItemFlags_Disabled = 1 << 10, // false // Disable interactions (DOES NOT affect visuals. DO NOT mix direct use of this with BeginDisabled(). See BeginDisabled()/EndDisabled() for full disable feature, and github #211).
ImGuiItemFlags_ReadOnly = 1 << 11, // false // [ALPHA] Allow hovering interactions but underlying value is not changed. ImGuiItemFlags_ReadOnly = 1 << 11, // false // [ALPHA] Allow hovering interactions but underlying value is not changed.
ImGuiItemFlags_MixedValue = 1 << 12, // false // [BETA] Represent a mixed/indeterminate value, generally multi-selection where values differ. Currently only supported by Checkbox() (later should support all sorts of widgets) ImGuiItemFlags_MixedValue = 1 << 12, // false // [BETA] Represent a mixed/indeterminate value, generally multi-selection where values differ. Currently only supported by Checkbox() (later should support all sorts of widgets)
ImGuiItemFlags_NoWindowHoverableCheck = 1 << 13, // false // Disable hoverable check in ItemHoverable() ImGuiItemFlags_NoWindowHoverableCheck = 1 << 13, // false // Disable hoverable check in ItemHoverable()
ImGuiItemFlags_AllowOverlap = 1 << 14, // false // Allow being overlapped by another widget. Not-hovered to Hovered transition deferred by a frame. ImGuiItemFlags_AllowOverlap = 1 << 14, // false // Allow being overlapped by another widget. Not-hovered to Hovered transition deferred by a frame.
ImGuiItemFlags_NoNavDisableMouseHover = 1 << 15, // false // Nav keyboard/gamepad mode doesn't disable hover highlight (behave as if NavHighlightItemUnderNav==false).
ImGuiItemFlags_NoMarkEdited = 1 << 16, // false // Skip calling MarkItemEdited()
// Controlled by widget code // Controlled by widget code
ImGuiItemFlags_Inputable = 1 << 20, // false // [WIP] Auto-activate input mode when tab focused. Currently only used and supported by a few items before it becomes a generic feature. ImGuiItemFlags_Inputable = 1 << 20, // false // [WIP] Auto-activate input mode when tab focused. Currently only used and supported by a few items before it becomes a generic feature.
@ -902,9 +907,8 @@ enum ImGuiInputTextFlagsPrivate_
{ {
// [Internal] // [Internal]
ImGuiInputTextFlags_Multiline = 1 << 26, // For internal use by InputTextMultiline() ImGuiInputTextFlags_Multiline = 1 << 26, // For internal use by InputTextMultiline()
ImGuiInputTextFlags_NoMarkEdited = 1 << 27, // For internal use by functions using InputText() before reformatting data ImGuiInputTextFlags_MergedItem = 1 << 27, // For internal use by TempInputText(), will skip calling ItemAdd(). Require bounding-box to strictly match.
ImGuiInputTextFlags_MergedItem = 1 << 28, // For internal use by TempInputText(), will skip calling ItemAdd(). Require bounding-box to strictly match. ImGuiInputTextFlags_LocalizeDecimalPoint= 1 << 28, // For internal use by InputScalar() and TempInputScalar()
ImGuiInputTextFlags_LocalizeDecimalPoint= 1 << 29, // For internal use by InputScalar() and TempInputScalar()
}; };
// Extend ImGuiButtonFlags_ // Extend ImGuiButtonFlags_
@ -916,15 +920,15 @@ enum ImGuiButtonFlagsPrivate_
ImGuiButtonFlags_PressedOnRelease = 1 << 7, // return true on release (default requires click+release) ImGuiButtonFlags_PressedOnRelease = 1 << 7, // return true on release (default requires click+release)
ImGuiButtonFlags_PressedOnDoubleClick = 1 << 8, // return true on double-click (default requires click+release) ImGuiButtonFlags_PressedOnDoubleClick = 1 << 8, // return true on double-click (default requires click+release)
ImGuiButtonFlags_PressedOnDragDropHold = 1 << 9, // return true when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers) ImGuiButtonFlags_PressedOnDragDropHold = 1 << 9, // return true when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers)
ImGuiButtonFlags_Repeat = 1 << 10, // hold to repeat //ImGuiButtonFlags_Repeat = 1 << 10, // hold to repeat
ImGuiButtonFlags_FlattenChildren = 1 << 11, // allow interactions even if a child window is overlapping ImGuiButtonFlags_FlattenChildren = 1 << 11, // allow interactions even if a child window is overlapping
ImGuiButtonFlags_AllowOverlap = 1 << 12, // require previous frame HoveredId to either match id or be null before being usable. ImGuiButtonFlags_AllowOverlap = 1 << 12, // require previous frame HoveredId to either match id or be null before being usable.
ImGuiButtonFlags_DontClosePopups = 1 << 13, // disable automatically closing parent popup on press // [UNUSED] //ImGuiButtonFlags_DontClosePopups = 1 << 13, // disable automatically closing parent popup on press
//ImGuiButtonFlags_Disabled = 1 << 14, // disable interactions -> use BeginDisabled() or ImGuiItemFlags_Disabled //ImGuiButtonFlags_Disabled = 1 << 14, // disable interactions -> use BeginDisabled() or ImGuiItemFlags_Disabled
ImGuiButtonFlags_AlignTextBaseLine = 1 << 15, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine ImGuiButtonFlags_AlignTextBaseLine = 1 << 15, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine
ImGuiButtonFlags_NoKeyModifiers = 1 << 16, // disable mouse interaction if a key modifier is held ImGuiButtonFlags_NoKeyModsAllowed = 1 << 16, // disable mouse interaction if a key modifier is held
ImGuiButtonFlags_NoHoldingActiveId = 1 << 17, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only) ImGuiButtonFlags_NoHoldingActiveId = 1 << 17, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only)
ImGuiButtonFlags_NoNavFocus = 1 << 18, // don't override navigation focus when activated (FIXME: this is essentially used every time an item uses ImGuiItemFlags_NoNav, but because legacy specs don't requires LastItemData to be set ButtonBehavior(), we can't poll g.LastItemData.InFlags) ImGuiButtonFlags_NoNavFocus = 1 << 18, // don't override navigation focus when activated (FIXME: this is essentially used every time an item uses ImGuiItemFlags_NoNav, but because legacy specs don't requires LastItemData to be set ButtonBehavior(), we can't poll g.LastItemData.ItemFlags)
ImGuiButtonFlags_NoHoveredOnFocus = 1 << 19, // don't report as hovered when nav focus is on this item ImGuiButtonFlags_NoHoveredOnFocus = 1 << 19, // don't report as hovered when nav focus is on this item
ImGuiButtonFlags_NoSetKeyOwner = 1 << 20, // don't set key/input owner on the initial click (note: mouse buttons are keys! often, the key in question will be ImGuiKey_MouseLeft!) ImGuiButtonFlags_NoSetKeyOwner = 1 << 20, // don't set key/input owner on the initial click (note: mouse buttons are keys! often, the key in question will be ImGuiKey_MouseLeft!)
ImGuiButtonFlags_NoTestKeyOwner = 1 << 21, // don't test key/input owner when polling the key (note: mouse buttons are keys! often, the key in question will be ImGuiKey_MouseLeft!) ImGuiButtonFlags_NoTestKeyOwner = 1 << 21, // don't test key/input owner when polling the key (note: mouse buttons are keys! often, the key in question will be ImGuiKey_MouseLeft!)
@ -963,7 +967,7 @@ enum ImGuiSelectableFlagsPrivate_
enum ImGuiTreeNodeFlagsPrivate_ enum ImGuiTreeNodeFlagsPrivate_
{ {
ImGuiTreeNodeFlags_ClipLabelForTrailingButton = 1 << 28,// FIXME-WIP: Hard-coded for CollapsingHeader() ImGuiTreeNodeFlags_ClipLabelForTrailingButton = 1 << 28,// FIXME-WIP: Hard-coded for CollapsingHeader()
ImGuiTreeNodeFlags_UpsideDownArrow = 1 << 29,// FIXME-WIP: Turn Down arrow into an Up arrow, but reversed trees (#6517) ImGuiTreeNodeFlags_UpsideDownArrow = 1 << 29,// FIXME-WIP: Turn Down arrow into an Up arrow, for reversed trees (#6517)
ImGuiTreeNodeFlags_OpenOnMask_ = ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_OpenOnArrow, ImGuiTreeNodeFlags_OpenOnMask_ = ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_OpenOnArrow,
}; };
@ -1005,13 +1009,16 @@ enum ImGuiLayoutType_
ImGuiLayoutType_Vertical = 1 ImGuiLayoutType_Vertical = 1
}; };
enum ImGuiLogType // Flags for LogBegin() text capturing function
enum ImGuiLogFlags_
{ {
ImGuiLogType_None = 0, ImGuiLogFlags_None = 0,
ImGuiLogType_TTY,
ImGuiLogType_File, ImGuiLogFlags_OutputTTY = 1 << 0,
ImGuiLogType_Buffer, ImGuiLogFlags_OutputFile = 1 << 1,
ImGuiLogType_Clipboard, ImGuiLogFlags_OutputBuffer = 1 << 2,
ImGuiLogFlags_OutputClipboard = 1 << 3,
ImGuiLogFlags_OutputMask_ = ImGuiLogFlags_OutputTTY | ImGuiLogFlags_OutputFile | ImGuiLogFlags_OutputBuffer | ImGuiLogFlags_OutputClipboard,
}; };
// X/Y enums are fixed to 0/1 so they may be used to index ImVec2 // X/Y enums are fixed to 0/1 so they may be used to index ImVec2
@ -1122,11 +1129,11 @@ struct IMGUI_API ImGuiInputTextState
ImGuiContext* Ctx; // parent UI context (needs to be set explicitly by parent). ImGuiContext* Ctx; // parent UI context (needs to be set explicitly by parent).
ImStbTexteditState* Stb; // State for stb_textedit.h ImStbTexteditState* Stb; // State for stb_textedit.h
ImGuiID ID; // widget id owning the text state ImGuiID ID; // widget id owning the text state
int CurLenA; // UTF-8 length of the string in TextA (in bytes) int TextLen; // UTF-8 length of the string in TextA (in bytes)
ImVector<char> TextA; // main UTF8 buffer. ImVector<char> TextA; // main UTF8 buffer. TextA.Size is a buffer size! Should always be >= buf_size passed by user (and of course >= CurLenA + 1).
ImVector<char> InitialTextA; // value to revert to when pressing Escape = backup of end-user buffer at the time of focus (in UTF-8, unaltered) ImVector<char> TextToRevertTo; // value to revert to when pressing Escape = backup of end-user buffer at the time of focus (in UTF-8, unaltered)
ImVector<char> CallbackTextBackup; // temporary storage for callback to support automatic reconcile of undo-stack ImVector<char> CallbackTextBackup; // temporary storage for callback to support automatic reconcile of undo-stack
int BufCapacityA; // end-user buffer capacity int BufCapacity; // end-user buffer capacity (include zero terminator)
ImVec2 Scroll; // horizontal offset (managed manually) + vertical scrolling (pulled from child window's own Scroll.y) ImVec2 Scroll; // horizontal offset (managed manually) + vertical scrolling (pulled from child window's own Scroll.y)
float CursorAnim; // timer for cursor blink, reset on every user action so the cursor reappears immediately float CursorAnim; // timer for cursor blink, reset on every user action so the cursor reappears immediately
bool CursorFollow; // set when we want scrolling to follow the current cursor position (not always!) bool CursorFollow; // set when we want scrolling to follow the current cursor position (not always!)
@ -1139,8 +1146,8 @@ struct IMGUI_API ImGuiInputTextState
ImGuiInputTextState(); ImGuiInputTextState();
~ImGuiInputTextState(); ~ImGuiInputTextState();
void ClearText() { CurLenA = 0; TextA[0] = 0; CursorClamp(); } void ClearText() { TextLen = 0; TextA[0] = 0; CursorClamp(); }
void ClearFreeMemory() { TextA.clear(); InitialTextA.clear(); } void ClearFreeMemory() { TextA.clear(); TextToRevertTo.clear(); }
void OnKeyPressed(int key); // Cannot be inline because we call in code in stb_textedit.h implementation void OnKeyPressed(int key); // Cannot be inline because we call in code in stb_textedit.h implementation
void OnCharPressed(unsigned int c); void OnCharPressed(unsigned int c);
@ -1233,7 +1240,7 @@ enum ImGuiNextItemDataFlags_
struct ImGuiNextItemData struct ImGuiNextItemData
{ {
ImGuiNextItemDataFlags Flags; ImGuiNextItemDataFlags HasFlags; // Called HasFlags instead of Flags to avoid mistaking this
ImGuiItemFlags ItemFlags; // Currently only tested/used for ImGuiItemFlags_AllowOverlap and ImGuiItemFlags_HasSelectionUserData. ImGuiItemFlags ItemFlags; // Currently only tested/used for ImGuiItemFlags_AllowOverlap and ImGuiItemFlags_HasSelectionUserData.
// Non-flags members are NOT cleared by ItemAdd() meaning they are still valid during NavProcessItem() // Non-flags members are NOT cleared by ItemAdd() meaning they are still valid during NavProcessItem()
ImGuiID FocusScopeId; // Set by SetNextItemSelectionUserData() ImGuiID FocusScopeId; // Set by SetNextItemSelectionUserData()
@ -1247,14 +1254,14 @@ struct ImGuiNextItemData
ImGuiID StorageId; // Set by SetNextItemStorageID() ImGuiID StorageId; // Set by SetNextItemStorageID()
ImGuiNextItemData() { memset(this, 0, sizeof(*this)); SelectionUserData = -1; } ImGuiNextItemData() { memset(this, 0, sizeof(*this)); SelectionUserData = -1; }
inline void ClearFlags() { Flags = ImGuiNextItemDataFlags_None; ItemFlags = ImGuiItemFlags_None; } // Also cleared manually by ItemAdd()! inline void ClearFlags() { HasFlags = ImGuiNextItemDataFlags_None; ItemFlags = ImGuiItemFlags_None; } // Also cleared manually by ItemAdd()!
}; };
// Status storage for the last submitted item // Status storage for the last submitted item
struct ImGuiLastItemData struct ImGuiLastItemData
{ {
ImGuiID ID; ImGuiID ID;
ImGuiItemFlags InFlags; // See ImGuiItemFlags_ ImGuiItemFlags ItemFlags; // See ImGuiItemFlags_
ImGuiItemStatusFlags StatusFlags; // See ImGuiItemStatusFlags_ ImGuiItemStatusFlags StatusFlags; // See ImGuiItemStatusFlags_
ImRect Rect; // Full rectangle ImRect Rect; // Full rectangle
ImRect NavRect; // Navigation scoring rectangle (not displayed) ImRect NavRect; // Navigation scoring rectangle (not displayed)
@ -1274,13 +1281,16 @@ struct ImGuiTreeNodeStackData
{ {
ImGuiID ID; ImGuiID ID;
ImGuiTreeNodeFlags TreeFlags; ImGuiTreeNodeFlags TreeFlags;
ImGuiItemFlags InFlags; // Used for nav landing ImGuiItemFlags ItemFlags; // Used for nav landing
ImRect NavRect; // Used for nav landing ImRect NavRect; // Used for nav landing
}; };
struct IMGUI_API ImGuiStackSizes // sizeof() = 20
struct IMGUI_API ImGuiErrorRecoveryState
{ {
short SizeOfWindowStack;
short SizeOfIDStack; short SizeOfIDStack;
short SizeOfTreeStack;
short SizeOfColorStack; short SizeOfColorStack;
short SizeOfStyleVarStack; short SizeOfStyleVarStack;
short SizeOfFontStack; short SizeOfFontStack;
@ -1290,18 +1300,16 @@ struct IMGUI_API ImGuiStackSizes
short SizeOfBeginPopupStack; short SizeOfBeginPopupStack;
short SizeOfDisabledStack; short SizeOfDisabledStack;
ImGuiStackSizes() { memset(this, 0, sizeof(*this)); } ImGuiErrorRecoveryState() { memset(this, 0, sizeof(*this)); }
void SetToContextState(ImGuiContext* ctx);
void CompareWithContextState(ImGuiContext* ctx);
}; };
// Data saved for each window pushed into the stack // Data saved for each window pushed into the stack
struct ImGuiWindowStackData struct ImGuiWindowStackData
{ {
ImGuiWindow* Window; ImGuiWindow* Window;
ImGuiLastItemData ParentLastItemDataBackup; ImGuiLastItemData ParentLastItemDataBackup;
ImGuiStackSizes StackSizesOnBegin; // Store size of various stacks for asserting ImGuiErrorRecoveryState StackSizesInBegin; // Store size of various stacks for asserting
bool DisabledOverrideReenable; // Non-child window override disabled flag bool DisabledOverrideReenable; // Non-child window override disabled flag
}; };
struct ImGuiShrinkWidthItem struct ImGuiShrinkWidthItem
@ -1572,12 +1580,18 @@ enum ImGuiScrollFlags_
ImGuiScrollFlags_MaskY_ = ImGuiScrollFlags_KeepVisibleEdgeY | ImGuiScrollFlags_KeepVisibleCenterY | ImGuiScrollFlags_AlwaysCenterY, ImGuiScrollFlags_MaskY_ = ImGuiScrollFlags_KeepVisibleEdgeY | ImGuiScrollFlags_KeepVisibleCenterY | ImGuiScrollFlags_AlwaysCenterY,
}; };
enum ImGuiNavHighlightFlags_ enum ImGuiNavRenderCursorFlags_
{ {
ImGuiNavHighlightFlags_None = 0, ImGuiNavRenderCursorFlags_None = 0,
ImGuiNavHighlightFlags_Compact = 1 << 1, // Compact highlight, no padding ImGuiNavRenderCursorFlags_Compact = 1 << 1, // Compact highlight, no padding/distance from focused item
ImGuiNavHighlightFlags_AlwaysDraw = 1 << 2, // Draw rectangular highlight if (g.NavId == id) _even_ when using the mouse. ImGuiNavRenderCursorFlags_AlwaysDraw = 1 << 2, // Draw rectangular highlight if (g.NavId == id) even when g.NavCursorVisible == false, aka even when using the mouse.
ImGuiNavHighlightFlags_NoRounding = 1 << 3, ImGuiNavRenderCursorFlags_NoRounding = 1 << 3,
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
ImGuiNavHighlightFlags_None = ImGuiNavRenderCursorFlags_None, // Renamed in 1.91.4
ImGuiNavHighlightFlags_Compact = ImGuiNavRenderCursorFlags_Compact, // Renamed in 1.91.4
ImGuiNavHighlightFlags_AlwaysDraw = ImGuiNavRenderCursorFlags_AlwaysDraw, // Renamed in 1.91.4
ImGuiNavHighlightFlags_NoRounding = ImGuiNavRenderCursorFlags_NoRounding, // Renamed in 1.91.4
#endif
}; };
enum ImGuiNavMoveFlags_ enum ImGuiNavMoveFlags_
@ -1598,7 +1612,7 @@ enum ImGuiNavMoveFlags_
ImGuiNavMoveFlags_IsPageMove = 1 << 11, // Identify a PageDown/PageUp request. ImGuiNavMoveFlags_IsPageMove = 1 << 11, // Identify a PageDown/PageUp request.
ImGuiNavMoveFlags_Activate = 1 << 12, // Activate/select target item. ImGuiNavMoveFlags_Activate = 1 << 12, // Activate/select target item.
ImGuiNavMoveFlags_NoSelect = 1 << 13, // Don't trigger selection by not setting g.NavJustMovedTo ImGuiNavMoveFlags_NoSelect = 1 << 13, // Don't trigger selection by not setting g.NavJustMovedTo
ImGuiNavMoveFlags_NoSetNavHighlight = 1 << 14, // Do not alter the visible state of keyboard vs mouse nav highlight ImGuiNavMoveFlags_NoSetNavCursorVisible = 1 << 14, // Do not alter the nav cursor visible state
ImGuiNavMoveFlags_NoClearActiveId = 1 << 15, // (Experimental) Do not clear active id when applying move result ImGuiNavMoveFlags_NoClearActiveId = 1 << 15, // (Experimental) Do not clear active id when applying move result
}; };
@ -1616,17 +1630,17 @@ struct ImGuiNavItemData
ImGuiID ID; // Init,Move // Best candidate item ID ImGuiID ID; // Init,Move // Best candidate item ID
ImGuiID FocusScopeId; // Init,Move // Best candidate focus scope ID ImGuiID FocusScopeId; // Init,Move // Best candidate focus scope ID
ImRect RectRel; // Init,Move // Best candidate bounding box in window relative space ImRect RectRel; // Init,Move // Best candidate bounding box in window relative space
ImGuiItemFlags InFlags; // ????,Move // Best candidate item flags ImGuiItemFlags ItemFlags; // ????,Move // Best candidate item flags
float DistBox; // Move // Best candidate box distance to current NavId float DistBox; // Move // Best candidate box distance to current NavId
float DistCenter; // Move // Best candidate center distance to current NavId float DistCenter; // Move // Best candidate center distance to current NavId
float DistAxial; // Move // Best candidate axial distance to current NavId float DistAxial; // Move // Best candidate axial distance to current NavId
ImGuiSelectionUserData SelectionUserData;//I+Mov // Best candidate SetNextItemSelectionUserData() value. Valid if (InFlags & ImGuiItemFlags_HasSelectionUserData) ImGuiSelectionUserData SelectionUserData;//I+Mov // Best candidate SetNextItemSelectionUserData() value. Valid if (ItemFlags & ImGuiItemFlags_HasSelectionUserData)
ImGuiNavItemData() { Clear(); } ImGuiNavItemData() { Clear(); }
void Clear() { Window = NULL; ID = FocusScopeId = 0; InFlags = 0; SelectionUserData = -1; DistBox = DistCenter = DistAxial = FLT_MAX; } void Clear() { Window = NULL; ID = FocusScopeId = 0; ItemFlags = 0; SelectionUserData = -1; DistBox = DistCenter = DistAxial = FLT_MAX; }
}; };
// Storage for PushFocusScope() // Storage for PushFocusScope(), g.FocusScopeStack[], g.NavFocusRoute[]
struct ImGuiFocusScopeData struct ImGuiFocusScopeData
{ {
ImGuiID ID; ImGuiID ID;
@ -2075,6 +2089,21 @@ struct ImGuiLocEntry
const char* Text; const char* Text;
}; };
//-----------------------------------------------------------------------------
// [SECTION] Error handling, State recovery support
//-----------------------------------------------------------------------------
// Macros used by Recoverable Error handling
// - Only dispatch error if _EXPR: evaluate as assert (similar to an assert macro).
// - The message will always be a string literal, in order to increase likelihood of being display by an assert handler.
// - See 'Demo->Configuration->Error Handling' and ImGuiIO definitions for details on error handling.
// - Read https://github.com/ocornut/imgui/wiki/Error-Handling for details on error handling.
#ifndef IM_ASSERT_USER_ERROR
#define IM_ASSERT_USER_ERROR(_EXPR,_MSG) do { if (!(_EXPR) && ImGui::ErrorLog(_MSG)) { IM_ASSERT((_EXPR) && _MSG); } } while (0) // Recoverable User Error
#endif
// The error callback is currently not public, as it is expected that only advanced users will rely on it.
typedef void (*ImGuiErrorCallback)(ImGuiContext* ctx, void* user_data, const char* msg); // Function signature for g.ErrorCallback
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] Metrics, Debug Tools // [SECTION] Metrics, Debug Tools
@ -2084,18 +2113,19 @@ enum ImGuiDebugLogFlags_
{ {
// Event types // Event types
ImGuiDebugLogFlags_None = 0, ImGuiDebugLogFlags_None = 0,
ImGuiDebugLogFlags_EventActiveId = 1 << 0, ImGuiDebugLogFlags_EventError = 1 << 0, // Error submitted by IM_ASSERT_USER_ERROR()
ImGuiDebugLogFlags_EventFocus = 1 << 1, ImGuiDebugLogFlags_EventActiveId = 1 << 1,
ImGuiDebugLogFlags_EventPopup = 1 << 2, ImGuiDebugLogFlags_EventFocus = 1 << 2,
ImGuiDebugLogFlags_EventNav = 1 << 3, ImGuiDebugLogFlags_EventPopup = 1 << 3,
ImGuiDebugLogFlags_EventClipper = 1 << 4, ImGuiDebugLogFlags_EventNav = 1 << 4,
ImGuiDebugLogFlags_EventSelection = 1 << 5, ImGuiDebugLogFlags_EventClipper = 1 << 5,
ImGuiDebugLogFlags_EventIO = 1 << 6, ImGuiDebugLogFlags_EventSelection = 1 << 6,
ImGuiDebugLogFlags_EventInputRouting = 1 << 7, ImGuiDebugLogFlags_EventIO = 1 << 7,
ImGuiDebugLogFlags_EventDocking = 1 << 8, ImGuiDebugLogFlags_EventInputRouting = 1 << 8,
ImGuiDebugLogFlags_EventViewport = 1 << 9, ImGuiDebugLogFlags_EventDocking = 1 << 9,
ImGuiDebugLogFlags_EventViewport = 1 << 10,
ImGuiDebugLogFlags_EventMask_ = ImGuiDebugLogFlags_EventActiveId | ImGuiDebugLogFlags_EventFocus | ImGuiDebugLogFlags_EventPopup | ImGuiDebugLogFlags_EventNav | ImGuiDebugLogFlags_EventClipper | ImGuiDebugLogFlags_EventSelection | ImGuiDebugLogFlags_EventIO | ImGuiDebugLogFlags_EventInputRouting | ImGuiDebugLogFlags_EventDocking | ImGuiDebugLogFlags_EventViewport, ImGuiDebugLogFlags_EventMask_ = ImGuiDebugLogFlags_EventError | ImGuiDebugLogFlags_EventActiveId | ImGuiDebugLogFlags_EventFocus | ImGuiDebugLogFlags_EventPopup | ImGuiDebugLogFlags_EventNav | ImGuiDebugLogFlags_EventClipper | ImGuiDebugLogFlags_EventSelection | ImGuiDebugLogFlags_EventIO | ImGuiDebugLogFlags_EventInputRouting | ImGuiDebugLogFlags_EventDocking | ImGuiDebugLogFlags_EventViewport,
ImGuiDebugLogFlags_OutputToTTY = 1 << 20, // Also send output to TTY ImGuiDebugLogFlags_OutputToTTY = 1 << 20, // Also send output to TTY
ImGuiDebugLogFlags_OutputToTestEngine = 1 << 21, // Also send output to Test Engine ImGuiDebugLogFlags_OutputToTestEngine = 1 << 21, // Also send output to Test Engine
}; };
@ -2317,9 +2347,15 @@ struct ImGuiContext
int PlatformWindowsCreatedCount; // Unique sequential creation counter (mostly for testing/debugging) int PlatformWindowsCreatedCount; // Unique sequential creation counter (mostly for testing/debugging)
int ViewportFocusedStampCount; // Every time the front-most window changes, we stamp its viewport with an incrementing counter int ViewportFocusedStampCount; // Every time the front-most window changes, we stamp its viewport with an incrementing counter
// Gamepad/keyboard Navigation // Keyboard/Gamepad Navigation
ImGuiWindow* NavWindow; // Focused window for navigation. Could be called 'FocusedWindow' bool NavCursorVisible; // Nav focus cursor/rectangle is visible? We hide it after a mouse click. We show it after a nav move.
bool NavHighlightItemUnderNav; // Disable mouse hovering highlight. Highlight navigation focused item instead of mouse hovered item.
//bool NavDisableHighlight; // Old name for !g.NavCursorVisible before 1.91.4 (2024/10/18). OPPOSITE VALUE (g.NavDisableHighlight == !g.NavCursorVisible)
//bool NavDisableMouseHover; // Old name for g.NavHighlightItemUnderNav before 1.91.1 (2024/10/18) this was called When user starts using keyboard/gamepad, we hide mouse hovering highlight until mouse is touched again.
bool NavMousePosDirty; // When set we will update mouse position if io.ConfigNavMoveSetMousePos is set (not enabled by default)
bool NavIdIsAlive; // Nav widget has been seen this frame ~~ NavRectRel is valid
ImGuiID NavId; // Focused item for navigation ImGuiID NavId; // Focused item for navigation
ImGuiWindow* NavWindow; // Focused window for navigation. Could be called 'FocusedWindow'
ImGuiID NavFocusScopeId; // Focused focus scope (e.g. selection code often wants to "clear other items" when landing on an item of the same scope) ImGuiID NavFocusScopeId; // Focused focus scope (e.g. selection code often wants to "clear other items" when landing on an item of the same scope)
ImGuiNavLayer NavLayer; // Focused layer (main scrolling layer, or menu/title bar layer) ImGuiNavLayer NavLayer; // Focused layer (main scrolling layer, or menu/title bar layer)
ImGuiID NavActivateId; // ~~ (g.ActiveId == 0) && (IsKeyPressed(ImGuiKey_Space) || IsKeyDown(ImGuiKey_Enter) || IsKeyPressed(ImGuiKey_NavGamepadActivate)) ? NavId : 0, also set when calling ActivateItem() ImGuiID NavActivateId; // ~~ (g.ActiveId == 0) && (IsKeyPressed(ImGuiKey_Space) || IsKeyDown(ImGuiKey_Enter) || IsKeyPressed(ImGuiKey_NavGamepadActivate)) ? NavId : 0, also set when calling ActivateItem()
@ -2333,10 +2369,7 @@ struct ImGuiContext
ImGuiActivateFlags NavNextActivateFlags; ImGuiActivateFlags NavNextActivateFlags;
ImGuiInputSource NavInputSource; // Keyboard or Gamepad mode? THIS CAN ONLY BE ImGuiInputSource_Keyboard or ImGuiInputSource_Mouse ImGuiInputSource NavInputSource; // Keyboard or Gamepad mode? THIS CAN ONLY BE ImGuiInputSource_Keyboard or ImGuiInputSource_Mouse
ImGuiSelectionUserData NavLastValidSelectionUserData; // Last valid data passed to SetNextItemSelectionUser(), or -1. For current window. Not reset when focusing an item that doesn't have selection data. ImGuiSelectionUserData NavLastValidSelectionUserData; // Last valid data passed to SetNextItemSelectionUser(), or -1. For current window. Not reset when focusing an item that doesn't have selection data.
bool NavIdIsAlive; // Nav widget has been seen this frame ~~ NavRectRel is valid ImS8 NavCursorHideFrames;
bool NavMousePosDirty; // When set we will update mouse position if (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) if set (NB: this not enabled by default)
bool NavDisableHighlight; // When user starts using mouse, we hide gamepad/keyboard highlight (NB: but they are still available, which is why NavDisableHighlight isn't always != NavDisableMouseHover)
bool NavDisableMouseHover; // When user starts using gamepad/keyboard, we hide mouse hovering highlight until mouse is touched again.
// Navigation: Init & Move Requests // Navigation: Init & Move Requests
bool NavAnyRequest; // ~~ NavMoveRequest || NavInitRequest this is to perform early out in ItemAdd() bool NavAnyRequest; // ~~ NavMoveRequest || NavInitRequest this is to perform early out in ItemAdd()
@ -2368,7 +2401,7 @@ struct ImGuiContext
ImGuiID NavJustMovedToFocusScopeId; // Just navigated to this focus scope id (result of a successfully MoveRequest). ImGuiID NavJustMovedToFocusScopeId; // Just navigated to this focus scope id (result of a successfully MoveRequest).
ImGuiKeyChord NavJustMovedToKeyMods; ImGuiKeyChord NavJustMovedToKeyMods;
bool NavJustMovedToIsTabbing; // Copy of ImGuiNavMoveFlags_IsTabbing. Maybe we should store whole flags. bool NavJustMovedToIsTabbing; // Copy of ImGuiNavMoveFlags_IsTabbing. Maybe we should store whole flags.
bool NavJustMovedToHasSelectionData; // Copy of move result's InFlags & ImGuiItemFlags_HasSelectionUserData). Maybe we should just store ImGuiNavItemData. bool NavJustMovedToHasSelectionData; // Copy of move result's ItemFlags & ImGuiItemFlags_HasSelectionUserData). Maybe we should just store ImGuiNavItemData.
// Navigation: Windowing (CTRL+TAB for list, or Menu button + keys or directional pads to move/resize) // Navigation: Windowing (CTRL+TAB for list, or Menu button + keys or directional pads to move/resize)
ImGuiKeyChord ConfigNavWindowingKeyNext; // = ImGuiMod_Ctrl | ImGuiKey_Tab (or ImGuiMod_Super | ImGuiKey_Tab on OS X). For reconfiguration (see #4828) ImGuiKeyChord ConfigNavWindowingKeyNext; // = ImGuiMod_Ctrl | ImGuiKey_Tab (or ImGuiMod_Super | ImGuiKey_Tab on OS X). For reconfiguration (see #4828)
@ -2463,8 +2496,8 @@ struct ImGuiContext
ImGuiComboPreviewData ComboPreviewData; ImGuiComboPreviewData ComboPreviewData;
ImRect WindowResizeBorderExpectedRect; // Expected border rect, switch to relative edit if moving ImRect WindowResizeBorderExpectedRect; // Expected border rect, switch to relative edit if moving
bool WindowResizeRelativeMode; bool WindowResizeRelativeMode;
short ScrollbarSeekMode; // 0: relative, -1/+1: prev/next page. short ScrollbarSeekMode; // 0: scroll to clicked location, -1/+1: prev/next page.
float ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage? float ScrollbarClickDeltaToGrabCenter; // When scrolling to mouse location: distance between mouse and center of grab box, normalized in parent space.
float SliderGrabClickOffset; float SliderGrabClickOffset;
float SliderCurrentAccum; // Accumulated slider delta when using navigation controls. float SliderCurrentAccum; // Accumulated slider delta when using navigation controls.
bool SliderCurrentAccumDirty; // Has the accumulated slider delta changed since last time we tried to apply it? bool SliderCurrentAccumDirty; // Has the accumulated slider delta changed since last time we tried to apply it?
@ -2473,8 +2506,8 @@ struct ImGuiContext
float DragSpeedDefaultRatio; // If speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio float DragSpeedDefaultRatio; // If speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio
float DisabledAlphaBackup; // Backup for style.Alpha for BeginDisabled() float DisabledAlphaBackup; // Backup for style.Alpha for BeginDisabled()
short DisabledStackSize; short DisabledStackSize;
short LockMarkEdited;
short TooltipOverrideCount; short TooltipOverrideCount;
ImGuiWindow* TooltipPreviousWindow; // Window of last tooltip submitted during the frame
ImVector<char> ClipboardHandlerData; // If no custom clipboard handler is defined ImVector<char> ClipboardHandlerData; // If no custom clipboard handler is defined
ImVector<ImGuiID> MenusIdSubmittedThisFrame; // A list of menu IDs that were rendered at least once ImVector<ImGuiID> MenusIdSubmittedThisFrame; // A list of menu IDs that were rendered at least once
ImGuiTypingSelectState TypingSelectState; // State for GetTypingSelectRequest() ImGuiTypingSelectState TypingSelectState; // State for GetTypingSelectRequest()
@ -2504,7 +2537,8 @@ struct ImGuiContext
// Capture/Logging // Capture/Logging
bool LogEnabled; // Currently capturing bool LogEnabled; // Currently capturing
ImGuiLogType LogType; // Capture target ImGuiLogFlags LogFlags; // Capture flags/type
ImGuiWindow* LogWindow;
ImFileHandle LogFile; // If != NULL log to stdout/ file ImFileHandle LogFile; // If != NULL log to stdout/ file
ImGuiTextBuffer LogBuffer; // Accumulation buffer when log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators. ImGuiTextBuffer LogBuffer; // Accumulation buffer when log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators.
const char* LogNextPrefix; const char* LogNextPrefix;
@ -2515,11 +2549,22 @@ struct ImGuiContext
int LogDepthToExpand; int LogDepthToExpand;
int LogDepthToExpandDefault; // Default/stored value for LogDepthMaxExpand if not specified in the LogXXX function call. int LogDepthToExpandDefault; // Default/stored value for LogDepthMaxExpand if not specified in the LogXXX function call.
// Error Handling
ImGuiErrorCallback ErrorCallback; // = NULL. May be exposed in public API eventually.
void* ErrorCallbackUserData; // = NULL
ImVec2 ErrorTooltipLockedPos;
bool ErrorFirst;
int ErrorCountCurrentFrame; // [Internal] Number of errors submitted this frame.
ImGuiErrorRecoveryState StackSizesInNewFrame; // [Internal]
ImGuiErrorRecoveryState*StackSizesInBeginForCurrentWindow; // [Internal]
// Debug Tools // Debug Tools
// (some of the highly frequently used data are interleaved in other structures above: DebugBreakXXX fields, DebugHookIdInfo, DebugLocateId etc.) // (some of the highly frequently used data are interleaved in other structures above: DebugBreakXXX fields, DebugHookIdInfo, DebugLocateId etc.)
int DebugDrawIdConflictsCount; // Locked count (preserved when holding CTRL)
ImGuiDebugLogFlags DebugLogFlags; ImGuiDebugLogFlags DebugLogFlags;
ImGuiTextBuffer DebugLogBuf; ImGuiTextBuffer DebugLogBuf;
ImGuiTextIndex DebugLogIndex; ImGuiTextIndex DebugLogIndex;
int DebugLogSkippedErrors;
ImGuiDebugLogFlags DebugLogAutoDisableFlags; ImGuiDebugLogFlags DebugLogAutoDisableFlags;
ImU8 DebugLogAutoDisableFrames; ImU8 DebugLogAutoDisableFrames;
ImU8 DebugLocateFrames; // For DebugLocateItemOnHover(). This is used together with DebugLocateId which is in a hot/cached spot above. ImU8 DebugLocateFrames; // For DebugLocateItemOnHover(). This is used together with DebugLocateId which is in a hot/cached spot above.
@ -2547,221 +2592,7 @@ struct ImGuiContext
ImVector<char> TempBuffer; // Temporary text buffer ImVector<char> TempBuffer; // Temporary text buffer
char TempKeychordName[64]; char TempKeychordName[64];
ImGuiContext(ImFontAtlas* shared_font_atlas) ImGuiContext(ImFontAtlas* shared_font_atlas);
{
IO.Ctx = this;
InputTextState.Ctx = this;
Initialized = false;
ConfigFlagsCurrFrame = ConfigFlagsLastFrame = ImGuiConfigFlags_None;
FontAtlasOwnedByContext = shared_font_atlas ? false : true;
Font = NULL;
FontSize = FontBaseSize = FontScale = CurrentDpiScale = 0.0f;
IO.Fonts = shared_font_atlas ? shared_font_atlas : IM_NEW(ImFontAtlas)();
Time = 0.0f;
FrameCount = 0;
FrameCountEnded = FrameCountPlatformEnded = FrameCountRendered = -1;
WithinFrameScope = WithinFrameScopeWithImplicitWindow = WithinEndChild = false;
GcCompactAll = false;
TestEngineHookItems = false;
TestEngine = NULL;
memset(ContextName, 0, sizeof(ContextName));
InputEventsNextMouseSource = ImGuiMouseSource_Mouse;
InputEventsNextEventId = 1;
WindowsActiveCount = 0;
CurrentWindow = NULL;
HoveredWindow = NULL;
HoveredWindowUnderMovingWindow = NULL;
HoveredWindowBeforeClear = NULL;
MovingWindow = NULL;
WheelingWindow = NULL;
WheelingWindowStartFrame = WheelingWindowScrolledFrame = -1;
WheelingWindowReleaseTimer = 0.0f;
DebugDrawIdConflicts = 0;
DebugHookIdInfo = 0;
HoveredId = HoveredIdPreviousFrame = 0;
HoveredIdPreviousFrameItemCount = 0;
HoveredIdAllowOverlap = false;
HoveredIdIsDisabled = false;
HoveredIdTimer = HoveredIdNotActiveTimer = 0.0f;
ItemUnclipByLog = false;
ActiveId = 0;
ActiveIdIsAlive = 0;
ActiveIdTimer = 0.0f;
ActiveIdIsJustActivated = false;
ActiveIdAllowOverlap = false;
ActiveIdNoClearOnFocusLoss = false;
ActiveIdHasBeenPressedBefore = false;
ActiveIdHasBeenEditedBefore = false;
ActiveIdHasBeenEditedThisFrame = false;
ActiveIdFromShortcut = false;
ActiveIdClickOffset = ImVec2(-1, -1);
ActiveIdWindow = NULL;
ActiveIdSource = ImGuiInputSource_None;
ActiveIdMouseButton = -1;
ActiveIdPreviousFrame = 0;
ActiveIdPreviousFrameIsAlive = false;
ActiveIdPreviousFrameHasBeenEditedBefore = false;
ActiveIdPreviousFrameWindow = NULL;
LastActiveId = 0;
LastActiveIdTimer = 0.0f;
LastKeyboardKeyPressTime = LastKeyModsChangeTime = LastKeyModsChangeFromNoneTime = -1.0;
ActiveIdUsingNavDirMask = 0x00;
ActiveIdUsingAllKeyboardKeys = false;
CurrentFocusScopeId = 0;
CurrentItemFlags = ImGuiItemFlags_None;
DebugShowGroupRects = false;
CurrentViewport = NULL;
MouseViewport = MouseLastHoveredViewport = NULL;
PlatformLastFocusedViewportId = 0;
ViewportCreatedCount = PlatformWindowsCreatedCount = 0;
ViewportFocusedStampCount = 0;
NavWindow = NULL;
NavId = NavFocusScopeId = NavActivateId = NavActivateDownId = NavActivatePressedId = 0;
NavLayer = ImGuiNavLayer_Main;
NavNextActivateId = 0;
NavActivateFlags = NavNextActivateFlags = ImGuiActivateFlags_None;
NavHighlightActivatedId = 0;
NavHighlightActivatedTimer = 0.0f;
NavInputSource = ImGuiInputSource_Keyboard;
NavLastValidSelectionUserData = ImGuiSelectionUserData_Invalid;
NavIdIsAlive = false;
NavMousePosDirty = false;
NavDisableHighlight = true;
NavDisableMouseHover = false;
NavAnyRequest = false;
NavInitRequest = false;
NavInitRequestFromMove = false;
NavMoveSubmitted = false;
NavMoveScoringItems = false;
NavMoveForwardToNextFrame = false;
NavMoveFlags = ImGuiNavMoveFlags_None;
NavMoveScrollFlags = ImGuiScrollFlags_None;
NavMoveKeyMods = ImGuiMod_None;
NavMoveDir = NavMoveDirForDebug = NavMoveClipDir = ImGuiDir_None;
NavScoringDebugCount = 0;
NavTabbingDir = 0;
NavTabbingCounter = 0;
NavJustMovedFromFocusScopeId = NavJustMovedToId = NavJustMovedToFocusScopeId = 0;
NavJustMovedToKeyMods = ImGuiMod_None;
NavJustMovedToIsTabbing = false;
NavJustMovedToHasSelectionData = false;
// All platforms use Ctrl+Tab but Ctrl<>Super are swapped on Mac...
// FIXME: Because this value is stored, it annoyingly interfere with toggling io.ConfigMacOSXBehaviors updating this..
ConfigNavWindowingKeyNext = IO.ConfigMacOSXBehaviors ? (ImGuiMod_Super | ImGuiKey_Tab) : (ImGuiMod_Ctrl | ImGuiKey_Tab);
ConfigNavWindowingKeyPrev = IO.ConfigMacOSXBehaviors ? (ImGuiMod_Super | ImGuiMod_Shift | ImGuiKey_Tab) : (ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Tab);
NavWindowingTarget = NavWindowingTargetAnim = NavWindowingListWindow = NULL;
NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f;
NavWindowingToggleLayer = false;
NavWindowingToggleKey = ImGuiKey_None;
DimBgRatio = 0.0f;
DragDropActive = DragDropWithinSource = DragDropWithinTarget = false;
DragDropSourceFlags = ImGuiDragDropFlags_None;
DragDropSourceFrameCount = -1;
DragDropMouseButton = -1;
DragDropTargetId = 0;
DragDropAcceptFlags = ImGuiDragDropFlags_None;
DragDropAcceptIdCurrRectSurface = 0.0f;
DragDropAcceptIdPrev = DragDropAcceptIdCurr = 0;
DragDropAcceptFrameCount = -1;
DragDropHoldJustPressedId = 0;
memset(DragDropPayloadBufLocal, 0, sizeof(DragDropPayloadBufLocal));
ClipperTempDataStacked = 0;
CurrentTable = NULL;
TablesTempDataStacked = 0;
CurrentTabBar = NULL;
CurrentMultiSelect = NULL;
MultiSelectTempDataStacked = 0;
HoverItemDelayId = HoverItemDelayIdPreviousFrame = HoverItemUnlockedStationaryId = HoverWindowUnlockedStationaryId = 0;
HoverItemDelayTimer = HoverItemDelayClearTimer = 0.0f;
MouseCursor = ImGuiMouseCursor_Arrow;
MouseStationaryTimer = 0.0f;
TempInputId = 0;
memset(&DataTypeZeroValue, 0, sizeof(DataTypeZeroValue));
BeginMenuDepth = BeginComboDepth = 0;
ColorEditOptions = ImGuiColorEditFlags_DefaultOptions_;
ColorEditCurrentID = ColorEditSavedID = 0;
ColorEditSavedHue = ColorEditSavedSat = 0.0f;
ColorEditSavedColor = 0;
WindowResizeRelativeMode = false;
ScrollbarSeekMode = 0;
ScrollbarClickDeltaToGrabCenter = 0.0f;
SliderGrabClickOffset = 0.0f;
SliderCurrentAccum = 0.0f;
SliderCurrentAccumDirty = false;
DragCurrentAccumDirty = false;
DragCurrentAccum = 0.0f;
DragSpeedDefaultRatio = 1.0f / 100.0f;
DisabledAlphaBackup = 0.0f;
DisabledStackSize = 0;
LockMarkEdited = 0;
TooltipOverrideCount = 0;
PlatformImeData.InputPos = ImVec2(0.0f, 0.0f);
PlatformImeDataPrev.InputPos = ImVec2(-1.0f, -1.0f); // Different to ensure initial submission
PlatformImeViewport = 0;
DockNodeWindowMenuHandler = NULL;
SettingsLoaded = false;
SettingsDirtyTimer = 0.0f;
HookIdNext = 0;
memset(LocalizationTable, 0, sizeof(LocalizationTable));
LogEnabled = false;
LogType = ImGuiLogType_None;
LogNextPrefix = LogNextSuffix = NULL;
LogFile = NULL;
LogLinePosY = FLT_MAX;
LogLineFirstItem = false;
LogDepthRef = 0;
LogDepthToExpand = LogDepthToExpandDefault = 2;
DebugLogFlags = ImGuiDebugLogFlags_OutputToTTY;
DebugLocateId = 0;
DebugLogAutoDisableFlags = ImGuiDebugLogFlags_None;
DebugLogAutoDisableFrames = 0;
DebugLocateFrames = 0;
DebugBeginReturnValueCullDepth = -1;
DebugItemPickerActive = false;
DebugItemPickerMouseButton = ImGuiMouseButton_Left;
DebugItemPickerBreakId = 0;
DebugFlashStyleColorTime = 0.0f;
DebugFlashStyleColorIdx = ImGuiCol_COUNT;
DebugHoveredDockNode = NULL;
// Same as DebugBreakClearData(). Those fields are scattered in their respective subsystem to stay in hot-data locations
DebugBreakInWindow = 0;
DebugBreakInTable = 0;
DebugBreakInLocateId = false;
DebugBreakKeyChord = ImGuiKey_Pause;
DebugBreakInShortcutRouting = ImGuiKey_None;
memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame));
FramerateSecPerFrameIdx = FramerateSecPerFrameCount = 0;
FramerateSecPerFrameAccum = 0.0f;
WantCaptureMouseNextFrame = WantCaptureKeyboardNextFrame = WantTextInputNextFrame = -1;
memset(TempKeychordName, 0, sizeof(TempKeychordName));
}
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -3009,9 +2840,10 @@ struct ImGuiTabItem
ImGuiTabItem() { memset(this, 0, sizeof(*this)); LastFrameVisible = LastFrameSelected = -1; RequestedWidth = -1.0f; NameOffset = -1; BeginOrder = IndexDuringLayout = -1; } ImGuiTabItem() { memset(this, 0, sizeof(*this)); LastFrameVisible = LastFrameSelected = -1; RequestedWidth = -1.0f; NameOffset = -1; BeginOrder = IndexDuringLayout = -1; }
}; };
// Storage for a tab bar (sizeof() 152 bytes) // Storage for a tab bar (sizeof() 160 bytes)
struct IMGUI_API ImGuiTabBar struct IMGUI_API ImGuiTabBar
{ {
ImGuiWindow* Window;
ImVector<ImGuiTabItem> Tabs; ImVector<ImGuiTabItem> Tabs;
ImGuiTabBarFlags Flags; ImGuiTabBarFlags Flags;
ImGuiID ID; // Zero for tab-bars used by docking ImGuiID ID; // Zero for tab-bars used by docking
@ -3352,6 +3184,7 @@ namespace ImGui
// If this ever crashes because g.CurrentWindow is NULL, it means that either: // If this ever crashes because g.CurrentWindow is NULL, it means that either:
// - ImGui::NewFrame() has never been called, which is illegal. // - ImGui::NewFrame() has never been called, which is illegal.
// - You are calling ImGui functions after ImGui::EndFrame()/ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal. // - You are calling ImGui functions after ImGui::EndFrame()/ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal.
IMGUI_API ImGuiIO& GetIOEx(ImGuiContext* ctx);
inline ImGuiWindow* GetCurrentWindowRead() { ImGuiContext& g = *GImGui; return g.CurrentWindow; } inline ImGuiWindow* GetCurrentWindowRead() { ImGuiContext& g = *GImGui; return g.CurrentWindow; }
inline ImGuiWindow* GetCurrentWindow() { ImGuiContext& g = *GImGui; g.CurrentWindow->WriteAccessed = true; return g.CurrentWindow; } inline ImGuiWindow* GetCurrentWindow() { ImGuiContext& g = *GImGui; g.CurrentWindow->WriteAccessed = true; return g.CurrentWindow; }
IMGUI_API ImGuiWindow* FindWindowByID(ImGuiID id); IMGUI_API ImGuiWindow* FindWindowByID(ImGuiID id);
@ -3454,7 +3287,7 @@ namespace ImGui
// Basic Accessors // Basic Accessors
inline ImGuiItemStatusFlags GetItemStatusFlags() { ImGuiContext& g = *GImGui; return g.LastItemData.StatusFlags; } inline ImGuiItemStatusFlags GetItemStatusFlags() { ImGuiContext& g = *GImGui; return g.LastItemData.StatusFlags; }
inline ImGuiItemFlags GetItemFlags() { ImGuiContext& g = *GImGui; return g.LastItemData.InFlags; } inline ImGuiItemFlags GetItemFlags() { ImGuiContext& g = *GImGui; return g.LastItemData.ItemFlags; }
inline ImGuiID GetActiveID() { ImGuiContext& g = *GImGui; return g.ActiveId; } inline ImGuiID GetActiveID() { ImGuiContext& g = *GImGui; return g.ActiveId; }
inline ImGuiID GetFocusID() { ImGuiContext& g = *GImGui; return g.NavId; } inline ImGuiID GetFocusID() { ImGuiContext& g = *GImGui; return g.NavId; }
IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window); IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window);
@ -3487,7 +3320,7 @@ namespace ImGui
IMGUI_API void EndDisabledOverrideReenable(); IMGUI_API void EndDisabledOverrideReenable();
// Logging/Capture // Logging/Capture
IMGUI_API void LogBegin(ImGuiLogType type, int auto_open_depth); // -> BeginCapture() when we design v2 api, for now stay under the radar by using the old name. IMGUI_API void LogBegin(ImGuiLogFlags flags, int auto_open_depth); // -> BeginCapture() when we design v2 api, for now stay under the radar by using the old name.
IMGUI_API void LogToBuffer(int auto_open_depth = -1); // Start logging/capturing to internal buffer IMGUI_API void LogToBuffer(int auto_open_depth = -1); // Start logging/capturing to internal buffer
IMGUI_API void LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end = NULL); IMGUI_API void LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end = NULL);
IMGUI_API void LogSetNextTextDecoration(const char* prefix, const char* suffix); IMGUI_API void LogSetNextTextDecoration(const char* prefix, const char* suffix);
@ -3523,7 +3356,7 @@ namespace ImGui
IMGUI_API bool BeginComboPreview(); IMGUI_API bool BeginComboPreview();
IMGUI_API void EndComboPreview(); IMGUI_API void EndComboPreview();
// Gamepad/Keyboard Navigation // Keyboard/Gamepad Navigation
IMGUI_API void NavInitWindow(ImGuiWindow* window, bool force_reinit); IMGUI_API void NavInitWindow(ImGuiWindow* window, bool force_reinit);
IMGUI_API void NavInitRequestApplyResult(); IMGUI_API void NavInitRequestApplyResult();
IMGUI_API bool NavMoveRequestButNoResultYet(); IMGUI_API bool NavMoveRequestButNoResultYet();
@ -3536,7 +3369,7 @@ namespace ImGui
IMGUI_API void NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags); IMGUI_API void NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags);
IMGUI_API void NavHighlightActivated(ImGuiID id); IMGUI_API void NavHighlightActivated(ImGuiID id);
IMGUI_API void NavClearPreferredPosForAxis(ImGuiAxis axis); IMGUI_API void NavClearPreferredPosForAxis(ImGuiAxis axis);
IMGUI_API void NavRestoreHighlightAfterMove(); IMGUI_API void SetNavCursorVisibleAfterMove();
IMGUI_API void NavUpdateCurrentWindowIsScrollPushableX(); IMGUI_API void NavUpdateCurrentWindowIsScrollPushableX();
IMGUI_API void SetNavWindow(ImGuiWindow* window); IMGUI_API void SetNavWindow(ImGuiWindow* window);
IMGUI_API void SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel); IMGUI_API void SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel);
@ -3708,6 +3541,8 @@ namespace ImGui
IMGUI_API void RenderDragDropTargetRect(const ImRect& bb, const ImRect& item_clip_rect); IMGUI_API void RenderDragDropTargetRect(const ImRect& bb, const ImRect& item_clip_rect);
// Typing-Select API // Typing-Select API
// (provide Windows Explorer style "select items by typing partial name" + "cycle through items by typing same letter" feature)
// (this is currently not documented nor used by main library, but should work. See "widgets_typingselect" in imgui_test_suite for usage code. Please let us know if you use this!)
IMGUI_API ImGuiTypingSelectRequest* GetTypingSelectRequest(ImGuiTypingSelectFlags flags = ImGuiTypingSelectFlags_None); IMGUI_API ImGuiTypingSelectRequest* GetTypingSelectRequest(ImGuiTypingSelectFlags flags = ImGuiTypingSelectFlags_None);
IMGUI_API int TypingSelectFindMatch(ImGuiTypingSelectRequest* req, int items_count, const char* (*get_item_name_func)(void*, int), void* user_data, int nav_item_idx); IMGUI_API int TypingSelectFindMatch(ImGuiTypingSelectRequest* req, int items_count, const char* (*get_item_name_func)(void*, int), void* user_data, int nav_item_idx);
IMGUI_API int TypingSelectFindNextSingleCharMatch(ImGuiTypingSelectRequest* req, int items_count, const char* (*get_item_name_func)(void*, int), void* user_data, int nav_item_idx); IMGUI_API int TypingSelectFindNextSingleCharMatch(ImGuiTypingSelectRequest* req, int items_count, const char* (*get_item_name_func)(void*, int), void* user_data, int nav_item_idx);
@ -3806,6 +3641,7 @@ namespace ImGui
IMGUI_API void TabBarRemoveTab(ImGuiTabBar* tab_bar, ImGuiID tab_id); IMGUI_API void TabBarRemoveTab(ImGuiTabBar* tab_bar, ImGuiID tab_id);
IMGUI_API void TabBarCloseTab(ImGuiTabBar* tab_bar, ImGuiTabItem* tab); IMGUI_API void TabBarCloseTab(ImGuiTabBar* tab_bar, ImGuiTabItem* tab);
IMGUI_API void TabBarQueueFocus(ImGuiTabBar* tab_bar, ImGuiTabItem* tab); IMGUI_API void TabBarQueueFocus(ImGuiTabBar* tab_bar, ImGuiTabItem* tab);
IMGUI_API void TabBarQueueFocus(ImGuiTabBar* tab_bar, const char* tab_name);
IMGUI_API void TabBarQueueReorder(ImGuiTabBar* tab_bar, ImGuiTabItem* tab, int offset); IMGUI_API void TabBarQueueReorder(ImGuiTabBar* tab_bar, ImGuiTabItem* tab, int offset);
IMGUI_API void TabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar, ImGuiTabItem* tab, ImVec2 mouse_pos); IMGUI_API void TabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar, ImGuiTabItem* tab, ImVec2 mouse_pos);
IMGUI_API bool TabBarProcessReorder(ImGuiTabBar* tab_bar); IMGUI_API bool TabBarProcessReorder(ImGuiTabBar* tab_bar);
@ -3826,7 +3662,10 @@ namespace ImGui
IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool borders = true, float rounding = 0.0f); IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool borders = true, float rounding = 0.0f);
IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f); IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f);
IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, ImDrawFlags flags = 0); IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, ImDrawFlags flags = 0);
IMGUI_API void RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags = ImGuiNavHighlightFlags_None); // Navigation highlight IMGUI_API void RenderNavCursor(const ImRect& bb, ImGuiID id, ImGuiNavRenderCursorFlags flags = ImGuiNavRenderCursorFlags_None); // Navigation highlight
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
inline void RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavRenderCursorFlags flags = ImGuiNavRenderCursorFlags_None) { RenderNavCursor(bb, id, flags); } // Renamed in 1.91.4
#endif
IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text. IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text.
IMGUI_API void RenderMouseCursor(ImVec2 pos, float scale, ImGuiMouseCursor mouse_cursor, ImU32 col_fill, ImU32 col_border, ImU32 col_shadow); IMGUI_API void RenderMouseCursor(ImVec2 pos, float scale, ImGuiMouseCursor mouse_cursor, ImU32 col_fill, ImU32 col_border, ImU32 col_shadow);
@ -3890,6 +3729,7 @@ namespace ImGui
IMGUI_API bool DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format, void* p_data_when_empty = NULL); IMGUI_API bool DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format, void* p_data_when_empty = NULL);
IMGUI_API int DataTypeCompare(ImGuiDataType data_type, const void* arg_1, const void* arg_2); IMGUI_API int DataTypeCompare(ImGuiDataType data_type, const void* arg_1, const void* arg_2);
IMGUI_API bool DataTypeClamp(ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max); IMGUI_API bool DataTypeClamp(ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max);
IMGUI_API bool DataTypeIsZero(ImGuiDataType data_type, const void* p_data);
// InputText // InputText
IMGUI_API bool InputTextEx(const char* label, const char* hint, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); IMGUI_API bool InputTextEx(const char* label, const char* hint, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
@ -3918,11 +3758,18 @@ namespace ImGui
IMGUI_API void GcCompactTransientWindowBuffers(ImGuiWindow* window); IMGUI_API void GcCompactTransientWindowBuffers(ImGuiWindow* window);
IMGUI_API void GcAwakeTransientWindowBuffers(ImGuiWindow* window); IMGUI_API void GcAwakeTransientWindowBuffers(ImGuiWindow* window);
// Error handling, State Recovery
IMGUI_API bool ErrorLog(const char* msg);
IMGUI_API void ErrorRecoveryStoreState(ImGuiErrorRecoveryState* state_out);
IMGUI_API void ErrorRecoveryTryToRecoverState(const ImGuiErrorRecoveryState* state_in);
IMGUI_API void ErrorRecoveryTryToRecoverWindowState(const ImGuiErrorRecoveryState* state_in);
IMGUI_API void ErrorCheckUsingSetCursorPosToExtendParentBoundaries();
IMGUI_API void ErrorCheckEndFrameFinalizeErrorTooltip();
IMGUI_API bool BeginErrorTooltip();
IMGUI_API void EndErrorTooltip();
// Debug Tools // Debug Tools
IMGUI_API void DebugAllocHook(ImGuiDebugAllocInfo* info, int frame_count, void* ptr, size_t size); // size >= 0 : alloc, size = -1 : free IMGUI_API void DebugAllocHook(ImGuiDebugAllocInfo* info, int frame_count, void* ptr, size_t size); // size >= 0 : alloc, size = -1 : free
IMGUI_API void ErrorCheckEndFrameRecover(ImGuiErrorLogCallback log_callback, void* user_data = NULL);
IMGUI_API void ErrorCheckEndWindowRecover(ImGuiErrorLogCallback log_callback, void* user_data = NULL);
IMGUI_API void ErrorCheckUsingSetCursorPosToExtendParentBoundaries();
IMGUI_API void DebugDrawCursorPos(ImU32 col = IM_COL32(255, 0, 0, 255)); IMGUI_API void DebugDrawCursorPos(ImU32 col = IM_COL32(255, 0, 0, 255));
IMGUI_API void DebugDrawLineExtents(ImU32 col = IM_COL32(255, 0, 0, 255)); IMGUI_API void DebugDrawLineExtents(ImU32 col = IM_COL32(255, 0, 0, 255));
IMGUI_API void DebugDrawItemRect(ImU32 col = IM_COL32(255, 0, 0, 255)); IMGUI_API void DebugDrawItemRect(ImU32 col = IM_COL32(255, 0, 0, 255));
@ -3959,9 +3806,8 @@ namespace ImGui
// Obsolete functions // Obsolete functions
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
inline void SetItemUsingMouseWheel() { SetItemKeyOwner(ImGuiKey_MouseWheelY); } // Changed in 1.89 //inline void SetItemUsingMouseWheel() { SetItemKeyOwner(ImGuiKey_MouseWheelY); } // Changed in 1.89
inline bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0) { return TreeNodeUpdateNextOpen(id, flags); } // Renamed in 1.89 //inline bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0) { return TreeNodeUpdateNextOpen(id, flags); } // Renamed in 1.89
//inline bool IsKeyPressedMap(ImGuiKey key, bool repeat = true) { IM_ASSERT(IsNamedKey(key)); return IsKeyPressed(key, repeat); } // Removed in 1.87: Mapping from named key is always identity! //inline bool IsKeyPressedMap(ImGuiKey key, bool repeat = true) { IM_ASSERT(IsNamedKey(key)); return IsKeyPressed(key, repeat); } // Removed in 1.87: Mapping from named key is always identity!
// Refactored focus/nav/tabbing system in 1.82 and 1.84. If you have old/custom copy-and-pasted widgets which used FocusableItemRegister(): // Refactored focus/nav/tabbing system in 1.82 and 1.84. If you have old/custom copy-and-pasted widgets which used FocusableItemRegister():
@ -4012,7 +3858,7 @@ extern const char* ImGuiTestEngine_FindItemDebugLabel(ImGuiContext* ctx, ImGuiI
// In IMGUI_VERSION_NUM >= 18934: changed IMGUI_TEST_ENGINE_ITEM_ADD(bb,id) to IMGUI_TEST_ENGINE_ITEM_ADD(id,bb,item_data); // In IMGUI_VERSION_NUM >= 18934: changed IMGUI_TEST_ENGINE_ITEM_ADD(bb,id) to IMGUI_TEST_ENGINE_ITEM_ADD(id,bb,item_data);
#define IMGUI_TEST_ENGINE_ITEM_ADD(_ID,_BB,_ITEM_DATA) if (g.TestEngineHookItems) ImGuiTestEngineHook_ItemAdd(&g, _ID, _BB, _ITEM_DATA) // Register item bounding box #define IMGUI_TEST_ENGINE_ITEM_ADD(_ID,_BB,_ITEM_DATA) if (g.TestEngineHookItems) ImGuiTestEngineHook_ItemAdd(&g, _ID, _BB, _ITEM_DATA) // Register item bounding box
#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID,_LABEL,_FLAGS) if (g.TestEngineHookItems) ImGuiTestEngineHook_ItemInfo(&g, _ID, _LABEL, _FLAGS) // Register item label and status flags (optional) #define IMGUI_TEST_ENGINE_ITEM_INFO(_ID,_LABEL,_FLAGS) if (g.TestEngineHookItems) ImGuiTestEngineHook_ItemInfo(&g, _ID, _LABEL, _FLAGS) // Register item label and status flags (optional)
#define IMGUI_TEST_ENGINE_LOG(_FMT,...) if (g.TestEngineHookItems) ImGuiTestEngineHook_Log(&g, _FMT, __VA_ARGS__) // Custom log entry from user land into test log #define IMGUI_TEST_ENGINE_LOG(_FMT,...) ImGuiTestEngineHook_Log(&g, _FMT, __VA_ARGS__) // Custom log entry from user land into test log
#else #else
#define IMGUI_TEST_ENGINE_ITEM_ADD(_BB,_ID) ((void)0) #define IMGUI_TEST_ENGINE_ITEM_ADD(_BB,_ID) ((void)0)
#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID,_LABEL,_FLAGS) ((void)g) #define IMGUI_TEST_ENGINE_ITEM_INFO(_ID,_LABEL,_FLAGS) ((void)g)

View File

@ -1,4 +1,4 @@
// dear imgui, v1.91.2 WIP // dear imgui, v1.91.5
// (tables and columns code) // (tables and columns code)
/* /*
@ -229,6 +229,7 @@ Index of this file:
#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"// warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated #pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"// warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
#pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type
#elif defined(__GNUC__) #elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked #pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked
@ -1160,7 +1161,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
} }
// Don't decrement auto-fit counters until container window got a chance to submit its items // Don't decrement auto-fit counters until container window got a chance to submit its items
if (table->HostSkipItems == false) if (table->HostSkipItems == false && table->InstanceCurrent == 0)
{ {
column->AutoFitQueue >>= 1; column->AutoFitQueue >>= 1;
column->CannotSkipItemsQueue >>= 1; column->CannotSkipItemsQueue >>= 1;
@ -1484,7 +1485,9 @@ void ImGui::EndTable()
{ {
short backup_nav_layers_active_mask = inner_window->DC.NavLayersActiveMask; short backup_nav_layers_active_mask = inner_window->DC.NavLayersActiveMask;
inner_window->DC.NavLayersActiveMask |= 1 << ImGuiNavLayer_Main; // So empty table don't appear to navigate differently. inner_window->DC.NavLayersActiveMask |= 1 << ImGuiNavLayer_Main; // So empty table don't appear to navigate differently.
g.CurrentTable = NULL; // To avoid error recovery recursing
EndChild(); EndChild();
g.CurrentTable = table;
inner_window->DC.NavLayersActiveMask = backup_nav_layers_active_mask; inner_window->DC.NavLayersActiveMask = backup_nav_layers_active_mask;
} }
else else
@ -3137,7 +3140,7 @@ void ImGui::TableHeader(const char* label)
if ((table->RowFlags & ImGuiTableRowFlags_Headers) == 0) if ((table->RowFlags & ImGuiTableRowFlags_Headers) == 0)
TableSetBgColor(ImGuiTableBgTarget_CellBg, GetColorU32(ImGuiCol_TableHeaderBg), table->CurrentColumn); TableSetBgColor(ImGuiTableBgTarget_CellBg, GetColorU32(ImGuiCol_TableHeaderBg), table->CurrentColumn);
} }
RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_Compact | ImGuiNavHighlightFlags_NoRounding); RenderNavCursor(bb, id, ImGuiNavRenderCursorFlags_Compact | ImGuiNavRenderCursorFlags_NoRounding);
if (held) if (held)
table->HeldHeaderColumn = (ImGuiTableColumnIdx)column_n; table->HeldHeaderColumn = (ImGuiTableColumnIdx)column_n;
window->DC.CursorPos.y -= g.Style.ItemSpacing.y * 0.5f; window->DC.CursorPos.y -= g.Style.ItemSpacing.y * 0.5f;

File diff suppressed because it is too large Load Diff

View File

@ -38,7 +38,25 @@ You can use the `ImGuiFreeTypeBuilderFlags_LoadColor` flag to load certain color
### Using OpenType SVG fonts (SVGinOT) ### Using OpenType SVG fonts (SVGinOT)
- *SVG in Open Type* is a standard by Adobe and Mozilla for color OpenType and Open Font Format fonts. It allows font creators to embed complete SVG files within a font enabling full color and even animations. - *SVG in Open Type* is a standard by Adobe and Mozilla for color OpenType and Open Font Format fonts. It allows font creators to embed complete SVG files within a font enabling full color and even animations.
- Popular fonts such as [twemoji](https://github.com/13rac1/twemoji-color-font) and fonts made with [scfbuild](https://github.com/13rac1/scfbuild) is SVGinOT - Popular fonts such as [twemoji](https://github.com/13rac1/twemoji-color-font) and fonts made with [scfbuild](https://github.com/13rac1/scfbuild) is SVGinOT
- Requires: [lunasvg](https://github.com/sammycage/lunasvg) v2.3.2 and above - Two alternatives are possible to render SVG fonts: use "lunasvg" or "plutosvg". plutosvg will support some more fonts (e.g. NotoColorEmoji-Regular) and may load them faster.
1. Add `#define IMGUI_ENABLE_FREETYPE_LUNASVG` in your `imconfig.h`.
2. Get latest lunasvg binaries or build yourself. Under Windows you may use vcpkg with: `vcpkg install lunasvg --triplet=x64-windows`. #### Using lunasvg
Requires: [lunasvg](https://github.com/sammycage/lunasvg) v2.3.2 and above
- Add `#define IMGUI_ENABLE_FREETYPE_LUNASVG` in your `imconfig.h`.
- Get latest lunasvg binaries or build yourself. Under Windows you may use vcpkg with: `vcpkg install lunasvg --triplet=x64-windows`.
#### Using plutosvg (and plutovg)
- Add `#define IMGUI_ENABLE_FREETYPE_PLUTOSVG` in your `imconfig.h`.
- Compile and link with plutosvg *and* plutovg (which is required by plutosvg)
_Compilation hints for plutovg_
- Compile all source files in `plutovg/source/*.c`
- Add include directory: `plutovg/include` + `plutovg/stb`
_Compilation hints for plutosvg_
- Compile `plutosvg/source/plutosvg.c`
- Add include directory: `plutosvg/source`
- Add define: `PLUTOSVG_HAS_FREETYPE`
- Link with: plutovg, freetype

View File

@ -6,8 +6,9 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2024/10/17: added plutosvg support for SVG Fonts (seems faster/better than lunasvg). Enable by using '#define IMGUI_ENABLE_FREETYPE_PLUTOSVG'. (#7927)
// 2023/11/13: added support for ImFontConfig::RasterizationDensity field for scaling render density without scaling metrics. // 2023/11/13: added support for ImFontConfig::RasterizationDensity field for scaling render density without scaling metrics.
// 2023/08/01: added support for SVG fonts, enable by using '#define IMGUI_ENABLE_FREETYPE_LUNASVG' (#6591) // 2023/08/01: added support for SVG fonts, enable by using '#define IMGUI_ENABLE_FREETYPE_LUNASVG'. (#6591)
// 2023/01/04: fixed a packing issue which in some occurrences would prevent large amount of glyphs from being packed correctly. // 2023/01/04: fixed a packing issue which in some occurrences would prevent large amount of glyphs from being packed correctly.
// 2021/08/23: fixed crash when FT_Render_Glyph() fails to render a glyph and returns NULL. // 2021/08/23: fixed crash when FT_Render_Glyph() fails to render a glyph and returns NULL.
// 2021/03/05: added ImGuiFreeTypeBuilderFlags_Bitmap to load bitmap glyphs. // 2021/03/05: added ImGuiFreeTypeBuilderFlags_Bitmap to load bitmap glyphs.
@ -45,12 +46,21 @@
#include FT_GLYPH_H // <freetype/ftglyph.h> #include FT_GLYPH_H // <freetype/ftglyph.h>
#include FT_SYNTHESIS_H // <freetype/ftsynth.h> #include FT_SYNTHESIS_H // <freetype/ftsynth.h>
#ifdef IMGUI_ENABLE_FREETYPE_LUNASVG // Handle LunaSVG and PlutoSVG
#if defined(IMGUI_ENABLE_FREETYPE_LUNASVG) && defined(IMGUI_ENABLE_FREETYPE_PLUTOSVG)
#error "Cannot enable both IMGUI_ENABLE_FREETYPE_LUNASVG and IMGUI_ENABLE_FREETYPE_PLUTOSVG"
#endif
#ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
#include FT_OTSVG_H // <freetype/otsvg.h> #include FT_OTSVG_H // <freetype/otsvg.h>
#include FT_BBOX_H // <freetype/ftbbox.h> #include FT_BBOX_H // <freetype/ftbbox.h>
#include <lunasvg.h> #include <lunasvg.h>
#endif
#ifdef IMGUI_ENABLE_FREETYPE_PLUTOSVG
#include <plutosvg.h>
#endif
#if defined(IMGUI_ENABLE_FREETYPE_LUNASVG) || defined (IMGUI_ENABLE_FREETYPE_PLUTOSVG)
#if !((FREETYPE_MAJOR >= 2) && (FREETYPE_MINOR >= 12)) #if !((FREETYPE_MAJOR >= 2) && (FREETYPE_MINOR >= 12))
#error IMGUI_ENABLE_FREETYPE_LUNASVG requires FreeType version >= 2.12 #error IMGUI_ENABLE_FREETYPE_PLUTOSVG or IMGUI_ENABLE_FREETYPE_LUNASVG requires FreeType version >= 2.12
#endif #endif
#endif #endif
@ -269,11 +279,11 @@ namespace
// Need an outline for this to work // Need an outline for this to work
FT_GlyphSlot slot = Face->glyph; FT_GlyphSlot slot = Face->glyph;
#ifdef IMGUI_ENABLE_FREETYPE_LUNASVG #if defined(IMGUI_ENABLE_FREETYPE_LUNASVG) || defined(IMGUI_ENABLE_FREETYPE_PLUTOSVG)
IM_ASSERT(slot->format == FT_GLYPH_FORMAT_OUTLINE || slot->format == FT_GLYPH_FORMAT_BITMAP || slot->format == FT_GLYPH_FORMAT_SVG); IM_ASSERT(slot->format == FT_GLYPH_FORMAT_OUTLINE || slot->format == FT_GLYPH_FORMAT_BITMAP || slot->format == FT_GLYPH_FORMAT_SVG);
#else #else
#if ((FREETYPE_MAJOR >= 2) && (FREETYPE_MINOR >= 12)) #if ((FREETYPE_MAJOR >= 2) && (FREETYPE_MINOR >= 12))
IM_ASSERT(slot->format != FT_GLYPH_FORMAT_SVG && "The font contains SVG glyphs, you'll need to enable IMGUI_ENABLE_FREETYPE_LUNASVG in imconfig.h and install required libraries in order to use this font"); IM_ASSERT(slot->format != FT_GLYPH_FORMAT_SVG && "The font contains SVG glyphs, you'll need to enable IMGUI_ENABLE_FREETYPE_PLUTOSVG or IMGUI_ENABLE_FREETYPE_LUNASVG in imconfig.h and install required libraries in order to use this font");
#endif #endif
IM_ASSERT(slot->format == FT_GLYPH_FORMAT_OUTLINE || slot->format == FT_GLYPH_FORMAT_BITMAP); IM_ASSERT(slot->format == FT_GLYPH_FORMAT_OUTLINE || slot->format == FT_GLYPH_FORMAT_BITMAP);
#endif // IMGUI_ENABLE_FREETYPE_LUNASVG #endif // IMGUI_ENABLE_FREETYPE_LUNASVG
@ -671,8 +681,6 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++) for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
{ {
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i]; ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
if (src_tmp.GlyphsCount == 0)
continue;
// When merging fonts with MergeMode=true: // When merging fonts with MergeMode=true:
// - We can have multiple input fonts writing into a same destination font. // - We can have multiple input fonts writing into a same destination font.
@ -683,6 +691,9 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
const float ascent = src_tmp.Font.Info.Ascender; const float ascent = src_tmp.Font.Info.Ascender;
const float descent = src_tmp.Font.Info.Descender; const float descent = src_tmp.Font.Info.Descender;
ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent); ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent);
if (src_tmp.GlyphsCount == 0)
continue;
const float font_off_x = cfg.GlyphOffset.x; const float font_off_x = cfg.GlyphOffset.x;
const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent); const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent);
@ -810,6 +821,10 @@ static bool ImFontAtlasBuildWithFreeType(ImFontAtlas* atlas)
SVG_RendererHooks hooks = { ImGuiLunasvgPortInit, ImGuiLunasvgPortFree, ImGuiLunasvgPortRender, ImGuiLunasvgPortPresetSlot }; SVG_RendererHooks hooks = { ImGuiLunasvgPortInit, ImGuiLunasvgPortFree, ImGuiLunasvgPortRender, ImGuiLunasvgPortPresetSlot };
FT_Property_Set(ft_library, "ot-svg", "svg-hooks", &hooks); FT_Property_Set(ft_library, "ot-svg", "svg-hooks", &hooks);
#endif // IMGUI_ENABLE_FREETYPE_LUNASVG #endif // IMGUI_ENABLE_FREETYPE_LUNASVG
#ifdef IMGUI_ENABLE_FREETYPE_PLUTOSVG
// With plutosvg, use provided hooks
FT_Property_Set(ft_library, "ot-svg", "svg-hooks", plutosvg_ft_svg_hooks());
#endif // IMGUI_ENABLE_FREETYPE_PLUTOSVG
bool ret = ImFontAtlasBuildWithFreeTypeEx(ft_library, atlas, atlas->FontBuilderFlags); bool ret = ImFontAtlasBuildWithFreeTypeEx(ft_library, atlas, atlas->FontBuilderFlags);
FT_Done_Library(ft_library); FT_Done_Library(ft_library);

View File

@ -5,6 +5,13 @@
#include "imgui.h" // IMGUI_API #include "imgui.h" // IMGUI_API
#ifndef IMGUI_DISABLE #ifndef IMGUI_DISABLE
// Usage:
// - Add '#define IMGUI_ENABLE_FREETYPE' in your imconfig to enable support for imgui_freetype in imgui.
// Optional support for OpenType SVG fonts:
// - Add '#define IMGUI_ENABLE_FREETYPE_PLUTOSVG' to use plutosvg (not provided). See #7927.
// - Add '#define IMGUI_ENABLE_FREETYPE_LUNASVG' to use lunasvg (not provided). See #6591.
// Forward declarations // Forward declarations
struct ImFontAtlas; struct ImFontAtlas;
struct ImFontBuilderIO; struct ImFontBuilderIO;