Merge branch 'master' into docking

# Conflicts:
#	examples/imgui_impl_dx9.cpp
#	examples/imgui_impl_opengl3.cpp
docking
omar 6 years ago
commit 49fb8e6c45

@ -102,11 +102,17 @@ Breaking Changes:
Other Changes: Other Changes:
- InputText: Fixed selection background starts rendering one frame after the cursor movement - InputText: Fixed selection background starts rendering one frame after the cursor movement
when first transitioning from no-selection to has-selection. (Bug in 1.69) (#2436) [@Nazg-Gul] when first transitioning from no-selection to has-selection. (Bug in 1.69) (#2436) [@Nazg-Gul]
- InputText: Work-around for buggy standard libraries where isprint('\t') returns true. (#2467, #1336)
- InputText: Fixed ImGuiInputTextFlags_AllowTabInput leading to two tabs characters being inserted
if the back-end provided both Key and Character input. (#2467, #1336)
- GetMouseDragDelta(): also returns the delta on the mouse button released frame. (#2419) - GetMouseDragDelta(): also returns the delta on the mouse button released frame. (#2419)
- GetMouseDragDelta(): verify that mouse positions are valid otherwise returns zero. - GetMouseDragDelta(): verify that mouse positions are valid otherwise returns zero.
- Inputs: Also add support for horizontal scroll with Shift+Mouse Wheel. (#2424, #1463) [@LucaRood] - Inputs: Also add support for horizontal scroll with Shift+Mouse Wheel. (#2424, #1463) [@LucaRood]
- Examples: OpenGL: Added a dummy GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized - Examples: OpenGL: Added a dummy GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized
GL function loaders early, and help users understand what they are missing. (#2421) GL function loaders early, and help users understand what they are missing. (#2421)
- Examples: OpenGL3: Minor tweaks + not calling glBindBuffer more than necessary in the render loop.
- Examples: Vulkan: Added missing support for 32-bit indices (#define ImDrawIdx unsigned int).
- Examples: DirectX9: Fixed erroneous assert in ImGui_ImplDX9_InvalidateDeviceObjects(). (#2454)
- Examples: FreeGLUT: Made io.DeltaTime always > 0. (#2430) - Examples: FreeGLUT: Made io.DeltaTime always > 0. (#2430)

@ -81,6 +81,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- input text: force scroll to end or scroll to a given line/contents (so user can implement a log or a search feature) - input text: force scroll to end or scroll to a given line/contents (so user can implement a log or a search feature)
- input text: a side bar that could e.g. preview where errors are. probably left to the user to draw but we'd need to give them the info there. - input text: a side bar that could e.g. preview where errors are. probably left to the user to draw but we'd need to give them the info there.
- input text: a way for the user to provide syntax coloring. - input text: a way for the user to provide syntax coloring.
- input text: Shift+TAB with ImGuiInputTextFlags_AllowTabInput could eat preceding blanks, up to tab_count.
- input text multi-line: don't directly call AddText() which does an unnecessary vertex reserve for character count prior to clipping. and/or more line-based clipping to AddText(). and/or reorganize TextUnformatted/RenderText for more efficiency for large text (e.g TextUnformatted could clip and log separately, etc). - input text multi-line: don't directly call AddText() which does an unnecessary vertex reserve for character count prior to clipping. and/or more line-based clipping to AddText(). and/or reorganize TextUnformatted/RenderText for more efficiency for large text (e.g TextUnformatted could clip and log separately, etc).
- input text multi-line: support for cut/paste without selection (cut/paste the current line) - input text multi-line: support for cut/paste without selection (cut/paste the current line)
- input text multi-line: line numbers? status bar? (follow up on #200) - input text multi-line: line numbers? status bar? (follow up on #200)
@ -165,7 +166,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- button: provide a button that looks framed. (?) - button: provide a button that looks framed. (?)
- image/image button: misalignment on padded/bordered button? - image/image button: misalignment on padded/bordered button?
- image/image button: parameters are confusing, image() has tint_col,border_col whereas imagebutton() has bg_col/tint_col. Even thou they are different parameters ordering could be more consistent. can we fix that? - image/image button: parameters are confusing, image() has tint_col,border_col whereas imagebutton() has bg_col/tint_col. Even thou they are different parameters ordering could be more consistent. can we fix that?
- image button: not taking an explicit id is odd. - image button: not taking an explicit id can be problematic. (#2464, #1390)
- slider/drag: ctrl+click when format doesn't include a % character.. disable? display underlying value in default format? (see InputScalarAsWidgetReplacement) - slider/drag: ctrl+click when format doesn't include a % character.. disable? display underlying value in default format? (see InputScalarAsWidgetReplacement)
- slider: allow using the [-]/[+] buttons used by InputFloat()/InputInt() - slider: allow using the [-]/[+] buttons used by InputFloat()/InputInt()
- slider: initial absolute click is imprecise. change to relative movement slider (same as scrollbar). (#1946) - slider: initial absolute click is imprecise. change to relative movement slider (same as scrollbar). (#1946)
@ -371,6 +372,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- examples: glfw: could go idle when minimized? if (glfwGetWindowAttrib(window, GLFW_ICONIFIED)) { glfwWaitEvents(); continue; } // issue: DeltaTime will be super high on resume, perhaps provide a way to let impl know (#440) - examples: glfw: could go idle when minimized? if (glfwGetWindowAttrib(window, GLFW_ICONIFIED)) { glfwWaitEvents(); continue; } // issue: DeltaTime will be super high on resume, perhaps provide a way to let impl know (#440)
- examples: opengl: rename imgui_impl_opengl2 to impl_opengl_legacy and imgui_impl_opengl3 to imgui_impl_opengl? (#1900) - examples: opengl: rename imgui_impl_opengl2 to impl_opengl_legacy and imgui_impl_opengl3 to imgui_impl_opengl? (#1900)
- examples: opengl: could use a single vertex buffer and glBufferSubData for uploads? - examples: opengl: could use a single vertex buffer and glBufferSubData for uploads?
- examples: vulkan: viewport: support for synchronized swapping of multiple swap chains.
- optimization: replace vsnprintf with stb_printf? or enable the defines/infrastructure to allow it (#1038) - optimization: replace vsnprintf with stb_printf? or enable the defines/infrastructure to allow it (#1038)
- optimization: add clipping for multi-component widgets (SliderFloatX, ColorEditX, etc.). one problem is that nav branch can't easily clip parent group when there is a move request. - optimization: add clipping for multi-component widgets (SliderFloatX, ColorEditX, etc.). one problem is that nav branch can't easily clip parent group when there is a move request.
- optimization: add a flag to disable most of rendering, for the case where the user expect to skip it (#335) - optimization: add a flag to disable most of rendering, for the case where the user expect to skip it (#335)

@ -1,8 +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.
set OUT_DIR=Debug set OUT_DIR=Debug
set OUT_EXE=example_sdl_opengl2.exe set OUT_EXE=example_sdl_opengl2
set INCLUDES=/I.. /I..\.. /I%SDL2_DIR%\include set INCLUDES=/I.. /I..\.. /I%SDL2_DIR%\include
set SOURCES=main.cpp ..\imgui_impl_sdl.cpp ..\imgui_impl_opengl2.cpp ..\..\imgui*.cpp set SOURCES=main.cpp ..\imgui_impl_sdl.cpp ..\imgui_impl_opengl2.cpp ..\..\imgui*.cpp
set LIBS=/libpath:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib set LIBS=/libpath:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib
mkdir %OUT_DIR% mkdir %OUT_DIR%
cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_DIR%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console

@ -1,6 +1,6 @@
@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_DIR=Debug
set OUT_EXE=example_sdl_opengl3.exe set OUT_EXE=example_sdl_opengl3
set INCLUDES=/I.. /I..\.. /I%SDL2_DIR%\include /I..\libs\gl3w set INCLUDES=/I.. /I..\.. /I%SDL2_DIR%\include /I..\libs\gl3w
set SOURCES=main.cpp ..\imgui_impl_sdl.cpp ..\imgui_impl_opengl3.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c set SOURCES=main.cpp ..\imgui_impl_sdl.cpp ..\imgui_impl_opengl3.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c
set LIBS=/libpath:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib set LIBS=/libpath:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib

@ -96,7 +96,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
return; return;
} }
// Copy and convert all vertices into a single contiguous 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(g_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK) if (ctx->Map(g_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK)
return; return;

@ -12,6 +12,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)
// 2019-03-29: Misc: Various minor tidying up.
// 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().
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
// 2018-06-12: DirectX12: Moved the ID3D12GraphicsCommandList* parameter from NewFrame() to RenderDrawData(). // 2018-06-12: DirectX12: Moved the ID3D12GraphicsCommandList* parameter from NewFrame() to RenderDrawData().
@ -43,10 +44,10 @@ static D3D12_GPU_DESCRIPTOR_HANDLE g_hFontSrvGpuDescHandle = {};
struct FrameResources struct FrameResources
{ {
ID3D12Resource* IB; ID3D12Resource* IndexBuffer;
ID3D12Resource* VB; ID3D12Resource* VertexBuffer;
int VertexBufferSize;
int IndexBufferSize; int IndexBufferSize;
int VertexBufferSize;
}; };
static FrameResources* g_pFrameResources = NULL; static FrameResources* g_pFrameResources = NULL;
static UINT g_numFramesInFlight = 0; static UINT g_numFramesInFlight = 0;
@ -68,17 +69,13 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
// FIXME: I'm assuming that this only gets called once per frame! // FIXME: I'm assuming that this only gets called once per frame!
// If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator. // If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator.
g_frameIndex = g_frameIndex + 1; g_frameIndex = g_frameIndex + 1;
FrameResources* frameResources = &g_pFrameResources[g_frameIndex % g_numFramesInFlight]; FrameResources* fr = &g_pFrameResources[g_frameIndex % g_numFramesInFlight];
ID3D12Resource* g_pVB = frameResources->VB;
ID3D12Resource* g_pIB = frameResources->IB;
int g_VertexBufferSize = frameResources->VertexBufferSize;
int g_IndexBufferSize = frameResources->IndexBufferSize;
// Create and grow vertex/index buffers if needed // Create and grow vertex/index buffers if needed
if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount) if (fr->VertexBuffer == NULL || fr->VertexBufferSize < draw_data->TotalVtxCount)
{ {
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } if (fr->VertexBuffer != NULL) { fr->VertexBuffer->Release(); fr->VertexBuffer = NULL; }
g_VertexBufferSize = draw_data->TotalVtxCount + 5000; fr->VertexBufferSize = draw_data->TotalVtxCount + 5000;
D3D12_HEAP_PROPERTIES props; D3D12_HEAP_PROPERTIES props;
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES)); memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
props.Type = D3D12_HEAP_TYPE_UPLOAD; props.Type = D3D12_HEAP_TYPE_UPLOAD;
@ -87,7 +84,7 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
D3D12_RESOURCE_DESC desc; D3D12_RESOURCE_DESC desc;
memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC)); memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC));
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
desc.Width = g_VertexBufferSize * sizeof(ImDrawVert); desc.Width = fr->VertexBufferSize * sizeof(ImDrawVert);
desc.Height = 1; desc.Height = 1;
desc.DepthOrArraySize = 1; desc.DepthOrArraySize = 1;
desc.MipLevels = 1; desc.MipLevels = 1;
@ -95,15 +92,13 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
desc.SampleDesc.Count = 1; desc.SampleDesc.Count = 1;
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
desc.Flags = D3D12_RESOURCE_FLAG_NONE; desc.Flags = D3D12_RESOURCE_FLAG_NONE;
if (g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&g_pVB)) < 0) if (g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&fr->VertexBuffer)) < 0)
return; return;
frameResources->VB = g_pVB;
frameResources->VertexBufferSize = g_VertexBufferSize;
} }
if (!g_pIB || g_IndexBufferSize < draw_data->TotalIdxCount) if (fr->IndexBuffer == NULL || fr->IndexBufferSize < draw_data->TotalIdxCount)
{ {
if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } if (fr->IndexBuffer != NULL) { fr->IndexBuffer->Release(); fr->IndexBuffer = NULL; }
g_IndexBufferSize = draw_data->TotalIdxCount + 10000; fr->IndexBufferSize = draw_data->TotalIdxCount + 10000;
D3D12_HEAP_PROPERTIES props; D3D12_HEAP_PROPERTIES props;
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES)); memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
props.Type = D3D12_HEAP_TYPE_UPLOAD; props.Type = D3D12_HEAP_TYPE_UPLOAD;
@ -112,7 +107,7 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
D3D12_RESOURCE_DESC desc; D3D12_RESOURCE_DESC desc;
memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC)); memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC));
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
desc.Width = g_IndexBufferSize * sizeof(ImDrawIdx); desc.Width = fr->IndexBufferSize * sizeof(ImDrawIdx);
desc.Height = 1; desc.Height = 1;
desc.DepthOrArraySize = 1; desc.DepthOrArraySize = 1;
desc.MipLevels = 1; desc.MipLevels = 1;
@ -120,19 +115,17 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
desc.SampleDesc.Count = 1; desc.SampleDesc.Count = 1;
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
desc.Flags = D3D12_RESOURCE_FLAG_NONE; desc.Flags = D3D12_RESOURCE_FLAG_NONE;
if (g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&g_pIB)) < 0) if (g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&fr->IndexBuffer)) < 0)
return; return;
frameResources->IB = g_pIB;
frameResources->IndexBufferSize = g_IndexBufferSize;
} }
// Copy and convert all vertices into a single contiguous buffer // Upload vertex/index data into a single contiguous GPU buffer
void* vtx_resource, *idx_resource; void* vtx_resource, *idx_resource;
D3D12_RANGE range; D3D12_RANGE range;
memset(&range, 0, sizeof(D3D12_RANGE)); memset(&range, 0, sizeof(D3D12_RANGE));
if (g_pVB->Map(0, &range, &vtx_resource) != S_OK) if (fr->VertexBuffer->Map(0, &range, &vtx_resource) != S_OK)
return; return;
if (g_pIB->Map(0, &range, &idx_resource) != S_OK) if (fr->IndexBuffer->Map(0, &range, &idx_resource) != S_OK)
return; return;
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource; ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource;
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource; ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource;
@ -144,14 +137,13 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
vtx_dst += cmd_list->VtxBuffer.Size; vtx_dst += cmd_list->VtxBuffer.Size;
idx_dst += cmd_list->IdxBuffer.Size; idx_dst += cmd_list->IdxBuffer.Size;
} }
g_pVB->Unmap(0, &range); fr->VertexBuffer->Unmap(0, &range);
g_pIB->Unmap(0, &range); fr->IndexBuffer->Unmap(0, &range);
// 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). DisplayMin 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). DisplayMin is (0,0) for single viewport apps.
VERTEX_CONSTANT_BUFFER vertex_constant_buffer; VERTEX_CONSTANT_BUFFER vertex_constant_buffer;
{ {
VERTEX_CONSTANT_BUFFER* constant_buffer = &vertex_constant_buffer;
float L = draw_data->DisplayPos.x; float L = draw_data->DisplayPos.x;
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
float T = draw_data->DisplayPos.y; float T = draw_data->DisplayPos.y;
@ -163,7 +155,7 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
{ 0.0f, 0.0f, 0.5f, 0.0f }, { 0.0f, 0.0f, 0.5f, 0.0f },
{ (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(&vertex_constant_buffer.mvp, mvp, sizeof(mvp));
} }
// Setup viewport // Setup viewport
@ -181,14 +173,14 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
unsigned int offset = 0; unsigned int offset = 0;
D3D12_VERTEX_BUFFER_VIEW vbv; D3D12_VERTEX_BUFFER_VIEW vbv;
memset(&vbv, 0, sizeof(D3D12_VERTEX_BUFFER_VIEW)); memset(&vbv, 0, sizeof(D3D12_VERTEX_BUFFER_VIEW));
vbv.BufferLocation = g_pVB->GetGPUVirtualAddress() + offset; vbv.BufferLocation = fr->VertexBuffer->GetGPUVirtualAddress() + offset;
vbv.SizeInBytes = g_VertexBufferSize * stride; vbv.SizeInBytes = fr->VertexBufferSize * stride;
vbv.StrideInBytes = stride; vbv.StrideInBytes = stride;
ctx->IASetVertexBuffers(0, 1, &vbv); ctx->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 = g_pIB->GetGPUVirtualAddress(); ibv.BufferLocation = fr->IndexBuffer->GetGPUVirtualAddress();
ibv.SizeInBytes = g_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); ctx->IASetIndexBuffer(&ibv);
ctx->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); ctx->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
@ -196,7 +188,7 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
ctx->SetGraphicsRootSignature(g_pRootSignature); ctx->SetGraphicsRootSignature(g_pRootSignature);
ctx->SetGraphicsRoot32BitConstants(0, 16, &vertex_constant_buffer, 0); ctx->SetGraphicsRoot32BitConstants(0, 16, &vertex_constant_buffer, 0);
// Setup render state // 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); ctx->OMSetBlendFactor(blend_factor);
@ -212,10 +204,12 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback) if (pcmd->UserCallback)
{ {
// User callback (registered via ImDrawList::AddCallback)
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(cmd_list, pcmd);
} }
else else
{ {
// Apply Scissor, Bind texture, Draw
const D3D12_RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) }; const D3D12_RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) };
ctx->SetGraphicsRootDescriptorTable(1, *(D3D12_GPU_DESCRIPTOR_HANDLE*)&pcmd->TextureId); ctx->SetGraphicsRootDescriptorTable(1, *(D3D12_GPU_DESCRIPTOR_HANDLE*)&pcmd->TextureId);
ctx->RSSetScissorRects(1, &r); ctx->RSSetScissorRects(1, &r);
@ -494,9 +488,9 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
// Create the input layout // Create the input layout
static D3D12_INPUT_ELEMENT_DESC local_layout[] = { static D3D12_INPUT_ELEMENT_DESC local_layout[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, IM_OFFSETOF(ImDrawVert, pos), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, IM_OFFSETOF(ImDrawVert, uv), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, IM_OFFSETOF(ImDrawVert, col), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
}; };
psoDesc.InputLayout = { local_layout, 3 }; psoDesc.InputLayout = { local_layout, 3 };
} }
@ -580,15 +574,17 @@ void ImGui_ImplDX12_InvalidateDeviceObjects()
if (!g_pd3dDevice) if (!g_pd3dDevice)
return; return;
ImGuiIO& io = ImGui::GetIO();
if (g_pVertexShaderBlob) { g_pVertexShaderBlob->Release(); g_pVertexShaderBlob = NULL; } if (g_pVertexShaderBlob) { g_pVertexShaderBlob->Release(); g_pVertexShaderBlob = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; } if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
if (g_pRootSignature) { g_pRootSignature->Release(); g_pRootSignature = NULL; } if (g_pRootSignature) { g_pRootSignature->Release(); g_pRootSignature = NULL; }
if (g_pPipelineState) { g_pPipelineState->Release(); g_pPipelineState = NULL; } if (g_pPipelineState) { g_pPipelineState->Release(); g_pPipelineState = NULL; }
if (g_pFontTextureResource) { g_pFontTextureResource->Release(); g_pFontTextureResource = NULL; ImGui::GetIO().Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well. if (g_pFontTextureResource) { g_pFontTextureResource->Release(); g_pFontTextureResource = NULL; io.Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
for (UINT i = 0; i < g_numFramesInFlight; i++) for (UINT i = 0; i < g_numFramesInFlight; i++)
{ {
if (g_pFrameResources[i].IB) { g_pFrameResources[i].IB->Release(); g_pFrameResources[i].IB = NULL; } FrameResources* fr = &g_pFrameResources[i];
if (g_pFrameResources[i].VB) { g_pFrameResources[i].VB->Release(); g_pFrameResources[i].VB = NULL; } if (fr->IndexBuffer) { fr->IndexBuffer->Release(); fr->IndexBuffer = NULL; }
if (fr->VertexBuffer) { fr->VertexBuffer->Release(); fr->VertexBuffer = NULL; }
} }
} }
@ -611,10 +607,11 @@ bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FO
// Create buffers with a default size (they will later be grown as needed) // Create buffers with a default size (they will later be grown as needed)
for (int i = 0; i < num_frames_in_flight; i++) for (int i = 0; i < num_frames_in_flight; i++)
{ {
g_pFrameResources[i].IB = NULL; FrameResources* fr = &g_pFrameResources[i];
g_pFrameResources[i].VB = NULL; fr->IndexBuffer = NULL;
g_pFrameResources[i].VertexBufferSize = 5000; fr->VertexBuffer = NULL;
g_pFrameResources[i].IndexBufferSize = 10000; fr->IndexBufferSize = 10000;
fr->VertexBufferSize = 5000;
} }
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
@ -628,10 +625,10 @@ void ImGui_ImplDX12_Shutdown()
ImGui_ImplDX12_ShutdownPlatformInterface(); ImGui_ImplDX12_ShutdownPlatformInterface();
ImGui_ImplDX12_InvalidateDeviceObjects(); ImGui_ImplDX12_InvalidateDeviceObjects();
delete[] g_pFrameResources; delete[] g_pFrameResources;
g_pFrameResources = NULL;
g_pd3dDevice = NULL; g_pd3dDevice = NULL;
g_hFontSrvCpuDescHandle.ptr = 0; g_hFontSrvCpuDescHandle.ptr = 0;
g_hFontSrvGpuDescHandle.ptr = 0; g_hFontSrvGpuDescHandle.ptr = 0;
g_pFrameResources = NULL;
g_numFramesInFlight = 0; g_numFramesInFlight = 0;
g_frameIndex = UINT_MAX; g_frameIndex = UINT_MAX;
} }

