mirror of
https://github.com/ocornut/imgui.git
synced 2025-09-08 20:38:25 +00:00
Merge branch 'master' into docking
# Conflicts: # backends/imgui_impl_opengl2.cpp # backends/imgui_impl_opengl3.cpp # imgui.cpp
This commit is contained in:
83
.github/workflows/build.yml
vendored
83
.github/workflows/build.yml
vendored
@@ -27,9 +27,13 @@ jobs:
|
||||
- name: Install Dependencies
|
||||
shell: powershell
|
||||
run: |
|
||||
Invoke-WebRequest -Uri "https://www.libsdl.org/release/SDL2-devel-2.26.3-VC.zip" -OutFile "SDL2-devel-2.26.3-VC.zip"
|
||||
Expand-Archive -Path SDL2-devel-2.26.3-VC.zip
|
||||
echo "SDL2_DIR=$(pwd)\SDL2-devel-2.26.3-VC\SDL2-2.26.3\" >>${env:GITHUB_ENV}
|
||||
Invoke-WebRequest -Uri "https://www.libsdl.org/release/SDL2-devel-2.32.8-VC.zip" -OutFile "SDL2-devel-2.32.8-VC.zip"
|
||||
Expand-Archive -Path SDL2-devel-2.32.8-VC.zip
|
||||
echo "SDL2_DIR=$(pwd)\SDL2-devel-2.32.8-VC\SDL2-2.32.8\" >>${env:GITHUB_ENV}
|
||||
|
||||
Invoke-WebRequest -Uri "https://www.libsdl.org/release/SDL3-devel-3.2.18-VC.zip" -OutFile "SDL3-devel-3.2.18-VC.zip"
|
||||
Expand-Archive -Path SDL3-devel-3.2.18-VC.zip
|
||||
echo "SDL3_DIR=$(pwd)\SDL3-devel-3.2.18-VC\SDL3-3.2.18\" >>${env:GITHUB_ENV}
|
||||
|
||||
Invoke-WebRequest -Uri "https://github.com/ocornut/imgui/files/3789205/vulkan-sdk-1.1.121.2.zip" -OutFile vulkan-sdk-1.1.121.2.zip
|
||||
Expand-Archive -Path vulkan-sdk-1.1.121.2.zip
|
||||
@@ -102,9 +106,12 @@ jobs:
|
||||
cl.exe /D_USRDLL /D_WINDLL /I. example_single_file.cpp /LD /FeImGui.dll /link
|
||||
cl.exe /DIMGUI_API=__declspec(dllimport) /I. ImGui.lib /Feexample_null.exe examples/example_null/main.cpp
|
||||
|
||||
# Win64 examples are more frequently compilted than the Win32 examples.
|
||||
# More of the Win32 examples requires 'workflow_run' to reduce waste.
|
||||
- name: Build Win32 example_glfw_opengl2
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build Win32 example_glfw_opengl3
|
||||
shell: cmd
|
||||
@@ -140,72 +147,111 @@ jobs:
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build Win32 example_sdl3_opengl3
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_opengl3/example_sdl3_opengl3.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||
|
||||
- name: Build Win32 example_sdl3_sdlgpu3
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_sdlgpu3/example_sdl3_sdlgpu3.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build Win32 example_sdl3_sdlrenderer3
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_sdlrenderer3/example_sdl3_sdlrenderer3.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build Win32 example_sdl3_vulkan
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_vulkan/example_sdl3_vulkan.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build Win32 example_win32_directx9
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx9/example_win32_directx9.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build Win32 example_win32_directx10
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx10/example_win32_directx10.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build Win32 example_win32_directx11
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx11/example_win32_directx11.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build x64 example_glfw_opengl2
|
||||
# Windows 64-bits
|
||||
- name: Build Win64 example_glfw_opengl2
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build x64 example_glfw_opengl3
|
||||
- name: Build Win64 example_glfw_opengl3
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
|
||||
- name: Build x64 example_glfw_vulkan
|
||||
- name: Build Win64 example_glfw_vulkan
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
|
||||
- name: Build x64 example_sdl2_sdlrenderer2
|
||||
- name: Build Win64 example_sdl2_sdlrenderer2
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build x64 example_sdl2_vulkan
|
||||
- name: Build Win64 example_sdl2_vulkan
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build x64 example_sdl2_opengl2
|
||||
- name: Build Win64 example_sdl2_opengl2
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_opengl2/example_sdl2_opengl2.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build x64 example_sdl2_opengl3
|
||||
- name: Build Win64 example_sdl2_opengl3
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_opengl3/example_sdl2_opengl3.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build x64 example_sdl2_directx11
|
||||
- name: Build Win64 example_sdl2_directx11
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
|
||||
- name: Build x64 example_win32_directx9
|
||||
- name: Build Win64 example_sdl3_opengl3
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_opengl3/example_sdl3_opengl3.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build Win64 example_sdl3_sdlgpu3
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_sdlgpu3/example_sdl3_sdlgpu3.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
|
||||
- name: Build Win64 example_sdl3_sdlrenderer3
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_sdlrenderer3/example_sdl3_sdlrenderer3.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
|
||||
- name: Build Win64 example_sdl3_vulkan
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_vulkan/example_sdl3_vulkan.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build Win64 example_win32_directx9
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx9/example_win32_directx9.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build x64 example_win32_directx10
|
||||
- name: Build Win64 example_win32_directx10
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx10/example_win32_directx10.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build x64 example_win32_directx11
|
||||
- name: Build Win64 example_win32_directx11
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx11/example_win32_directx11.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build x64 example_win32_directx12
|
||||
- name: Build Win64 example_win32_directx12
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx12/example_win32_directx12.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
|
||||
@@ -433,7 +479,7 @@ jobs:
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
brew install glfw3 sdl2
|
||||
brew install glfw3 sdl2 sdl3
|
||||
|
||||
- name: Build example_null (extra warnings, clang 64-bit)
|
||||
run: make -C examples/example_null WITH_EXTRA_WARNINGS=1
|
||||
@@ -491,6 +537,9 @@ jobs:
|
||||
- name: Build example_sdl2_opengl3
|
||||
run: make -C examples/example_sdl2_opengl3
|
||||
|
||||
- name: Build example_sdl3_opengl3
|
||||
run: make -C examples/example_sdl3_opengl3
|
||||
|
||||
- name: Build example_apple_metal
|
||||
run: xcodebuild -project examples/example_apple_metal/example_apple_metal.xcodeproj -target example_apple_metal_macos
|
||||
|
||||
|
@@ -161,10 +161,8 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
||||
ImGui_ImplAllegro5_SetupRenderState(draw_data);
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
|
||||
ImVector<ImDrawVertAllegro>& vertices = bd->BufVertices;
|
||||
#if ALLEGRO_HAS_DRAW_INDEXED_PRIM
|
||||
vertices.resize(draw_list->VtxBuffer.Size);
|
||||
|
@@ -206,9 +206,8 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
||||
ImDrawIdx* idx_dst = nullptr;
|
||||
bd->pVB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&vtx_dst);
|
||||
bd->pIB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&idx_dst);
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
@@ -274,9 +273,8 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
||||
int global_idx_offset = 0;
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
|
@@ -216,9 +216,8 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||
return;
|
||||
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData;
|
||||
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
@@ -290,9 +289,8 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||
int global_vtx_offset = 0;
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
|
@@ -339,9 +339,8 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
||||
return;
|
||||
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource;
|
||||
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
@@ -372,9 +371,8 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
||||
int global_idx_offset = 0;
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
|
@@ -236,9 +236,8 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
||||
// FIXME-OPT: This is a minor waste of resource, the ideal is to use imconfig.h and
|
||||
// 1) to avoid repacking colors: #define IMGUI_USE_BGRA_PACKED_COLOR
|
||||
// 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 (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_src = draw_list->VtxBuffer.Data;
|
||||
for (int i = 0; i < draw_list->VtxBuffer.Size; i++)
|
||||
{
|
||||
@@ -268,9 +267,8 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
||||
int global_vtx_offset = 0;
|
||||
int global_idx_offset = 0;
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
|
@@ -235,7 +235,7 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id<MTLCommandBuffer>
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdListsCount == 0)
|
||||
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdLists.Size == 0)
|
||||
return;
|
||||
|
||||
// Catch up with texture updates. Most of the times, the list will have 1 element with an OK status, aka nothing to do.
|
||||
@@ -271,10 +271,8 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id<MTLCommandBuffer>
|
||||
// Render command lists
|
||||
size_t vertexBufferOffset = 0;
|
||||
size_t indexBufferOffset = 0;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
|
||||
memcpy((char*)vertexBuffer.buffer.contents + vertexBufferOffset, draw_list->VtxBuffer.Data, (size_t)draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy((char*)indexBuffer.buffer.contents + indexBufferOffset, draw_list->IdxBuffer.Data, (size_t)draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
|
||||
|
@@ -27,6 +27,7 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-07-15: OpenGL: Set GL_UNPACK_ALIGNMENT to 1 before updating textures. (#8802)
|
||||
// 2025-06-11: OpenGL: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. Removed ImGui_ImplOpenGL2_CreateFontsTexture() and ImGui_ImplOpenGL2_DestroyFontsTexture().
|
||||
// 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)
|
||||
@@ -218,9 +219,8 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, pos)));
|
||||
@@ -296,6 +296,7 @@ void ImGui_ImplOpenGL2_UpdateTexture(ImTextureData* tex)
|
||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP));
|
||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP));
|
||||
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
|
||||
GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
|
||||
GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->Width, tex->Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
|
||||
|
||||
// Store identifiers
|
||||
@@ -315,6 +316,7 @@ void ImGui_ImplOpenGL2_UpdateTexture(ImTextureData* tex)
|
||||
GLuint gl_tex_id = (GLuint)(intptr_t)tex->TexID;
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_2D, gl_tex_id));
|
||||
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, tex->Width));
|
||||
GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
|
||||
for (ImTextureRect& r : tex->Updates)
|
||||
GL_CALL(glTexSubImage2D(GL_TEXTURE_2D, 0, r.x, r.y, r.w, r.h, GL_RGBA, GL_UNSIGNED_BYTE, tex->GetPixelsAt(r.x, r.y)));
|
||||
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
|
||||
|
@@ -25,6 +25,8 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-07-22: OpenGL: Add and call embedded loader shutdown during ImGui_ImplOpenGL3_Shutdown() to facilitate multiple init/shutdown cycles in same process. (#8792)
|
||||
// 2025-07-15: OpenGL: Set GL_UNPACK_ALIGNMENT to 1 before updating textures (#8802) + restore non-WebGL/ES update path that doesn't require a CPU-side copy.
|
||||
// 2025-06-11: OpenGL: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. Removed ImGui_ImplOpenGL3_CreateFontsTexture() and ImGui_ImplOpenGL3_DestroyFontsTexture().
|
||||
// 2025-06-04: OpenGL: Made GLES 3.20 contexts not access GL_CONTEXT_PROFILE_MASK nor GL_PRIMITIVE_RESTART. (#8664)
|
||||
// 2025-02-18: OpenGL: Lazily reinitialize embedded GL loader for when calling backend from e.g. other DLL boundaries. (#8406)
|
||||
@@ -431,6 +433,10 @@ void ImGui_ImplOpenGL3_Shutdown()
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
||||
IM_DELETE(bd);
|
||||
|
||||
#ifdef IMGUI_IMPL_OPENGL_LOADER_IMGL3W
|
||||
imgl3wShutdown();
|
||||
#endif
|
||||
}
|
||||
|
||||
void ImGui_ImplOpenGL3_NewFrame()
|
||||
@@ -594,10 +600,8 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
|
||||
// Upload vertex/index buffers
|
||||
// - OpenGL drivers are in a very sorry state nowadays....
|
||||
// During 2021 we attempted to switch from glBufferData() to orphaning+glBufferSubData() following reports
|
||||
@@ -721,6 +725,17 @@ static void ImGui_ImplOpenGL3_DestroyTexture(ImTextureData* tex)
|
||||
|
||||
void ImGui_ImplOpenGL3_UpdateTexture(ImTextureData* tex)
|
||||
{
|
||||
// FIXME: Consider backing up and restoring
|
||||
if (tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantUpdates)
|
||||
{
|
||||
#ifdef GL_UNPACK_ROW_LENGTH // Not on WebGL/ES
|
||||
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
|
||||
#endif
|
||||
#ifdef GL_UNPACK_ALIGNMENT
|
||||
GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
|
||||
#endif
|
||||
}
|
||||
|
||||
if (tex->Status == ImTextureStatus_WantCreate)
|
||||
{
|
||||
// Create and upload new texture to graphics system
|
||||
@@ -740,9 +755,6 @@ void ImGui_ImplOpenGL3_UpdateTexture(ImTextureData* tex)
|
||||
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
|
||||
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
|
||||
#endif
|
||||
GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->Width, tex->Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
|
||||
|
||||
// Store identifiers
|
||||
@@ -761,7 +773,7 @@ void ImGui_ImplOpenGL3_UpdateTexture(ImTextureData* tex)
|
||||
|
||||
GLuint gl_tex_id = (GLuint)(intptr_t)tex->TexID;
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_2D, gl_tex_id));
|
||||
#if 0// GL_UNPACK_ROW_LENGTH // Not on WebGL/ES
|
||||
#if GL_UNPACK_ROW_LENGTH // Not on WebGL/ES
|
||||
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, tex->Width));
|
||||
for (ImTextureRect& r : tex->Updates)
|
||||
GL_CALL(glTexSubImage2D(GL_TEXTURE_2D, 0, r.x, r.y, r.w, r.h, GL_RGBA, GL_UNSIGNED_BYTE, tex->GetPixelsAt(r.x, r.y)));
|
||||
|
@@ -166,6 +166,7 @@ typedef khronos_uint8_t GLubyte;
|
||||
#define GL_SCISSOR_BOX 0x0C10
|
||||
#define GL_SCISSOR_TEST 0x0C11
|
||||
#define GL_UNPACK_ROW_LENGTH 0x0CF2
|
||||
#define GL_UNPACK_ALIGNMENT 0x0CF5
|
||||
#define GL_PACK_ALIGNMENT 0x0D05
|
||||
#define GL_MAX_TEXTURE_SIZE 0x0D33
|
||||
#define GL_TEXTURE_2D 0x0DE1
|
||||
@@ -476,6 +477,7 @@ typedef GL3WglProc (*GL3WGetProcAddressProc)(const char *proc);
|
||||
/* gl3w api */
|
||||
GL3W_API int imgl3wInit(void);
|
||||
GL3W_API int imgl3wInit2(GL3WGetProcAddressProc proc);
|
||||
GL3W_API void imgl3wShutdown(void);
|
||||
GL3W_API int imgl3wIsSupported(int major, int minor);
|
||||
GL3W_API GL3WglProc imgl3wGetProcAddress(const char *proc);
|
||||
|
||||
@@ -631,7 +633,7 @@ extern "C" {
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
static HMODULE libgl;
|
||||
static HMODULE libgl = NULL;
|
||||
typedef PROC(__stdcall* GL3WglGetProcAddr)(LPCSTR);
|
||||
static GL3WglGetProcAddr wgl_get_proc_address;
|
||||
|
||||
@@ -644,7 +646,7 @@ static int open_libgl(void)
|
||||
return GL3W_OK;
|
||||
}
|
||||
|
||||
static void close_libgl(void) { FreeLibrary(libgl); }
|
||||
static void close_libgl(void) { FreeLibrary(libgl); libgl = NULL; }
|
||||
static GL3WglProc get_proc(const char *proc)
|
||||
{
|
||||
GL3WglProc res;
|
||||
@@ -656,7 +658,7 @@ static GL3WglProc get_proc(const char *proc)
|
||||
#elif defined(__APPLE__)
|
||||
#include <dlfcn.h>
|
||||
|
||||
static void *libgl;
|
||||
static void *libgl = NULL;
|
||||
static int open_libgl(void)
|
||||
{
|
||||
libgl = dlopen("/System/Library/Frameworks/OpenGL.framework/OpenGL", RTLD_LAZY | RTLD_LOCAL);
|
||||
@@ -665,7 +667,7 @@ static int open_libgl(void)
|
||||
return GL3W_OK;
|
||||
}
|
||||
|
||||
static void close_libgl(void) { dlclose(libgl); }
|
||||
static void close_libgl(void) { dlclose(libgl); libgl = NULL; }
|
||||
|
||||
static GL3WglProc get_proc(const char *proc)
|
||||
{
|
||||
@@ -833,6 +835,11 @@ int imgl3wInit2(GL3WGetProcAddressProc proc)
|
||||
return parse_version();
|
||||
}
|
||||
|
||||
void imgl3wShutdown(void)
|
||||
{
|
||||
close_libgl();
|
||||
}
|
||||
|
||||
int imgl3wIsSupported(int major, int minor)
|
||||
{
|
||||
if (major < 2)
|
||||
|
@@ -182,9 +182,8 @@ void ImGui_ImplSDLGPU3_PrepareDrawData(ImDrawData* draw_data, SDL_GPUCommandBuff
|
||||
|
||||
ImDrawVert* vtx_dst = (ImDrawVert*)SDL_MapGPUTransferBuffer(v->Device, fd->VertexTransferBuffer, true);
|
||||
ImDrawIdx* idx_dst = (ImDrawIdx*)SDL_MapGPUTransferBuffer(v->Device, fd->IndexTransferBuffer, true);
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
@@ -240,9 +239,8 @@ void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffe
|
||||
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||
int global_vtx_offset = 0;
|
||||
int global_idx_offset = 0;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
|
@@ -171,9 +171,8 @@ void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
||||
ImVec2 clip_scale = render_scale;
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
|
||||
|
||||
|
@@ -191,9 +191,8 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
||||
ImVec2 clip_scale = render_scale;
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
|
||||
|
||||
|
@@ -579,9 +579,8 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
||||
check_vk_result(err);
|
||||
err = vkMapMemory(v->Device, rb->IndexBufferMemory, 0, index_size, 0, (void**)&idx_dst);
|
||||
check_vk_result(err);
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
@@ -619,9 +618,8 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
||||
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||
int global_vtx_offset = 0;
|
||||
int global_idx_offset = 0;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
|
@@ -369,7 +369,7 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
||||
// Avoid rendering when minimized
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdListsCount == 0)
|
||||
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdLists.Size == 0)
|
||||
return;
|
||||
|
||||
// Catch up with texture updates. Most of the times, the list will have 1 element with an OK status, aka nothing to do.
|
||||
@@ -444,9 +444,8 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
||||
// Upload vertex/index data into a single contiguous GPU buffer
|
||||
ImDrawVert* vtx_dst = (ImDrawVert*)fr->VertexBufferHost;
|
||||
ImDrawIdx* idx_dst = (ImDrawIdx*)fr->IndexBufferHost;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
@@ -473,9 +472,8 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
||||
int global_idx_offset = 0;
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale;
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
|
@@ -245,9 +245,8 @@ void MyImGuiBackend_RenderDrawData(ImDrawData* draw_data)
|
||||
// Render command lists
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; // vertex buffer generated by Dear ImGui
|
||||
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; // index buffer generated by Dear ImGui
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
|
@@ -35,6 +35,29 @@ HOW TO UPDATE?
|
||||
and API updates have been a little more frequent lately. They are documented below and in imgui.cpp and should not affect all users.
|
||||
- Please report any issue!
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.92.2 WIP (In Progress)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Breaking Changes:
|
||||
|
||||
Other Changes:
|
||||
|
||||
- Windows: fixed an issue where resizable child windows would emit border
|
||||
logic when hidden/non-visible (e.g. when in a docked window that is not
|
||||
selected), impacting code not checking for BeginChild() return value. (#8815)
|
||||
- Error Handling: minor improvements to error handling for TableGetSortSpecs()
|
||||
and TableSetBgColor() calls. (#1651, #8499)
|
||||
- Misc: removed more redundant inline static linkage from imgui_internal.h to
|
||||
facilitate using in C++ modules. (#8813, #8682, #8358) [@stripe2933]
|
||||
- CI: Added SDL3 builds to MacOS and Windows. (#8819, #8778) [@scribam]
|
||||
- CI: Updated Windows CI to use a more recent SDL2. (#8819, #8778) [@scribam]
|
||||
- Backends: OpenGL3: add and call embedded loader shutdown in ImGui_ImplOpenGL3_Shutdown()
|
||||
to facilitate multiple init/shutdown cycles in same process. (#8792) [@tim-rex]
|
||||
- Backends: OpenGL2, OpenGL3: set GL_UNPACK_ALIGNMENT to 1 before updating
|
||||
textures. (#8802) [@Daandelange]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.92.1 (Released 2025-07-09)
|
||||
-----------------------------------------------------------------------
|
||||
@@ -64,13 +87,13 @@ Changes:
|
||||
- Debug Tools: added IMGUI_DEBUG_HIGHLIGHT_ALL_ID_CONFLICTS to detect
|
||||
id conflicts _before_ hovering. This is very slow and should only be used
|
||||
temporarily. (#8651, #7961, #7669)
|
||||
- Examples: GLFW+OpenGL3, GLFW+WGPU: Emscripten Makefiles uses GLFW port
|
||||
- Examples: GLFW+OpenGL3, GLFW+WGPU: Emscripten Makefiles uses GLFW port
|
||||
'contrib.glfw3' which offers better HiDPI support. (#8742) [@pthom]
|
||||
- Backends: GLFW, SDL2 made ImGui_ImplGLFW_GetContentScaleXXX() and
|
||||
ImGui_ImplSDL2_GetContentScaleXXXX() helpers return 1.0f on Emscripten
|
||||
- Backends: GLFW, SDL2 made ImGui_ImplGLFW_GetContentScaleXXX() and
|
||||
ImGui_ImplSDL2_GetContentScaleXXXX() helpers return 1.0f on Emscripten
|
||||
and Android platforms, matching macOS logic. (#8742, #8733) [@pthom]
|
||||
- Backends: SDL3: avoid calling SDL_StartTextInput() again if already active.
|
||||
(fixes e.g.: an issue on iOS where the keyboard animation will popup every
|
||||
(fixes e.g.: an issue on iOS where the keyboard animation will popup every
|
||||
time the user types a key + probably other things) (#8727) [@morrazzzz]
|
||||
- Backends: OSX: added ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress
|
||||
mouse cursor support. (#8739) [@cfillion]
|
||||
|
40
docs/FAQ.md
40
docs/FAQ.md
@@ -389,8 +389,8 @@ node open/closed state differently. See what makes more sense in your situation!
|
||||
### Q: What are ImTextureID/ImTextureRef?
|
||||
|
||||
**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).
|
||||
- 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.
|
||||
- To load and display your own textures, 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).
|
||||
- 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.
|
||||
- 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.
|
||||
@@ -398,12 +398,20 @@ node open/closed state differently. See what makes more sense in your situation!
|
||||
**Details:**
|
||||
|
||||
1.92 introduced `ImTextureRef` in June 2025.
|
||||
- Most drawing functions using ImTextureID were changed to use ImTextureRef.
|
||||
- We intentionally do not provide an implicit ImTextureRef -> ImTextureID cast operator because it is technically lossy to convert ImTextureRef to ImTextureID before rendering.
|
||||
- All drawing functions using `ImTextureID` were changed to use `ImTextureRef`.
|
||||
- You can trivially create a `ImTextureRef` from a `ImTextureID`.
|
||||
- **If you use Image functions with textures that you have loaded/created yourself, you will mostly likely only ever store/manipulate `ImTextureID` and then pass them as `ImTextureRef`.**
|
||||
- You only NEED to manipulate `ImTextureRef` when dealing with textures managed by the backend itself, aka mainly the atlas texture for now.
|
||||
- We intentionally do not provide an implicit `ImTextureRef` -> `ImTextureID` cast operator because it is technically lossy to convert ImTextureRef to ImTextureID before rendering.
|
||||
|
||||
**ImTextureID = backend specific, low-level identifier for a texture uploaded in GPU/graphics system.**
|
||||
```cpp
|
||||
#ifndef ImTextureID
|
||||
typedef ImU64 ImTextureID; // Default: store up to 64-bits (any pointer or integer). A majority of backends are ok with that.
|
||||
#endif
|
||||
```
|
||||
- When a Rendered Backend creates a texture, it store its native identifier into a ImTextureID value (e.g. Used by DX11 backend to a `ID3D11ShaderResourceView*`; Used by OpenGL backends to store `GLuint`; Used by SDLGPU backend to store a `SDL_GPUTextureSamplerBinding*`, etc.).
|
||||
- User may submit their own textures to e.g. ImGui::Image() function by passing the same type.
|
||||
- User may submit their own textures to e.g. `ImGui::Image()` function by passing this value.
|
||||
- During the rendering loop, the Renderer Backend retrieve the ImTextureID, which stored inside a ImTextureRef, which is stored inside ImDrawCmd.
|
||||
- Compile-time type configuration:
|
||||
- To use something other than a 64-bit value: add '#define ImTextureID MyTextureType*' in your imconfig.h file.
|
||||
@@ -411,13 +419,29 @@ node open/closed state differently. See what makes more sense in your situation!
|
||||
- You may decide to store a higher-level structure containing texture, sampler, shader etc. with various constructors if you like. You will need to implement ==/!= operators.
|
||||
|
||||
**ImTextureRef = higher-level identifier for a texture.**
|
||||
```cpp
|
||||
// Store a ImTextureID _or_ a ImTextureData*.
|
||||
struct ImTextureRef
|
||||
{
|
||||
ImTextureRef() { _TexData = NULL; _TexID = ImTextureID_Invalid; }
|
||||
ImTextureRef(ImTextureID tex_id) { _TexData = NULL; _TexID = tex_id; }
|
||||
inline ImTextureID GetTexID() const { return _TexData ? _TexData->TexID : _TexID; }
|
||||
|
||||
// Members (either are set, never both!)
|
||||
ImTextureData* _TexData; // A texture, generally owned by a ImFontAtlas. Will convert to ImTextureID during render loop, after texture has been uploaded.
|
||||
ImTextureID _TexID; // _OR_ Low-level backend texture identifier, if already uploaded or created by user/app. Generally provided to e.g. ImGui::Image() calls.
|
||||
};
|
||||
```
|
||||
- The identifier is valid even before the texture has been uploaded to the GPU/graphics system.
|
||||
- This is what gets passed to functions such as `ImGui::Image()`, `ImDrawList::AddImage()`.
|
||||
- This is what gets stored in draw commands (`ImDrawCmd`) to identify a texture during rendering.
|
||||
- When a texture is created by user code (e.g. custom images), we directly stores the low-level `ImTextureID`.
|
||||
- When a texture is created by the backend, we stores a `ImTextureData*` which becomes an indirection to extract the `ImTextureID` value during rendering, after texture upload has happened.
|
||||
- There is no constructor to create a `ImTextureID` from a `ImTextureData*` as we don't expect this to be useful to the end-user, and it would be erroneously called by many legacy code.
|
||||
- If you want to bind the current atlas when using custom rectangle, you can use `io.Fonts->TexRef`.
|
||||
- When a texture is created by user code (e.g. custom images), we directly store the low-level `ImTextureID`.
|
||||
- Because of this, when displaying your own texture you are likely to ever only manage ImTextureID values on your side.
|
||||
- When a texture is created by the backend, we store a `ImTextureData*` which becomes an indirection to extract the `ImTextureID` value during rendering, after texture upload has happened.
|
||||
- To create a `ImTextureRef` from a `ImTextureData*` you can use `ImTextureData::GetTexRef()`.
|
||||
We intentionally do not provide an `ImTextureRef` constructor for this: we don't expect this to be frequently useful to the end-user, and it would be erroneously called by many legacy code.
|
||||
- There is no constructor to create a `ImTextureRef` from a `ImTextureData*` as we don't expect this to be useful to the end-user, and it would be erroneously called by many legacy code.
|
||||
- If you want to bind the current atlas when using custom rectangles, you can use `io.Fonts->TexRef`.
|
||||
- Binding generators for languages such as C (which don't have constructors), should provide a helper, e.g. `inline ImTextureRef ImTextureRefFromID(ImTextureID tex_id) { ImTextureRef tex_ref = { ._TexData = NULL, .TexID = tex_id }; return tex_ref; }`
|
||||
|
||||
**Please read documentations or tutorials on your graphics API to understand how to display textures on the screen before moving onward.**
|
||||
|
@@ -16,7 +16,7 @@ Businesses: support continued development and maintenance via invoiced sponsorin
|
||||
| [The Pitch](#the-pitch) - [Usage](#usage) - [How it works](#how-it-works) - [Releases & Changelogs](#releases--changelogs) - [Demo](#demo) - [Getting Started & Integration](#getting-started--integration) |
|
||||
:----------------------------------------------------------: |
|
||||
| [Gallery](#gallery) - [Support, FAQ](#support-frequently-asked-questions-faq) - [How to help](#how-to-help) - **[Funding & Sponsors](https://github.com/ocornut/imgui/wiki/Funding)** - [Credits](#credits) - [License](#license) |
|
||||
| [Wiki](https://github.com/ocornut/imgui/wiki) - [Extensions](https://github.com/ocornut/imgui/wiki/Useful-Extensions) - [Languages bindings & frameworks backends](https://github.com/ocornut/imgui/wiki/Bindings) - [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) - [User quotes](https://github.com/ocornut/imgui/wiki/Quotes) |
|
||||
| [Wiki](https://github.com/ocornut/imgui/wiki) - [Extensions](https://github.com/ocornut/imgui/wiki/Useful-Extensions) - [Language bindings & framework backends](https://github.com/ocornut/imgui/wiki/Bindings) - [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) - [User quotes](https://github.com/ocornut/imgui/wiki/Quotes) |
|
||||
|
||||
### The Pitch
|
||||
|
||||
|
116
imgui.cpp
116
imgui.cpp
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.92.1
|
||||
// dear imgui, v1.92.2 WIP
|
||||
// (main code and documentation)
|
||||
|
||||
// Help:
|
||||
@@ -78,7 +78,7 @@ CODE
|
||||
// [SECTION] RENDER HELPERS
|
||||
// [SECTION] INITIALIZATION, SHUTDOWN
|
||||
// [SECTION] MAIN CODE (most of the code! lots of stuff, needs tidying up!)
|
||||
// [SECTION] FONTS
|
||||
// [SECTION] FONTS, TEXTURES
|
||||
// [SECTION] ID STACK
|
||||
// [SECTION] INPUTS
|
||||
// [SECTION] ERROR CHECKING, STATE RECOVERY
|
||||
@@ -2644,11 +2644,11 @@ static inline int ImTextCharToUtf8_inline(char* buf, int buf_size, unsigned int
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* ImTextCharToUtf8(char out_buf[5], unsigned int c)
|
||||
int ImTextCharToUtf8(char out_buf[5], unsigned int c)
|
||||
{
|
||||
int count = ImTextCharToUtf8_inline(out_buf, 5, c);
|
||||
out_buf[count] = 0;
|
||||
return out_buf;
|
||||
return count;
|
||||
}
|
||||
|
||||
// Not optimal but we very rarely use this function.
|
||||
@@ -5442,46 +5442,6 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags(const ImVec2& mouse_pos)
|
||||
io.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : false;
|
||||
}
|
||||
|
||||
static void ImGui::UpdateTexturesNewFrame()
|
||||
{
|
||||
// Cannot update every atlases based on atlas's FrameCount < g.FrameCount, because an atlas may be shared by multiple contexts with different frame count.
|
||||
ImGuiContext& g = *GImGui;
|
||||
const bool has_textures = (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasTextures) != 0;
|
||||
for (ImFontAtlas* atlas : g.FontAtlases)
|
||||
{
|
||||
if (atlas->OwnerContext == &g)
|
||||
{
|
||||
ImFontAtlasUpdateNewFrame(atlas, g.FrameCount, has_textures);
|
||||
}
|
||||
else
|
||||
{
|
||||
// (1) If you manage font atlases yourself, e.g. create a ImFontAtlas yourself you need to call ImFontAtlasUpdateNewFrame() on it.
|
||||
// Otherwise, calling ImGui::CreateContext() without parameter will create an atlas owned by the context.
|
||||
// (2) If you have multiple font atlases, make sure the 'atlas->RendererHasTextures' as specified in the ImFontAtlasUpdateNewFrame() call matches for that.
|
||||
// (3) If you have multiple imgui contexts, they also need to have a matching value for ImGuiBackendFlags_RendererHasTextures.
|
||||
IM_ASSERT(atlas->Builder != NULL && atlas->Builder->FrameCount != -1);
|
||||
IM_ASSERT(atlas->RendererHasTextures == has_textures);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build a single texture list
|
||||
static void ImGui::UpdateTexturesEndFrame()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.PlatformIO.Textures.resize(0);
|
||||
for (ImFontAtlas* atlas : g.FontAtlases)
|
||||
for (ImTextureData* tex : atlas->TexList)
|
||||
{
|
||||
// We provide this information so backends can decide whether to destroy textures.
|
||||
// This means in practice that if N imgui contexts are created with a shared atlas, we assume all of them have a backend initialized.
|
||||
tex->RefCount = (unsigned short)atlas->RefCount;
|
||||
g.PlatformIO.Textures.push_back(tex);
|
||||
}
|
||||
for (ImTextureData* tex : g.UserTextures)
|
||||
g.PlatformIO.Textures.push_back(tex);
|
||||
}
|
||||
|
||||
// Called once a frame. Followed by SetCurrentFont() which sets up the remaining data.
|
||||
// FIXME-VIEWPORT: the concept of a single ClipRectFullscreen is not ideal!
|
||||
static void SetupDrawListSharedData()
|
||||
@@ -8100,7 +8060,11 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
#endif
|
||||
|
||||
// Decide if we are going to handle borders and resize grips
|
||||
const bool handle_borders_and_resize_grips = (window->DockNodeAsHost || !window->DockIsActive);
|
||||
// 'window->SkipItems' is not updated yet so for child windows we rely on ParentWindow to avoid submitting decorations. (#8815)
|
||||
// Whenever we add support for full decorated child windows we will likely make this logic more general.
|
||||
bool handle_borders_and_resize_grips = (window->DockNodeAsHost || !window->DockIsActive);
|
||||
if ((flags & ImGuiWindowFlags_ChildWindow) && window->ParentWindow->SkipItems)
|
||||
handle_borders_and_resize_grips = false;
|
||||
|
||||
// Handle manual resize: Resize Grips, Borders, Gamepad
|
||||
int border_hovered = -1, border_held = -1;
|
||||
@@ -9282,11 +9246,13 @@ bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] FONTS
|
||||
// [SECTION] FONTS, TEXTURES
|
||||
//-----------------------------------------------------------------------------
|
||||
// Most of the relevant font logic is in imgui_draw.cpp.
|
||||
// Those are high-level support functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
// - UpdateTexturesNewFrame() [Internal]
|
||||
// - UpdateTexturesEndFrame() [Internal]
|
||||
// - UpdateFontsNewFrame() [Internal]
|
||||
// - UpdateFontsEndFrame() [Internal]
|
||||
// - GetDefaultFont() [Internal]
|
||||
@@ -9301,6 +9267,46 @@ bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max)
|
||||
// - PopFont()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void ImGui::UpdateTexturesNewFrame()
|
||||
{
|
||||
// Cannot update every atlases based on atlas's FrameCount < g.FrameCount, because an atlas may be shared by multiple contexts with different frame count.
|
||||
ImGuiContext& g = *GImGui;
|
||||
const bool has_textures = (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasTextures) != 0;
|
||||
for (ImFontAtlas* atlas : g.FontAtlases)
|
||||
{
|
||||
if (atlas->OwnerContext == &g)
|
||||
{
|
||||
ImFontAtlasUpdateNewFrame(atlas, g.FrameCount, has_textures);
|
||||
}
|
||||
else
|
||||
{
|
||||
// (1) If you manage font atlases yourself, e.g. create a ImFontAtlas yourself you need to call ImFontAtlasUpdateNewFrame() on it.
|
||||
// Otherwise, calling ImGui::CreateContext() without parameter will create an atlas owned by the context.
|
||||
// (2) If you have multiple font atlases, make sure the 'atlas->RendererHasTextures' as specified in the ImFontAtlasUpdateNewFrame() call matches for that.
|
||||
// (3) If you have multiple imgui contexts, they also need to have a matching value for ImGuiBackendFlags_RendererHasTextures.
|
||||
IM_ASSERT(atlas->Builder != NULL && atlas->Builder->FrameCount != -1);
|
||||
IM_ASSERT(atlas->RendererHasTextures == has_textures);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build a single texture list
|
||||
static void ImGui::UpdateTexturesEndFrame()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.PlatformIO.Textures.resize(0);
|
||||
for (ImFontAtlas* atlas : g.FontAtlases)
|
||||
for (ImTextureData* tex : atlas->TexList)
|
||||
{
|
||||
// We provide this information so backends can decide whether to destroy textures.
|
||||
// This means in practice that if N imgui contexts are created with a shared atlas, we assume all of them have a backend initialized.
|
||||
tex->RefCount = (unsigned short)atlas->RefCount;
|
||||
g.PlatformIO.Textures.push_back(tex);
|
||||
}
|
||||
for (ImTextureData* tex : g.UserTextures)
|
||||
g.PlatformIO.Textures.push_back(tex);
|
||||
}
|
||||
|
||||
void ImGui::UpdateFontsNewFrame()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@@ -9343,16 +9349,19 @@ ImFont* ImGui::GetDefaultFont()
|
||||
return g.IO.FontDefault ? g.IO.FontDefault : atlas->Fonts[0];
|
||||
}
|
||||
|
||||
// EXPERIMENTAL: DO NOT USE YET.
|
||||
void ImGui::RegisterUserTexture(ImTextureData* tex)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(tex->RefCount > 0);
|
||||
tex->RefCount++;
|
||||
g.UserTextures.push_back(tex);
|
||||
}
|
||||
|
||||
void ImGui::UnregisterUserTexture(ImTextureData* tex)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(tex->RefCount > 0);
|
||||
tex->RefCount--;
|
||||
g.UserTextures.find_erase(tex);
|
||||
}
|
||||
|
||||
@@ -13184,7 +13193,7 @@ bool ImGui::IsWindowFocused(ImGuiFocusedFlags flags)
|
||||
IM_ASSERT(cur_window); // Not inside a Begin()/End()
|
||||
const bool popup_hierarchy = (flags & ImGuiFocusedFlags_NoPopupHierarchy) == 0;
|
||||
const bool dock_hierarchy = (flags & ImGuiFocusedFlags_DockHierarchy) != 0;
|
||||
if (flags & ImGuiHoveredFlags_RootWindow)
|
||||
if (flags & ImGuiFocusedFlags_RootWindow)
|
||||
cur_window = GetCombinedRootWindow(cur_window, popup_hierarchy, dock_hierarchy);
|
||||
|
||||
if (flags & ImGuiHoveredFlags_ChildWindows)
|
||||
@@ -22759,8 +22768,10 @@ void ImGui::DebugNodeFont(ImFont* font)
|
||||
#endif
|
||||
|
||||
char c_str[5];
|
||||
Text("Fallback character: '%s' (U+%04X)", ImTextCharToUtf8(c_str, font->FallbackChar), font->FallbackChar);
|
||||
Text("Ellipsis character: '%s' (U+%04X)", ImTextCharToUtf8(c_str, font->EllipsisChar), font->EllipsisChar);
|
||||
ImTextCharToUtf8(c_str, font->FallbackChar);
|
||||
Text("Fallback character: '%s' (U+%04X)", c_str, font->FallbackChar);
|
||||
ImTextCharToUtf8(c_str, font->EllipsisChar);
|
||||
Text("Ellipsis character: '%s' (U+%04X)", c_str, font->EllipsisChar);
|
||||
|
||||
for (int src_n = 0; src_n < font->Sources.Size; src_n++)
|
||||
{
|
||||
@@ -22802,7 +22813,10 @@ void ImGui::DebugNodeFont(ImFont* font)
|
||||
{
|
||||
char utf8_buf[5];
|
||||
for (unsigned int n = c; n < c_end; n++)
|
||||
BulletText("Codepoint U+%04X (%s)", n, ImTextCharToUtf8(utf8_buf, n));
|
||||
{
|
||||
ImTextCharToUtf8(utf8_buf, n);
|
||||
BulletText("Codepoint U+%04X (%s)", n, utf8_buf);
|
||||
}
|
||||
TreePop();
|
||||
}
|
||||
TableNextColumn();
|
||||
|
22
imgui.h
22
imgui.h
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.92.1
|
||||
// dear imgui, v1.92.2 WIP
|
||||
// (headers)
|
||||
|
||||
// Help:
|
||||
@@ -28,8 +28,8 @@
|
||||
|
||||
// Library Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||
#define IMGUI_VERSION "1.92.1"
|
||||
#define IMGUI_VERSION_NUM 19210
|
||||
#define IMGUI_VERSION "1.92.2 WIP"
|
||||
#define IMGUI_VERSION_NUM 19212
|
||||
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
|
||||
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
|
||||
#define IMGUI_HAS_VIEWPORT // In 'docking' WIP branch.
|
||||
@@ -322,7 +322,7 @@ IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||
// - When a Rendered Backend creates a texture, it store its native identifier into a ImTextureID value.
|
||||
// (e.g. Used by DX11 backend to a `ID3D11ShaderResourceView*`; Used by OpenGL backends to store `GLuint`;
|
||||
// Used by SDLGPU backend to store a `SDL_GPUTextureSamplerBinding*`, etc.).
|
||||
// - User may submit their own textures to e.g. ImGui::Image() function by passing the same type.
|
||||
// - User may submit their own textures to e.g. ImGui::Image() function by passing this value.
|
||||
// - During the rendering loop, the Renderer Backend retrieve the ImTextureID, which stored inside a
|
||||
// ImTextureRef, which is stored inside a ImDrawCmd.
|
||||
// - Compile-time type configuration:
|
||||
@@ -342,15 +342,17 @@ typedef ImU64 ImTextureID; // Default: store up to 64-bits (any pointer or
|
||||
#define ImTextureID_Invalid ((ImTextureID)0)
|
||||
#endif
|
||||
|
||||
// ImTextureRef = higher-level identifier for a texture.
|
||||
// ImTextureRef = higher-level identifier for a texture. Store a ImTextureID _or_ a ImTextureData*.
|
||||
// The identifier is valid even before the texture has been uploaded to the GPU/graphics system.
|
||||
// This is what gets passed to functions such as `ImGui::Image()`, `ImDrawList::AddImage()`.
|
||||
// This is what gets stored in draw commands (`ImDrawCmd`) to identify a texture during rendering.
|
||||
// - When a texture is created by user code (e.g. custom images), we directly stores the low-level ImTextureID.
|
||||
// Because of this, when displaying your own texture you are likely to ever only manage ImTextureID values on your side.
|
||||
// - When a texture is created by the backend, we stores a ImTextureData* which becomes an indirection
|
||||
// to extract the ImTextureID value during rendering, after texture upload has happened.
|
||||
// - There is no constructor to create a ImTextureID from a ImTextureData* as we don't expect this
|
||||
// to be useful to the end-user, and it would be erroneously called by many legacy code.
|
||||
// - To create a ImTextureRef from a ImTextureData you can use ImTextureData::GetTexRef().
|
||||
// We intentionally do not provide an ImTextureRef constructor for this: we don't expect this
|
||||
// to be frequently useful to the end-user, and it would be erroneously called by many legacy code.
|
||||
// - If you want to bind the current atlas when using custom rectangle, you can use io.Fonts->TexRef.
|
||||
// - Binding generators for languages such as C (which don't have constructors), should provide a helper, e.g.
|
||||
// inline ImTextureRef ImTextureRefFromID(ImTextureID tex_id) { ImTextureRef tex_ref = { ._TexData = NULL, .TexID = tex_id }; return tex_ref; }
|
||||
@@ -3479,7 +3481,7 @@ struct ImDrawList
|
||||
struct ImDrawData
|
||||
{
|
||||
bool Valid; // Only valid after Render() is called and before the next NewFrame() is called.
|
||||
int CmdListsCount; // Number of ImDrawList* to render. (== CmdLists.Size). Exists for legacy reason.
|
||||
int CmdListsCount; // == CmdLists.Size. (OBSOLETE: exists for legacy reasons). Number of ImDrawList* to render.
|
||||
int TotalIdxCount; // For convenience, sum of all ImDrawList's IdxBuffer.Size
|
||||
int TotalVtxCount; // For convenience, sum of all ImDrawList's VtxBuffer.Size
|
||||
ImVector<ImDrawList*> CmdLists; // Array of ImDrawList* to render. The ImDrawLists are owned by ImGuiContext and only pointed to from here.
|
||||
@@ -3544,7 +3546,7 @@ struct ImTextureRect
|
||||
struct ImTextureData
|
||||
{
|
||||
//------------------------------------------ core / backend ---------------------------------------
|
||||
int UniqueID; // w - // Sequential index to facilitate identifying a texture when debugging/printing. Unique per atlas.
|
||||
int UniqueID; // w - // [DEBUG] Sequential index to facilitate identifying a texture when debugging/printing. Unique per atlas.
|
||||
ImTextureStatus Status; // rw rw // ImTextureStatus_OK/_WantCreate/_WantUpdates/_WantDestroy. Always use SetStatus() to modify!
|
||||
void* BackendUserData; // - rw // Convenience storage for backend. Some backends may have enough with TexID.
|
||||
ImTextureID TexID; // r w // Backend-specific texture identifier. Always use SetTexID() to modify! The identifier will stored in ImDrawCmd::GetTexID() and passed to backend's RenderDrawData function.
|
||||
@@ -3562,7 +3564,7 @@ struct ImTextureData
|
||||
bool WantDestroyNextFrame; // rw - // [Internal] Queued to set ImTextureStatus_WantDestroy next frame. May still be used in the current frame.
|
||||
|
||||
// Functions
|
||||
ImTextureData() { memset(this, 0, sizeof(*this)); TexID = ImTextureID_Invalid; }
|
||||
ImTextureData() { memset(this, 0, sizeof(*this)); Status = ImTextureStatus_Destroyed; TexID = ImTextureID_Invalid; }
|
||||
~ImTextureData() { DestroyPixels(); }
|
||||
IMGUI_API void Create(ImTextureFormat format, int w, int h);
|
||||
IMGUI_API void DestroyPixels();
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.92.1
|
||||
// dear imgui, v1.92.2 WIP
|
||||
// (demo code)
|
||||
|
||||
// Help:
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.92.1
|
||||
// dear imgui, v1.92.2 WIP
|
||||
// (drawing and font code)
|
||||
|
||||
/*
|
||||
@@ -2318,17 +2318,16 @@ void ImDrawData::DeIndexAllBuffers()
|
||||
{
|
||||
ImVector<ImDrawVert> new_vtx_buffer;
|
||||
TotalVtxCount = TotalIdxCount = 0;
|
||||
for (int i = 0; i < CmdListsCount; i++)
|
||||
for (ImDrawList* draw_list : CmdLists)
|
||||
{
|
||||
ImDrawList* cmd_list = CmdLists[i];
|
||||
if (cmd_list->IdxBuffer.empty())
|
||||
if (draw_list->IdxBuffer.empty())
|
||||
continue;
|
||||
new_vtx_buffer.resize(cmd_list->IdxBuffer.Size);
|
||||
for (int j = 0; j < cmd_list->IdxBuffer.Size; j++)
|
||||
new_vtx_buffer[j] = cmd_list->VtxBuffer[cmd_list->IdxBuffer[j]];
|
||||
cmd_list->VtxBuffer.swap(new_vtx_buffer);
|
||||
cmd_list->IdxBuffer.resize(0);
|
||||
TotalVtxCount += cmd_list->VtxBuffer.Size;
|
||||
new_vtx_buffer.resize(draw_list->IdxBuffer.Size);
|
||||
for (int j = 0; j < draw_list->IdxBuffer.Size; j++)
|
||||
new_vtx_buffer[j] = draw_list->VtxBuffer[draw_list->IdxBuffer[j]];
|
||||
draw_list->VtxBuffer.swap(new_vtx_buffer);
|
||||
draw_list->IdxBuffer.resize(0);
|
||||
TotalVtxCount += draw_list->VtxBuffer.Size;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2463,8 +2462,10 @@ const char* ImTextureDataGetFormatName(ImTextureFormat format)
|
||||
|
||||
void ImTextureData::Create(ImTextureFormat format, int w, int h)
|
||||
{
|
||||
IM_ASSERT(Status == ImTextureStatus_Destroyed);
|
||||
DestroyPixels();
|
||||
Format = format;
|
||||
Status = ImTextureStatus_WantCreate;
|
||||
Width = w;
|
||||
Height = h;
|
||||
BytesPerPixel = ImTextureDataGetFormatBytesPerPixel(format);
|
||||
@@ -2745,10 +2746,9 @@ void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas, int frame_count, bool rendere
|
||||
if (atlas->Builder == NULL) // This will only happen if fonts were not already loaded.
|
||||
ImFontAtlasBuildMain(atlas);
|
||||
}
|
||||
else // Legacy backend
|
||||
{
|
||||
// Legacy backend
|
||||
if (!atlas->RendererHasTextures)
|
||||
IM_ASSERT_USER_ERROR(atlas->TexIsBuilt, "Backend does not support ImGuiBackendFlags_RendererHasTextures, and font atlas is not built! Update backend OR make sure you called ImGui_ImplXXXX_NewFrame() function for renderer backend, which should call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8().");
|
||||
}
|
||||
if (atlas->TexIsBuilt && atlas->Builder->PreloadedAllGlyphsRanges)
|
||||
IM_ASSERT_USER_ERROR(atlas->RendererHasTextures == false, "Called ImFontAtlas::Build() before ImGuiBackendFlags_RendererHasTextures got set! With new backends: you don't need to call Build().");
|
||||
|
||||
@@ -2803,8 +2803,9 @@ void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas, int frame_count, bool rendere
|
||||
}
|
||||
else if (tex->WantDestroyNextFrame && tex->Status != ImTextureStatus_WantDestroy)
|
||||
{
|
||||
// Request destroy. Keep bool as it allows us to keep track of things.
|
||||
// We don't destroy pixels right away, as backend may have an in-flight copy from RAM.
|
||||
// Request destroy.
|
||||
// - Keep bool to true in order to differentiate a planned destroy vs a destroy decided by the backend.
|
||||
// - We don't destroy pixels right away, as backend may have an in-flight copy from RAM.
|
||||
IM_ASSERT(tex->Status == ImTextureStatus_OK || tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantUpdates);
|
||||
tex->Status = ImTextureStatus_WantDestroy;
|
||||
}
|
||||
@@ -2960,7 +2961,7 @@ void ImFontAtlasTextureBlockQueueUpload(ImFontAtlas* atlas, ImTextureData* tex,
|
||||
tex->UsedRect.h = (unsigned short)(ImMax(tex->UsedRect.y + tex->UsedRect.h, req.y + req.h) - tex->UsedRect.y);
|
||||
atlas->TexIsBuilt = false;
|
||||
|
||||
// No need to queue if status is _WantCreate
|
||||
// No need to queue if status is == ImTextureStatus_WantCreate
|
||||
if (tex->Status == ImTextureStatus_OK || tex->Status == ImTextureStatus_WantUpdates)
|
||||
{
|
||||
tex->Status = ImTextureStatus_WantUpdates;
|
||||
@@ -3977,7 +3978,6 @@ ImTextureData* ImFontAtlasTextureAdd(ImFontAtlas* atlas, int w, int h)
|
||||
}
|
||||
|
||||
new_tex->Create(atlas->TexDesiredFormat, w, h);
|
||||
new_tex->Status = ImTextureStatus_WantCreate;
|
||||
atlas->TexIsBuilt = false;
|
||||
|
||||
ImFontAtlasBuildSetTexture(atlas, new_tex);
|
||||
|
121
imgui_internal.h
121
imgui_internal.h
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.92.1
|
||||
// dear imgui, v1.92.2 WIP
|
||||
// (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.
|
||||
@@ -380,17 +380,17 @@ IMGUI_API ImGuiID ImHashStr(const char* data, size_t data_size = 0, ImGuiI
|
||||
|
||||
// Helpers: Sorting
|
||||
#ifndef ImQsort
|
||||
static inline void ImQsort(void* base, size_t count, size_t size_of_element, int(IMGUI_CDECL *compare_func)(void const*, void const*)) { if (count > 1) qsort(base, count, size_of_element, compare_func); }
|
||||
inline void ImQsort(void* base, size_t count, size_t size_of_element, int(IMGUI_CDECL *compare_func)(void const*, void const*)) { if (count > 1) qsort(base, count, size_of_element, compare_func); }
|
||||
#endif
|
||||
|
||||
// Helpers: Color Blending
|
||||
IMGUI_API ImU32 ImAlphaBlendColors(ImU32 col_a, ImU32 col_b);
|
||||
|
||||
// Helpers: Bit manipulation
|
||||
static inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; }
|
||||
static inline bool ImIsPowerOfTwo(ImU64 v) { return v != 0 && (v & (v - 1)) == 0; }
|
||||
static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; }
|
||||
static inline unsigned int ImCountSetBits(unsigned int v) { unsigned int count = 0; while (v > 0) { v = v & (v - 1); count++; } return count; }
|
||||
inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; }
|
||||
inline bool ImIsPowerOfTwo(ImU64 v) { return v != 0 && (v & (v - 1)) == 0; }
|
||||
inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; }
|
||||
inline unsigned int ImCountSetBits(unsigned int v) { unsigned int count = 0; while (v > 0) { v = v & (v - 1); count++; } return count; }
|
||||
|
||||
// Helpers: String
|
||||
#define ImStrlen strlen
|
||||
@@ -409,10 +409,10 @@ IMGUI_API const char* ImStrSkipBlank(const char* str);
|
||||
IMGUI_API int ImStrlenW(const ImWchar* str); // Computer string length (ImWchar string)
|
||||
IMGUI_API const char* ImStrbol(const char* buf_mid_line, const char* buf_begin); // Find beginning-of-line
|
||||
IM_MSVC_RUNTIME_CHECKS_OFF
|
||||
static inline char ImToUpper(char c) { return (c >= 'a' && c <= 'z') ? c &= ~32 : c; }
|
||||
static inline bool ImCharIsBlankA(char c) { return c == ' ' || c == '\t'; }
|
||||
static inline bool ImCharIsBlankW(unsigned int c) { return c == ' ' || c == '\t' || c == 0x3000; }
|
||||
static inline bool ImCharIsXdigitA(char c) { return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); }
|
||||
inline char ImToUpper(char c) { return (c >= 'a' && c <= 'z') ? c &= ~32 : c; }
|
||||
inline bool ImCharIsBlankA(char c) { return c == ' ' || c == '\t'; }
|
||||
inline bool ImCharIsBlankW(unsigned int c) { return c == ' ' || c == '\t' || c == 0x3000; }
|
||||
inline bool ImCharIsXdigitA(char c) { return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); }
|
||||
IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||
|
||||
// Helpers: Formatting
|
||||
@@ -428,7 +428,7 @@ IMGUI_API const char* ImParseFormatSanitizeForScanning(const char* fmt_in, cha
|
||||
IMGUI_API int ImParseFormatPrecision(const char* format, int default_value);
|
||||
|
||||
// Helpers: UTF-8 <> wchar conversions
|
||||
IMGUI_API const char* ImTextCharToUtf8(char out_buf[5], unsigned int c); // return out_buf
|
||||
IMGUI_API int ImTextCharToUtf8(char out_buf[5], unsigned int c); // return output UTF-8 bytes count
|
||||
IMGUI_API int ImTextStrToUtf8(char* out_buf, int out_buf_size, const ImWchar* in_text, const ImWchar* in_text_end); // return output UTF-8 bytes count
|
||||
IMGUI_API int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end); // read one character. return input UTF-8 bytes count
|
||||
IMGUI_API int ImTextStrFromUtf8(ImWchar* out_buf, int out_buf_size, const char* in_text, const char* in_text_end, const char** in_remaining = NULL); // return input UTF-8 bytes count
|
||||
@@ -442,11 +442,11 @@ IMGUI_API int ImTextCountLines(const char* in_text, const char* in_tex
|
||||
#ifdef IMGUI_DISABLE_FILE_FUNCTIONS
|
||||
#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS
|
||||
typedef void* ImFileHandle;
|
||||
static inline ImFileHandle ImFileOpen(const char*, const char*) { return NULL; }
|
||||
static inline bool ImFileClose(ImFileHandle) { return false; }
|
||||
static inline ImU64 ImFileGetSize(ImFileHandle) { return (ImU64)-1; }
|
||||
static inline ImU64 ImFileRead(void*, ImU64, ImU64, ImFileHandle) { return 0; }
|
||||
static inline ImU64 ImFileWrite(const void*, ImU64, ImU64, ImFileHandle) { return 0; }
|
||||
inline ImFileHandle ImFileOpen(const char*, const char*) { return NULL; }
|
||||
inline bool ImFileClose(ImFileHandle) { return false; }
|
||||
inline ImU64 ImFileGetSize(ImFileHandle) { return (ImU64)-1; }
|
||||
inline ImU64 ImFileRead(void*, ImU64, ImU64, ImFileHandle) { return 0; }
|
||||
inline ImU64 ImFileWrite(const void*, ImU64, ImU64, ImFileHandle) { return 0; }
|
||||
#endif
|
||||
#ifndef IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS
|
||||
typedef FILE* ImFileHandle;
|
||||
@@ -473,56 +473,56 @@ IM_MSVC_RUNTIME_CHECKS_OFF
|
||||
#define ImAtan2(Y, X) atan2f((Y), (X))
|
||||
#define ImAtof(STR) atof(STR)
|
||||
#define ImCeil(X) ceilf(X)
|
||||
static inline float ImPow(float x, float y) { return powf(x, y); } // DragBehaviorT/SliderBehaviorT uses ImPow with either float/double and need the precision
|
||||
static inline double ImPow(double x, double y) { return pow(x, y); }
|
||||
static inline float ImLog(float x) { return logf(x); } // DragBehaviorT/SliderBehaviorT uses ImLog with either float/double and need the precision
|
||||
static inline double ImLog(double x) { return log(x); }
|
||||
static inline int ImAbs(int x) { return x < 0 ? -x : x; }
|
||||
static inline float ImAbs(float x) { return fabsf(x); }
|
||||
static inline double ImAbs(double x) { return fabs(x); }
|
||||
static inline float ImSign(float x) { return (x < 0.0f) ? -1.0f : (x > 0.0f) ? 1.0f : 0.0f; } // Sign operator - returns -1, 0 or 1 based on sign of argument
|
||||
static inline double ImSign(double x) { return (x < 0.0) ? -1.0 : (x > 0.0) ? 1.0 : 0.0; }
|
||||
inline float ImPow(float x, float y) { return powf(x, y); } // DragBehaviorT/SliderBehaviorT uses ImPow with either float/double and need the precision
|
||||
inline double ImPow(double x, double y) { return pow(x, y); }
|
||||
inline float ImLog(float x) { return logf(x); } // DragBehaviorT/SliderBehaviorT uses ImLog with either float/double and need the precision
|
||||
inline double ImLog(double x) { return log(x); }
|
||||
inline int ImAbs(int x) { return x < 0 ? -x : x; }
|
||||
inline float ImAbs(float x) { return fabsf(x); }
|
||||
inline double ImAbs(double x) { return fabs(x); }
|
||||
inline float ImSign(float x) { return (x < 0.0f) ? -1.0f : (x > 0.0f) ? 1.0f : 0.0f; } // Sign operator - returns -1, 0 or 1 based on sign of argument
|
||||
inline double ImSign(double x) { return (x < 0.0) ? -1.0 : (x > 0.0) ? 1.0 : 0.0; }
|
||||
#ifdef IMGUI_ENABLE_SSE
|
||||
static inline float ImRsqrt(float x) { return _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(x))); }
|
||||
inline float ImRsqrt(float x) { return _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(x))); }
|
||||
#else
|
||||
static inline float ImRsqrt(float x) { return 1.0f / sqrtf(x); }
|
||||
inline float ImRsqrt(float x) { return 1.0f / sqrtf(x); }
|
||||
#endif
|
||||
static inline double ImRsqrt(double x) { return 1.0 / sqrt(x); }
|
||||
inline double ImRsqrt(double x) { return 1.0 / sqrt(x); }
|
||||
#endif
|
||||
// - ImMin/ImMax/ImClamp/ImLerp/ImSwap are used by widgets which support variety of types: signed/unsigned int/long long float/double
|
||||
// (Exceptionally using templates here but we could also redefine them for those types)
|
||||
template<typename T> static inline T ImMin(T lhs, T rhs) { return lhs < rhs ? lhs : rhs; }
|
||||
template<typename T> static inline T ImMax(T lhs, T rhs) { return lhs >= rhs ? lhs : rhs; }
|
||||
template<typename T> static inline T ImClamp(T v, T mn, T mx) { return (v < mn) ? mn : (v > mx) ? mx : v; }
|
||||
template<typename T> static inline T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * t); }
|
||||
template<typename T> static inline void ImSwap(T& a, T& b) { T tmp = a; a = b; b = tmp; }
|
||||
template<typename T> static inline T ImAddClampOverflow(T a, T b, T mn, T mx) { if (b < 0 && (a < mn - b)) return mn; if (b > 0 && (a > mx - b)) return mx; return a + b; }
|
||||
template<typename T> static inline T ImSubClampOverflow(T a, T b, T mn, T mx) { if (b > 0 && (a < mn + b)) return mn; if (b < 0 && (a > mx + b)) return mx; return a - b; }
|
||||
template<typename T> T ImMin(T lhs, T rhs) { return lhs < rhs ? lhs : rhs; }
|
||||
template<typename T> T ImMax(T lhs, T rhs) { return lhs >= rhs ? lhs : rhs; }
|
||||
template<typename T> T ImClamp(T v, T mn, T mx) { return (v < mn) ? mn : (v > mx) ? mx : v; }
|
||||
template<typename T> T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * t); }
|
||||
template<typename T> void ImSwap(T& a, T& b) { T tmp = a; a = b; b = tmp; }
|
||||
template<typename T> T ImAddClampOverflow(T a, T b, T mn, T mx) { if (b < 0 && (a < mn - b)) return mn; if (b > 0 && (a > mx - b)) return mx; return a + b; }
|
||||
template<typename T> T ImSubClampOverflow(T a, T b, T mn, T mx) { if (b > 0 && (a < mn + b)) return mn; if (b < 0 && (a > mx + b)) return mx; return a - b; }
|
||||
// - Misc maths helpers
|
||||
static inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x < rhs.x ? lhs.x : rhs.x, lhs.y < rhs.y ? lhs.y : rhs.y); }
|
||||
static inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x >= rhs.x ? lhs.x : rhs.x, lhs.y >= rhs.y ? lhs.y : rhs.y); }
|
||||
static inline ImVec2 ImClamp(const ImVec2& v, const ImVec2&mn, const ImVec2&mx) { return ImVec2((v.x < mn.x) ? mn.x : (v.x > mx.x) ? mx.x : v.x, (v.y < mn.y) ? mn.y : (v.y > mx.y) ? mx.y : v.y); }
|
||||
static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, float t) { return ImVec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t); }
|
||||
static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); }
|
||||
static inline ImVec4 ImLerp(const ImVec4& a, const ImVec4& b, float t) { return ImVec4(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t, a.w + (b.w - a.w) * t); }
|
||||
static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; }
|
||||
static inline float ImLengthSqr(const ImVec2& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y); }
|
||||
static inline float ImLengthSqr(const ImVec4& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y) + (lhs.z * lhs.z) + (lhs.w * lhs.w); }
|
||||
static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = (lhs.x * lhs.x) + (lhs.y * lhs.y); if (d > 0.0f) return ImRsqrt(d); return fail_value; }
|
||||
static inline float ImTrunc(float f) { return (float)(int)(f); }
|
||||
static inline ImVec2 ImTrunc(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); }
|
||||
static inline float ImFloor(float f) { return (float)((f >= 0 || (float)(int)f == f) ? (int)f : (int)f - 1); } // Decent replacement for floorf()
|
||||
static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2(ImFloor(v.x), ImFloor(v.y)); }
|
||||
static inline float ImTrunc64(float f) { return (float)(ImS64)(f); }
|
||||
static inline float ImRound64(float f) { return (float)(ImS64)(f + 0.5f); }
|
||||
static inline int ImModPositive(int a, int b) { return (a + b) % b; }
|
||||
static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; }
|
||||
static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); }
|
||||
static inline float ImLinearSweep(float current, float target, float speed) { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; }
|
||||
static inline float ImLinearRemapClamp(float s0, float s1, float d0, float d1, float x) { return ImSaturate((x - s0) / (s1 - s0)) * (d1 - d0) + d0; }
|
||||
static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
|
||||
static inline bool ImIsFloatAboveGuaranteedIntegerPrecision(float f) { return f <= -16777216 || f >= 16777216; }
|
||||
static inline float ImExponentialMovingAverage(float avg, float sample, int n) { avg -= avg / n; avg += sample / n; return avg; }
|
||||
inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x < rhs.x ? lhs.x : rhs.x, lhs.y < rhs.y ? lhs.y : rhs.y); }
|
||||
inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x >= rhs.x ? lhs.x : rhs.x, lhs.y >= rhs.y ? lhs.y : rhs.y); }
|
||||
inline ImVec2 ImClamp(const ImVec2& v, const ImVec2&mn, const ImVec2&mx){ return ImVec2((v.x < mn.x) ? mn.x : (v.x > mx.x) ? mx.x : v.x, (v.y < mn.y) ? mn.y : (v.y > mx.y) ? mx.y : v.y); }
|
||||
inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, float t) { return ImVec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t); }
|
||||
inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); }
|
||||
inline ImVec4 ImLerp(const ImVec4& a, const ImVec4& b, float t) { return ImVec4(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t, a.w + (b.w - a.w) * t); }
|
||||
inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; }
|
||||
inline float ImLengthSqr(const ImVec2& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y); }
|
||||
inline float ImLengthSqr(const ImVec4& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y) + (lhs.z * lhs.z) + (lhs.w * lhs.w); }
|
||||
inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = (lhs.x * lhs.x) + (lhs.y * lhs.y); if (d > 0.0f) return ImRsqrt(d); return fail_value; }
|
||||
inline float ImTrunc(float f) { return (float)(int)(f); }
|
||||
inline ImVec2 ImTrunc(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); }
|
||||
inline float ImFloor(float f) { return (float)((f >= 0 || (float)(int)f == f) ? (int)f : (int)f - 1); } // Decent replacement for floorf()
|
||||
inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2(ImFloor(v.x), ImFloor(v.y)); }
|
||||
inline float ImTrunc64(float f) { return (float)(ImS64)(f); }
|
||||
inline float ImRound64(float f) { return (float)(ImS64)(f + 0.5f); }
|
||||
inline int ImModPositive(int a, int b) { return (a + b) % b; }
|
||||
inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; }
|
||||
inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); }
|
||||
inline float ImLinearSweep(float current, float target, float speed) { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; }
|
||||
inline float ImLinearRemapClamp(float s0, float s1, float d0, float d1, float x) { return ImSaturate((x - s0) / (s1 - s0)) * (d1 - d0) + d0; }
|
||||
inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
|
||||
inline bool ImIsFloatAboveGuaranteedIntegerPrecision(float f) { return f <= -16777216 || f >= 16777216; }
|
||||
inline float ImExponentialMovingAverage(float avg, float sample, int n){ avg -= avg / n; avg += sample / n; return avg; }
|
||||
IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||
|
||||
// Helpers: Geometry
|
||||
@@ -3357,7 +3357,7 @@ namespace ImGui
|
||||
IMGUI_API void SetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags flags);
|
||||
|
||||
// Fonts, drawing
|
||||
IMGUI_API void RegisterUserTexture(ImTextureData* tex); // Register external texture
|
||||
IMGUI_API void RegisterUserTexture(ImTextureData* tex); // Register external texture. EXPERIMENTAL: DO NOT USE YET.
|
||||
IMGUI_API void UnregisterUserTexture(ImTextureData* tex);
|
||||
IMGUI_API void RegisterFontAtlas(ImFontAtlas* atlas);
|
||||
IMGUI_API void UnregisterFontAtlas(ImFontAtlas* atlas);
|
||||
@@ -3969,7 +3969,6 @@ namespace ImGui
|
||||
//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!
|
||||
|
||||
// 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():
|
||||
// (Old) IMGUI_VERSION_NUM < 18209: using 'ItemAdd(....)' and 'bool tab_focused = FocusableItemRegister(...)'
|
||||
// (Old) IMGUI_VERSION_NUM >= 18209: using 'ItemAdd(..., ImGuiItemAddFlags_Focusable)' and 'bool tab_focused = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Focused) != 0'
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.92.1
|
||||
// dear imgui, v1.92.2 WIP
|
||||
// (tables and columns code)
|
||||
|
||||
/*
|
||||
@@ -1825,6 +1825,11 @@ void ImGui::TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
IM_ASSERT(target != ImGuiTableBgTarget_None);
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (color == IM_COL32_DISABLE)
|
||||
color = 0;
|
||||
@@ -2876,9 +2881,7 @@ ImGuiTableSortSpecs* ImGui::TableGetSortSpecs()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
IM_ASSERT(table != NULL);
|
||||
|
||||
if (!(table->Flags & ImGuiTableFlags_Sortable))
|
||||
if (table == NULL || !(table->Flags & ImGuiTableFlags_Sortable))
|
||||
return NULL;
|
||||
|
||||
// Require layout (in case TableHeadersRow() hasn't been called) as it may alter IsSortSpecsDirty in some paths.
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.92.1
|
||||
// dear imgui, v1.92.2 WIP
|
||||
// (widgets code)
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user