Metrics: Show wire-frame mesh and approximate surface area when hovering ImDrawCmd. Amend aeb5795.
Internals: Added ImTriangleArea()
diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt
index be749e2..bbd9b04 100644
--- a/docs/CHANGELOG.txt
+++ b/docs/CHANGELOG.txt
@@ -84,10 +84,11 @@
- Misc: Windows: Disabled win32 function by default when building with UWP. (#2892, #2895)
- Misc: Using static_assert() when using C++11, instead of our own construct (avoid zealous Clang warnings).
- Misc: Added IMGUI_DISABLE_FILE_FUNCTIONS/IMGUI_DISABLE_DEFAULT_FILE_FUNCTION to nullify or disable
- default implementationof ImFileXXX functions linking with fopen/fclose/fread/fwrite. (#2734)
+ default implementation of ImFileXXX functions linking with fopen/fclose/fread/fwrite. (#2734)
- Docs: Improved and moved FAQ to docs/FAQ.md so it can be readable on the web. [@ButternCream, @ocornut]
- Docs: Added permanent redirect from https://www.dearimgui.org/faq to FAQ page.
- Demo: Added simple item reordering demo in Widgets -> Drag and Drop section. (#2823, #143) [@rokups]
+- Metrics: Show wire-frame mesh and approximate surface area when hovering ImDrawCmd. [@ShironekoBen]
- Metrics: Expose basic details of each window key/value state storage.
- Examples: DX12: Using IDXGIDebug1::ReportLiveObjects() when DX12_ENABLE_DEBUG_LAYER is enabled.
- Examples: Emscripten: Removed BINARYEN_TRAP_MODE=clamp from Makefile which was removed in Emscripten 1.39.0
diff --git a/imgui.cpp b/imgui.cpp
index ee4385d..923c794 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -45,7 +45,7 @@
// [SECTION] FORWARD DECLARATIONS
// [SECTION] CONTEXT AND MEMORY ALLOCATORS
// [SECTION] MAIN USER FACING STRUCTURES (ImGuiStyle, ImGuiIO)
-// [SECTION] MISC HELPERS/UTILITIES (Maths, String, Format, Hash, File functions)
+// [SECTION] MISC HELPERS/UTILITIES (Geomtry, String, Format, Hash, File functions)
// [SECTION] MISC HELPERS/UTILITIES (File functions)
// [SECTION] MISC HELPERS/UTILITIES (ImText* functions)
// [SECTION] MISC HELPERS/UTILITIES (Color functions)
@@ -1083,7 +1083,7 @@
}
//-----------------------------------------------------------------------------
-// [SECTION] MISC HELPERS/UTILITIES (Maths, String, Format, Hash, File functions)
+// [SECTION] MISC HELPERS/UTILITIES (Geometry, String, Format, Hash, File functions)
//-----------------------------------------------------------------------------
ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p)
@@ -9715,7 +9715,7 @@
static bool show_windows_rects = false;
static int show_windows_rect_type = WRT_WorkRect;
static bool show_windows_begin_order = false;
- static bool show_drawcmd_clip_rects = true;
+ static bool show_drawcmd_details = true;
// Basic info
ImGuiContext& g = *GImGui;
@@ -9766,7 +9766,7 @@
return;
if (window && !window->WasActive)
- ImGui::Text("(Note: owning Window is inactive: DrawList is not being rendered!)");
+ ImGui::TextDisabled("Warning: owning Window is inactive. This DrawList is not being rendered!");
unsigned int elem_offset = 0;
for (const ImDrawCmd* pcmd = draw_list->CmdBuffer.begin(); pcmd < draw_list->CmdBuffer.end(); elem_offset += pcmd->ElemCount, pcmd++)
@@ -9780,73 +9780,51 @@
}
ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL;
-
- // Calculate approximate coverage area (touched pixel count)
- // This will be in pixels squared as long there's no post-scaling happening to the ImGui output
- // Optionally also draw all the polys in the list in wireframe when hovering over
-
- float total_area = 0.0f;
-
- for (unsigned int base_idx = elem_offset; base_idx < (elem_offset + pcmd->ElemCount); base_idx += 3)
- {
- ImVec2 triangles_pos[3];
- for (int n = 0; n < 3; n++)
- {
- int vtx_i = idx_buffer ? idx_buffer[base_idx + n] : (base_idx + n);
- ImDrawVert& v = draw_list->VtxBuffer[vtx_i];
- triangles_pos[n] = v.pos;
- }
-
- // Calculate triangle area and accumulate
-
- float area = abs((triangles_pos[0].x * (triangles_pos[1].y - triangles_pos[2].y)) +
- (triangles_pos[1].x * (triangles_pos[2].y - triangles_pos[0].y)) +
- (triangles_pos[2].x * (triangles_pos[0].y - triangles_pos[1].y))) * 0.5f;
-
- total_area += area;
- }
-
char buf[300];
- ImFormatString(buf, IM_ARRAYSIZE(buf), "Draw %4d triangles, tex 0x%p, area %.0fpx^2, clip_rect (%4.0f,%4.0f)-(%4.0f,%4.0f)",
- pcmd->ElemCount/3, (void*)(intptr_t)pcmd->TextureId, total_area,
+ ImFormatString(buf, IM_ARRAYSIZE(buf), "DrawCmd: %4d triangles, Tex 0x%p, ClipRect (%4.0f,%4.0f)-(%4.0f,%4.0f)",
+ pcmd->ElemCount/3, (void*)(intptr_t)pcmd->TextureId,
pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w);
bool pcmd_node_open = ImGui::TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "%s", buf);
- if (show_drawcmd_clip_rects && fg_draw_list && ImGui::IsItemHovered())
+ if (show_drawcmd_details && fg_draw_list && ImGui::IsItemHovered())
{
ImRect clip_rect = pcmd->ClipRect;
ImRect vtxs_rect;
for (unsigned int i = elem_offset; i < elem_offset + (int)pcmd->ElemCount; i++)
vtxs_rect.Add(draw_list->VtxBuffer[idx_buffer ? idx_buffer[i] : i].pos);
- clip_rect.Floor(); fg_draw_list->AddRect(clip_rect.Min, clip_rect.Max, IM_COL32(255,0,255,255));
- vtxs_rect.Floor(); fg_draw_list->AddRect(vtxs_rect.Min, vtxs_rect.Max, IM_COL32(255,255,0,255));
+ fg_draw_list->AddRect(ImFloor(clip_rect.Min), ImFloor(clip_rect.Max), IM_COL32(255,0,255,255));
+ fg_draw_list->AddRect(ImFloor(vtxs_rect.Min), ImFloor(vtxs_rect.Max), IM_COL32(255,255,0,255));
}
if (!pcmd_node_open)
continue;
- // Display vertex information summary. Hover to get all triangles drawn in wireframe
- ImFormatString(buf, IM_ARRAYSIZE(buf), "ElemCount: %d, ElemCount/3: %d, VtxOffset: +%d, IdxOffset: +%d", pcmd->ElemCount, pcmd->ElemCount/3, pcmd->VtxOffset, pcmd->IdxOffset);
- ImGui::Selectable(buf, false);
-
- if (fg_draw_list && ImGui::IsItemHovered())
+ // Calculate approximate coverage area (touched pixel count)
+ // This will be in pixels squared as long there's no post-scaling happening to the renderer output.
+ float total_area = 0.0f;
+ for (unsigned int base_idx = elem_offset; base_idx < (elem_offset + pcmd->ElemCount); base_idx += 3)
{
- // Draw wireframe version of everything
+ ImVec2 triangle[3];
+ for (int n = 0; n < 3; n++)
+ triangle[n] = draw_list->VtxBuffer[idx_buffer ? idx_buffer[base_idx + n] : (base_idx + n)].pos;
+ total_area += ImTriangleArea(triangle[0], triangle[1], triangle[2]);
+ }
+ // Display vertex information summary. Hover to get all triangles drawn in wire-frame
+ ImFormatString(buf, IM_ARRAYSIZE(buf), "Mesh: ElemCount: %d, VtxOffset: +%d, IdxOffset: +%d, Area: ~%0.f px", pcmd->ElemCount, pcmd->VtxOffset, pcmd->IdxOffset, total_area);
+ ImGui::Selectable(buf);
+ if (fg_draw_list && ImGui::IsItemHovered() && show_drawcmd_details)
+ {
+ // Draw wire-frame version of everything
ImDrawListFlags backup_flags = fg_draw_list->Flags;
- fg_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines at is more readable for very large and thin triangles.
-
+ fg_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines is more readable for very large and thin triangles.
+ ImRect clip_rect = pcmd->ClipRect;
+ fg_draw_list->AddRect(ImFloor(clip_rect.Min), ImFloor(clip_rect.Max), IM_COL32(255, 0, 255, 255));
for (unsigned int base_idx = elem_offset; base_idx < (elem_offset + pcmd->ElemCount); base_idx += 3)
{
- ImVec2 triangles_pos[3];
+ ImVec2 triangle[3];
for (int n = 0; n < 3; n++)
- {
- int vtx_i = idx_buffer ? idx_buffer[base_idx + n] : (base_idx + n);
- ImDrawVert& v = draw_list->VtxBuffer[vtx_i];
- triangles_pos[n] = v.pos;
- }
-
- fg_draw_list->AddPolyline(triangles_pos, 3, IM_COL32(255, 255, 0, 255), true, 1.0f);
+ triangle[n] = draw_list->VtxBuffer[idx_buffer ? idx_buffer[base_idx + n] : (base_idx + n)].pos;
+ fg_draw_list->AddPolyline(triangle, 3, IM_COL32(255, 255, 0, 255), true, 1.0f);
}
-
fg_draw_list->Flags = backup_flags;
}
@@ -9856,22 +9834,21 @@
for (int prim = clipper.DisplayStart, idx_i = elem_offset + clipper.DisplayStart*3; prim < clipper.DisplayEnd; prim++)
{
char *buf_p = buf, *buf_end = buf + IM_ARRAYSIZE(buf);
- ImVec2 triangles_pos[3];
+ ImVec2 triangle[3];
for (int n = 0; n < 3; n++, idx_i++)
{
- int vtx_i = idx_buffer ? idx_buffer[idx_i] : idx_i;
- ImDrawVert& v = draw_list->VtxBuffer[vtx_i];
- triangles_pos[n] = v.pos;
+ ImDrawVert& v = draw_list->VtxBuffer[idx_buffer ? idx_buffer[idx_i] : idx_i];
+ triangle[n] = v.pos;
buf_p += ImFormatString(buf_p, buf_end - buf_p, "%s %04d: pos (%8.2f,%8.2f), uv (%.6f,%.6f), col %08X\n",
- (n == 0) ? "elem" : " ", idx_i, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col);
+ (n == 0) ? "Vert:" : " ", idx_i, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col);
}
ImGui::Selectable(buf, false);
if (fg_draw_list && ImGui::IsItemHovered())
{
ImDrawListFlags backup_flags = fg_draw_list->Flags;
- fg_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines at is more readable for very large and thin triangles.
- fg_draw_list->AddPolyline(triangles_pos, 3, IM_COL32(255,255,0,255), true, 1.0f);
+ fg_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines is more readable for very large and thin triangles.
+ fg_draw_list->AddPolyline(triangle, 3, IM_COL32(255,255,0,255), true, 1.0f);
fg_draw_list->Flags = backup_flags;
}
}
@@ -10058,7 +10035,7 @@
}
ImGui::Unindent();
}
- ImGui::Checkbox("Show clipping rectangle when hovering ImDrawCmd node", &show_drawcmd_clip_rects);
+ ImGui::Checkbox("Show details when hovering ImDrawCmd node", &show_drawcmd_details);
ImGui::TreePop();
}
diff --git a/imgui_demo.cpp b/imgui_demo.cpp
index 4091bcf..1a29678 100644
--- a/imgui_demo.cpp
+++ b/imgui_demo.cpp
@@ -3421,7 +3421,7 @@
ImGui::Text("Fallback character: '%c' (U+%04X)", font->FallbackChar, font->FallbackChar);
ImGui::Text("Ellipsis character: '%c' (U+%04X)", font->EllipsisChar, font->EllipsisChar);
const float surface_sqrt = sqrtf((float)font->MetricsTotalSurface);
- ImGui::Text("Texture surface: %d pixels (approx) ~ %dx%d", font->MetricsTotalSurface, (int)surface_sqrt, (int)surface_sqrt);
+ ImGui::Text("Texture Area: about %d px ~%dx%d px", font->MetricsTotalSurface, (int)surface_sqrt, (int)surface_sqrt);
for (int config_i = 0; config_i < font->ConfigDataCount; config_i++)
if (const ImFontConfig* cfg = &font->ConfigData[config_i])
ImGui::BulletText("Input %d: \'%s\', Oversample: (%d,%d), PixelSnapH: %d", config_i, cfg->Name, cfg->OversampleH, cfg->OversampleV, cfg->PixelSnapH);
diff --git a/imgui_internal.h b/imgui_internal.h
index 405bea2..33730c1 100644
--- a/imgui_internal.h
+++ b/imgui_internal.h
@@ -194,11 +194,11 @@
//-----------------------------------------------------------------------------
// - Helpers: Misc
// - Helpers: Bit manipulation
-// - Helpers: Geometry
// - Helpers: String, Formatting
// - Helpers: UTF-8 <> wchar conversions
// - Helpers: ImVec2/ImVec4 operators
// - Helpers: Maths
+// - Helpers: Geometry
// - Helper: ImBoolVector
// - Helper: ImPool<>
// - Helper: ImChunkStream<>
@@ -216,13 +216,6 @@
static inline bool ImIsPowerOfTwo(int 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; }
-// Helpers: Geometry
-IMGUI_API ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p);
-IMGUI_API bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p);
-IMGUI_API ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p);
-IMGUI_API void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p, float& out_u, float& out_v, float& out_w);
-IMGUI_API ImGuiDir ImGetDirQuadrantFromDelta(float dx, float dy);
-
// Helpers: String, Formatting
IMGUI_API int ImStricmp(const char* str1, const char* str2);
IMGUI_API int ImStrnicmp(const char* str1, const char* str2, size_t count);
@@ -343,6 +336,14 @@
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 ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
+// Helpers: Geometry
+IMGUI_API ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p);
+IMGUI_API bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p);
+IMGUI_API ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p);
+IMGUI_API void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p, float& out_u, float& out_v, float& out_w);
+inline float ImTriangleArea(const ImVec2& a, const ImVec2& b, const ImVec2& c) { return ImFabs((a.x * (b.y - c.y)) + (b.x * (c.y - a.y)) + (c.x * (a.y - b.y))) * 0.5f; }
+IMGUI_API ImGuiDir ImGetDirQuadrantFromDelta(float dx, float dy);
+
// Helper: ImBoolVector
// Store 1-bit per value. Note that Resize() currently clears the whole vector.
struct IMGUI_API ImBoolVector