@ -12,6 +12,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)
// 2018-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2018-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2019-03-29: Misc: Fixed erroneous assert in ImGui_ImplDX9_InvalidateDeviceObjects().
// 2019-01-16: Misc: Disabled fog before drawing UI's. Fixes issue #2288. // 2019-01-16: Misc: Disabled fog before drawing UI's. Fixes issue #2288.
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
// 2018-06-08: Misc: Extracted imgui_impl_dx9.cpp/.h away from the old combined DX9+Win32 example. // 2018-06-08: Misc: Extracted imgui_impl_dx9.cpp/.h away from the old combined DX9+Win32 example.
@ -265,24 +266,9 @@ void ImGui_ImplDX9_InvalidateDeviceObjects()
{ {
if (!g_pd3dDevice) if (!g_pd3dDevice)
return; return;
if (g_pVB) if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
{ if (g_pIB) { g_pIB->Release(); g_pIB = NULL; }
g_pVB->Release(); if (g_FontTexture) { g_FontTexture->Release(); g_FontTexture = NULL; ImGui::GetIO().Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
g_pVB = NULL;
}
if (g_pIB)
{
g_pIB->Release();
g_pIB = NULL;
}
// At this point note that we set ImGui::GetIO().Fonts->TexID to be == g_FontTexture, so clear both.
ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(g_FontTexture == io.Fonts->TexID);
if (g_FontTexture)
g_FontTexture->Release();
g_FontTexture = NULL;
io.Fonts->TexID = NULL;
} }
void ImGui_ImplDX9_NewFrame() void ImGui_ImplDX9_NewFrame()

@ -14,6 +14,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)
// 2018-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2018-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2019-03-29: OpenGL: Not calling glBindBuffer more than necessary in the render loop.
// 2019-03-15: OpenGL: Added a dummy GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized GL function loaders early. // 2019-03-15: OpenGL: Added a dummy GL call + comments in ImGui_ImplOpenGL3_Init() to detect uninitialized GL function loaders early.
// 2019-03-03: OpenGL: Fix support for ES 2.0 (WebGL 1.0). // 2019-03-03: OpenGL: Fix support for ES 2.0 (WebGL 1.0).
// 2019-02-20: OpenGL: Fix for OSX not supporting OpenGL 4.5, we don't try to read GL_CLIP_ORIGIN even if defined by the headers/loader. // 2019-02-20: OpenGL: Fix for OSX not supporting OpenGL 4.5, we don't try to read GL_CLIP_ORIGIN even if defined by the headers/loader.
@ -106,8 +107,8 @@
static char g_GlslVersionString[32] = ""; static char g_GlslVersionString[32] = "";
static GLuint g_FontTexture = 0; static GLuint g_FontTexture = 0;
static GLuint g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; static GLuint g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; // Uniforms location
static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; static int g_AttribLocationVtxPos = 0, g_AttribLocationVtxUV = 0, g_AttribLocationVtxColor = 0; // Vertex attributes location
static unsigned int g_VboHandle = 0, g_ElementsHandle = 0; static unsigned int g_VboHandle = 0, g_ElementsHandle = 0;
// Forward Declarations // Forward Declarations
@ -182,7 +183,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
#endif #endif
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
#ifndef IMGUI_IMPL_OPENGL_ES2 #ifndef IMGUI_IMPL_OPENGL_ES2
GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); GLint last_vertex_array_object; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array_object);
#endif #endif
#ifdef GL_POLYGON_MODE #ifdef GL_POLYGON_MODE
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
@ -238,20 +239,23 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise. glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise.
#endif #endif
// Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared among GL contexts)
// The renderer would actually work without any VAO bound, but then our VertexAttrib calls would overwrite the default one currently bound.
#ifndef IMGUI_IMPL_OPENGL_ES2 #ifndef IMGUI_IMPL_OPENGL_ES2
// Recreate the VAO every time GLuint vertex_array_object = 0;
// (This is to easily allow multiple GL contexts. VAO are not shared among GL contexts, and we don't track creation/deletion of windows so we don't have an obvious key to use to cache them.) glGenVertexArrays(1, &vertex_array_object);
GLuint vao_handle = 0; glBindVertexArray(vertex_array_object);
glGenVertexArrays(1, &vao_handle);
glBindVertexArray(vao_handle);
#endif #endif
// Bind vertex/index buffers and setup attributes for ImDrawVert
glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
glEnableVertexAttribArray(g_AttribLocationPosition); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle);
glEnableVertexAttribArray(g_AttribLocationUV); glEnableVertexAttribArray(g_AttribLocationVtxPos);
glEnableVertexAttribArray(g_AttribLocationColor); glEnableVertexAttribArray(g_AttribLocationVtxUV);
glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)); glEnableVertexAttribArray(g_AttribLocationVtxColor);
glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)); glVertexAttribPointer(g_AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos));
glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col)); glVertexAttribPointer(g_AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv));
glVertexAttribPointer(g_AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col));
// 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
@ -263,10 +267,8 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* cmd_list = draw_data->CmdLists[n];
size_t idx_buffer_offset = 0; size_t idx_buffer_offset = 0;
glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); // Upload vertex/index buffers
glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW); glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), (const GLvoid*)cmd_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 < cmd_list->CmdBuffer.Size; cmd_i++)
@ -292,7 +294,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
if (clip_origin_lower_left) if (clip_origin_lower_left)
glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)); glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y));
else else
glScissor((int)clip_rect.x, (int)clip_rect.y, (int)clip_rect.z, (int)clip_rect.w); // Support for GL 4.5's glClipControl(GL_UPPER_LEFT) glScissor((int)clip_rect.x, (int)clip_rect.y, (int)clip_rect.z, (int)clip_rect.w); // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT)
// Bind texture, Draw // Bind texture, Draw
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
@ -302,8 +304,10 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
idx_buffer_offset += pcmd->ElemCount * sizeof(ImDrawIdx); idx_buffer_offset += pcmd->ElemCount * sizeof(ImDrawIdx);
} }
} }
// Destroy the temporary VAO
#ifndef IMGUI_IMPL_OPENGL_ES2 #ifndef IMGUI_IMPL_OPENGL_ES2
glDeleteVertexArrays(1, &vao_handle); glDeleteVertexArrays(1, &vertex_array_object);
#endif #endif
// Restore modified GL state // Restore modified GL state
@ -314,7 +318,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
#endif #endif
glActiveTexture(last_active_texture); glActiveTexture(last_active_texture);
#ifndef IMGUI_IMPL_OPENGL_ES2 #ifndef IMGUI_IMPL_OPENGL_ES2
glBindVertexArray(last_vertex_array); glBindVertexArray(last_vertex_array_object);
#endif #endif
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);
@ -566,9 +570,9 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects()
g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture");
g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx");
g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); g_AttribLocationVtxPos = glGetAttribLocation(g_ShaderHandle, "Position");
g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); g_AttribLocationVtxUV = glGetAttribLocation(g_ShaderHandle, "UV");
g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); g_AttribLocationVtxColor = glGetAttribLocation(g_ShaderHandle, "Color");
// Create buffers // Create buffers
glGenBuffers(1, &g_VboHandle); glGenBuffers(1, &g_VboHandle);

@ -14,6 +14,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)
// 2019-04-01: Vulkan: Support for 32-bit index buffer (#define ImDrawIdx unsigned int).
// 2019-02-16: Vulkan: Viewport and clipping rectangles correctly using draw_data->FramebufferScale to allow retina display. // 2019-02-16: Vulkan: Viewport and clipping rectangles correctly using draw_data->FramebufferScale to allow retina display.
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
// 2018-08-25: Vulkan: Fixed mishandled VkSurfaceCapabilitiesKHR::maxImageCount=0 case. // 2018-08-25: Vulkan: Fixed mishandled VkSurfaceCapabilitiesKHR::maxImageCount=0 case.
@ -216,17 +217,17 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
VkResult err; VkResult err;
FrameDataForRender* fd = &g_FramesDataBuffers[g_FrameIndex]; FrameDataForRender* fd = &g_FramesDataBuffers[g_FrameIndex];
g_FrameIndex = (g_FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES; g_FrameIndex = (g_FrameIndex + 1) % IM_ARRAYSIZE(g_FramesDataBuffers);
// Create the Vertex and Index buffers: // Create the Vertex and Index buffers:
size_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert); size_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert);
size_t index_size = draw_data->TotalIdxCount * sizeof(ImDrawIdx); size_t index_size = draw_data->TotalIdxCount * sizeof(ImDrawIdx);
if (!fd->VertexBuffer || fd->VertexBufferSize < vertex_size) if (fd->VertexBuffer == VK_NULL_HANDLE || fd->VertexBufferSize < vertex_size)
CreateOrResizeBuffer(fd->VertexBuffer, fd->VertexBufferMemory, fd->VertexBufferSize, vertex_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); CreateOrResizeBuffer(fd->VertexBuffer, fd->VertexBufferMemory, fd->VertexBufferSize, vertex_size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
if (!fd->IndexBuffer || fd->IndexBufferSize < index_size) if (fd->IndexBuffer == VK_NULL_HANDLE || fd->IndexBufferSize < index_size)
CreateOrResizeBuffer(fd->IndexBuffer, fd->IndexBufferMemory, fd->IndexBufferSize, index_size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); CreateOrResizeBuffer(fd->IndexBuffer, fd->IndexBufferMemory, fd->IndexBufferSize, index_size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
// Upload Vertex and index Data: // Upload vertex/index data into a single contiguous GPU buffer
{ {
ImDrawVert* vtx_dst = NULL; ImDrawVert* vtx_dst = NULL;
ImDrawIdx* idx_dst = NULL; ImDrawIdx* idx_dst = NULL;
@ -267,7 +268,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
VkBuffer vertex_buffers[1] = { fd->VertexBuffer }; VkBuffer vertex_buffers[1] = { fd->VertexBuffer };
VkDeviceSize vertex_offset[1] = { 0 }; VkDeviceSize vertex_offset[1] = { 0 };
vkCmdBindVertexBuffers(command_buffer, 0, 1, vertex_buffers, vertex_offset); vkCmdBindVertexBuffers(command_buffer, 0, 1, vertex_buffers, vertex_offset);
vkCmdBindIndexBuffer(command_buffer, fd->IndexBuffer, 0, VK_INDEX_TYPE_UINT16); vkCmdBindIndexBuffer(command_buffer, fd->IndexBuffer, 0, sizeof(ImDrawIdx) == 2 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32);
} }
// Setup viewport: // Setup viewport:
@ -310,6 +311,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback) if (pcmd->UserCallback)
{ {
// User callback (registered via ImDrawList::AddCallback)
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(cmd_list, pcmd);
} }
else else
@ -697,7 +699,7 @@ void ImGui_ImplVulkan_InvalidateDeviceObjects()
{ {
ImGui_ImplVulkan_InvalidateFontUploadObjects(); ImGui_ImplVulkan_InvalidateFontUploadObjects();
for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++) for (int i = 0; i < IM_ARRAYSIZE(g_FramesDataBuffers); i++)
{ {
FrameDataForRender* fd = &g_FramesDataBuffers[i]; FrameDataForRender* fd = &g_FramesDataBuffers[i];
if (fd->VertexBuffer) { vkDestroyBuffer (g_Device, fd->VertexBuffer, g_Allocator); fd->VertexBuffer = VK_NULL_HANDLE; } if (fd->VertexBuffer) { vkDestroyBuffer (g_Device, fd->VertexBuffer, g_Allocator); fd->VertexBuffer = VK_NULL_HANDLE; }
@ -876,7 +878,7 @@ void ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(VkPhysicalDevice physical_
// Create Command Buffers // Create Command Buffers
VkResult err; VkResult err;
for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++) for (int i = 0; i < IM_ARRAYSIZE(wd->Frames); i++)
{ {
ImGui_ImplVulkanH_FrameData* fd = &wd->Frames[i]; ImGui_ImplVulkanH_FrameData* fd = &wd->Frames[i];
{ {
@ -1077,7 +1079,7 @@ void ImGui_ImplVulkanH_DestroyWindowData(VkInstance instance, VkDevice device, I
vkDeviceWaitIdle(device); // FIXME: We could wait on the Queue if we had the queue in wd-> (otherwise VulkanH functions can't use globals) vkDeviceWaitIdle(device); // FIXME: We could wait on the Queue if we had the queue in wd-> (otherwise VulkanH functions can't use globals)
//vkQueueWaitIdle(g_Queue); //vkQueueWaitIdle(g_Queue);
for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++) for (int i = 0; i < IM_ARRAYSIZE(wd->Frames); i++)
{ {
ImGui_ImplVulkanH_FrameData* fd = &wd->Frames[i]; ImGui_ImplVulkanH_FrameData* fd = &wd->Frames[i];
vkDestroyFence(device, fd->Fence, allocator); vkDestroyFence(device, fd->Fence, allocator);

@ -944,7 +944,7 @@ CODE
#endif #endif
#include "imgui_internal.h" #include "imgui_internal.h"
#include <ctype.h> // toupper, isprint #include <ctype.h> // toupper
#include <stdio.h> // vsnprintf, sscanf, printf #include <stdio.h> // vsnprintf, sscanf, printf
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier #if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
#include <stddef.h> // intptr_t #include <stddef.h> // intptr_t

@ -19,7 +19,7 @@ Index of this file:
// Misc data structures (ImGuiInputTextCallbackData, ImGuiSizeCallbackData, ImGuiPayload, ImGuiWindowClass) // Misc data structures (ImGuiInputTextCallbackData, ImGuiSizeCallbackData, ImGuiPayload, ImGuiWindowClass)
// Obsolete functions // Obsolete functions
// Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, ImColor) // Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, ImColor)
// Draw List API (ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListFlags, ImDrawList, ImDrawData) // Draw List API (ImDrawCallback, ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListFlags, ImDrawList, ImDrawData)
// Font API (ImFontConfig, ImFontGlyph, ImFontGlyphRangesBuilder, ImFontAtlasFlags, ImFontAtlas, ImFont) // Font API (ImFontConfig, ImFontGlyph, ImFontGlyphRangesBuilder, ImFontAtlasFlags, ImFontAtlas, ImFont)
// Platform interface for multi-viewport support (ImGuiPlatformMonitor, ImGuiPlatformIO, ImGuiViewport) // Platform interface for multi-viewport support (ImGuiPlatformMonitor, ImGuiPlatformIO, ImGuiViewport)

@ -50,7 +50,7 @@ Index of this file:
#endif #endif
#include "imgui.h" #include "imgui.h"
#include <ctype.h> // toupper, isprint #include <ctype.h> // toupper
#include <limits.h> // INT_MIN, INT_MAX #include <limits.h> // INT_MIN, INT_MAX
#include <math.h> // sqrtf, powf, cosf, sinf, floorf, ceilf #include <math.h> // sqrtf, powf, cosf, sinf, floorf, ceilf
#include <stdio.h> // vsnprintf, sscanf, printf #include <stdio.h> // vsnprintf, sscanf, printf
@ -1601,7 +1601,7 @@ static void ShowDemoWindowWidgets()
"IsItemEdited() = %d\n" "IsItemEdited() = %d\n"
"IsItemActivated() = %d\n" "IsItemActivated() = %d\n"
"IsItemDeactivated() = %d\n" "IsItemDeactivated() = %d\n"
"IsItemDeactivatedEdit() = %d\n" "IsItemDeactivatedAfterEdit() = %d\n"
"IsItemVisible() = %d\n" "IsItemVisible() = %d\n"
"GetItemRectMin() = (%.1f, %.1f)\n" "GetItemRectMin() = (%.1f, %.1f)\n"
"GetItemRectMax() = (%.1f, %.1f)\n" "GetItemRectMax() = (%.1f, %.1f)\n"
@ -2630,6 +2630,7 @@ static void ShowDemoWindowMisc()
ImGui::Text("Keys pressed:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyPressed(i)) { ImGui::SameLine(); ImGui::Text("%d (0x%X)", i, i); } ImGui::Text("Keys pressed:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyPressed(i)) { ImGui::SameLine(); ImGui::Text("%d (0x%X)", i, i); }
ImGui::Text("Keys release:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyReleased(i)) { ImGui::SameLine(); ImGui::Text("%d (0x%X)", i, i); } ImGui::Text("Keys release:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyReleased(i)) { ImGui::SameLine(); ImGui::Text("%d (0x%X)", i, i); }
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("NavInputs down:"); for (int i = 0; i < IM_ARRAYSIZE(io.NavInputs); i++) if (io.NavInputs[i] > 0.0f) { ImGui::SameLine(); ImGui::Text("[%d] %.2f", i, io.NavInputs[i]); } ImGui::Text("NavInputs down:"); for (int i = 0; i < IM_ARRAYSIZE(io.NavInputs); i++) if (io.NavInputs[i] > 0.0f) { ImGui::SameLine(); ImGui::Text("[%d] %.2f", i, io.NavInputs[i]); }
ImGui::Text("NavInputs pressed:"); for (int i = 0; i < IM_ARRAYSIZE(io.NavInputs); i++) if (io.NavInputsDownDuration[i] == 0.0f) { ImGui::SameLine(); ImGui::Text("[%d]", i); } ImGui::Text("NavInputs pressed:"); for (int i = 0; i < IM_ARRAYSIZE(io.NavInputs); i++) if (io.NavInputsDownDuration[i] == 0.0f) { ImGui::SameLine(); ImGui::Text("[%d]", i); }

@ -73,6 +73,7 @@ Index of this file:
#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
#if __GNUC__ >= 8 #if __GNUC__ >= 8
#pragma GCC diagnostic ignored "-Wclass-memaccess" // 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" // warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
#endif #endif
@ -2473,7 +2474,7 @@ void ImFont::BuildLookupTable()
ImFontGlyph& tab_glyph = Glyphs.back(); ImFontGlyph& tab_glyph = Glyphs.back();
tab_glyph = *FindGlyph((ImWchar)' '); tab_glyph = *FindGlyph((ImWchar)' ');
tab_glyph.Codepoint = '\t'; tab_glyph.Codepoint = '\t';
tab_glyph.AdvanceX *= 4; tab_glyph.AdvanceX *= IM_TABSIZE;
IndexAdvanceX[(int)tab_glyph.Codepoint] = (float)tab_glyph.AdvanceX; IndexAdvanceX[(int)tab_glyph.Codepoint] = (float)tab_glyph.AdvanceX;
IndexLookup[(int)tab_glyph.Codepoint] = (ImWchar)(Glyphs.Size-1); IndexLookup[(int)tab_glyph.Codepoint] = (ImWchar)(Glyphs.Size-1);
} }

@ -136,6 +136,7 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit ImGui context pointe
#else #else
#define IM_NEWLINE "\n" #define IM_NEWLINE "\n"
#endif #endif
#define IM_TABSIZE (4)
#define IMGUI_DEBUG_LOG(_FMT,...) printf("[%05d] " _FMT, GImGui->FrameCount, __VA_ARGS__) #define IMGUI_DEBUG_LOG(_FMT,...) printf("[%05d] " _FMT, GImGui->FrameCount, __VA_ARGS__)
#define IM_STATIC_ASSERT(_COND) typedef char static_assertion_##__line__[(_COND)?1:-1] #define IM_STATIC_ASSERT(_COND) typedef char static_assertion_##__line__[(_COND)?1:-1]

@ -37,7 +37,7 @@ Index of this file:
#endif #endif
#include "imgui_internal.h" #include "imgui_internal.h"
#include <ctype.h> // toupper, isprint #include <ctype.h> // toupper
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier #if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
#include <stddef.h> // intptr_t #include <stddef.h> // intptr_t
#else #else
@ -3170,7 +3170,8 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f
{ {
unsigned int c = *p_char; unsigned int c = *p_char;
if (c < 128 && c != ' ' && !isprint((int)(c & 0xFF))) // Filter non-printable (NB: isprint is unreliable! see #2467)
if (c < 0x20)
{ {
bool pass = false; bool pass = false;
pass |= (c == '\n' && (flags & ImGuiInputTextFlags_Multiline)); pass |= (c == '\n' && (flags & ImGuiInputTextFlags_Multiline));
@ -3179,9 +3180,11 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f
return false; return false;
} }
if (c >= 0xE000 && c <= 0xF8FF) // Filter private Unicode range. I don't imagine anybody would want to input them. GLFW on OSX seems to send private characters for special keys like arrow keys. // Filter private Unicode range. GLFW on OSX seems to send private characters for special keys like arrow keys (FIXME)
if (c >= 0xE000 && c <= 0xF8FF)
return false; return false;
// Generic named filters
if (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_CharsScientific)) if (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_CharsScientific))
{ {
if (flags & ImGuiInputTextFlags_CharsDecimal) if (flags & ImGuiInputTextFlags_CharsDecimal)
@ -3205,6 +3208,7 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f
return false; return false;
} }
// Custom callback filter
if (flags & ImGuiInputTextFlags_CallbackCharFilter) if (flags & ImGuiInputTextFlags_CallbackCharFilter)
{ {
ImGuiInputTextCallbackData callback_data; ImGuiInputTextCallbackData callback_data;
@ -3360,7 +3364,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
FocusWindow(window); FocusWindow(window);
IM_ASSERT(ImGuiNavInput_COUNT < 32); IM_ASSERT(ImGuiNavInput_COUNT < 32);
g.ActiveIdBlockNavInputFlags = (1 << ImGuiNavInput_Cancel); g.ActiveIdBlockNavInputFlags = (1 << ImGuiNavInput_Cancel);
if (flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_AllowTabInput)) // Disable keyboard tabbing out if (flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_AllowTabInput)) // Disable keyboard tabbing out as we will use the \t character.
g.ActiveIdBlockNavInputFlags |= (1 << ImGuiNavInput_KeyTab_); g.ActiveIdBlockNavInputFlags |= (1 << ImGuiNavInput_KeyTab_);
if (!is_multiline && !(flags & ImGuiInputTextFlags_CallbackHistory)) if (!is_multiline && !(flags & ImGuiInputTextFlags_CallbackHistory))
g.ActiveIdAllowNavDirFlags = ((1 << ImGuiDir_Up) | (1 << ImGuiDir_Down)); g.ActiveIdAllowNavDirFlags = ((1 << ImGuiDir_Up) | (1 << ImGuiDir_Down));
@ -3462,16 +3466,28 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
if (state->SelectedAllMouseLock && !io.MouseDown[0]) if (state->SelectedAllMouseLock && !io.MouseDown[0])
state->SelectedAllMouseLock = false; state->SelectedAllMouseLock = false;
if (io.InputQueueCharacters.Size > 0) // It is ill-defined whether the back-end needs to send a \t character when pressing the TAB keys.
// Win32 and GLFW naturally do it but not SDL.
const bool ignore_char_inputs = (io.KeyCtrl && !io.KeyAlt) || (is_osx && io.KeySuper);
if ((flags & ImGuiInputTextFlags_AllowTabInput) && IsKeyPressedMap(ImGuiKey_Tab) && !ignore_char_inputs && !io.KeyShift && !is_readonly)
if (!io.InputQueueCharacters.contains('\t'))
{ {
// Process text input (before we check for Return because using some IME will effectively send a Return?) unsigned int c = '\t'; // Insert TAB
if (InputTextFilterCharacter(&c, flags, callback, callback_user_data))
state->OnKeyPressed((int)c);
}
// Process regular text input (before we check for Return because using some IME will effectively send a Return?)
// We ignore CTRL inputs, but need to allow ALT+CTRL as some keyboards (e.g. German) use AltGR (which _is_ Alt+Ctrl) to input certain characters. // We ignore CTRL inputs, but need to allow ALT+CTRL as some keyboards (e.g. German) use AltGR (which _is_ Alt+Ctrl) to input certain characters.
bool ignore_inputs = (io.KeyCtrl && !io.KeyAlt) || (is_osx && io.KeySuper); if (io.InputQueueCharacters.Size > 0)
if (!ignore_inputs && !is_readonly && !user_nav_input_start) {
if (!ignore_char_inputs && !is_readonly && !user_nav_input_start)
for (int n = 0; n < io.InputQueueCharacters.Size; n++) for (int n = 0; n < io.InputQueueCharacters.Size; n++)
{ {
// Insert character if they pass filtering // Insert character if they pass filtering
unsigned int c = (unsigned int)io.InputQueueCharacters[n]; unsigned int c = (unsigned int)io.InputQueueCharacters[n];
if (c == '\t' && io.KeyShift)
continue;
if (InputTextFilterCharacter(&c, flags, callback, callback_user_data)) if (InputTextFilterCharacter(&c, flags, callback, callback_user_data))
state->OnKeyPressed((int)c); state->OnKeyPressed((int)c);
} }
@ -3533,12 +3549,6 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
state->OnKeyPressed((int)c); state->OnKeyPressed((int)c);
} }
} }
else if ((flags & ImGuiInputTextFlags_AllowTabInput) && IsKeyPressedMap(ImGuiKey_Tab) && !io.KeyCtrl && !io.KeyShift && !io.KeyAlt && !is_readonly)
{
unsigned int c = '\t'; // Insert TAB
if (InputTextFilterCharacter(&c, flags, callback, callback_user_data))
state->OnKeyPressed((int)c);
}
else if (IsKeyPressedMap(ImGuiKey_Escape)) else if (IsKeyPressedMap(ImGuiKey_Escape))
{ {
clear_active_id = cancel_edit = true; clear_active_id = cancel_edit = true;

@ -43,7 +43,8 @@ while (true)
if (freetype_test.UpdateRebuild()) if (freetype_test.UpdateRebuild())
{ {
// REUPLOAD FONT TEXTURE TO GPU // REUPLOAD FONT TEXTURE TO GPU
// e.g ImGui_ImplOpenGL3_DestroyDeviceObjects() + ImGui_ImplOpenGL3_CreateDeviceObjects() ImGui_ImplXXX_DestroyDeviceObjects();
ImGui_ImplXXX_CreateDeviceObjects();
} }
ImGui::NewFrame(); ImGui::NewFrame();
freetype_test.ShowFreetypeOptionsWindow(); freetype_test.ShowFreetypeOptionsWindow();
@ -85,10 +86,10 @@ struct FreeTypeTest
if (!WantRebuild) if (!WantRebuild)
return false; return false;
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
for (int n = 0; n < io.Fonts->Fonts.Size; n++)
{
ImFontConfig* font_config = (ImFontConfig*)io.Fonts->Fonts[n]->ConfigData;
io.Fonts->TexGlyphPadding = FontsPadding; io.Fonts->TexGlyphPadding = FontsPadding;
for (int n = 0; n < io.Fonts->ConfigData.Size; n++)
{
ImFontConfig* font_config = (ImFontConfig*)&io.Fonts->ConfigData[n];
font_config->RasterizerMultiply = FontsMultiply; font_config->RasterizerMultiply = FontsMultiply;
font_config->RasterizerFlags = (BuildMode == FontBuildMode_FreeType) ? FontsFlags : 0x00; font_config->RasterizerFlags = (BuildMode == FontBuildMode_FreeType) ? FontsFlags : 0x00;
} }

Loading…
Cancel
Save