mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-31 05:01:05 +01:00 
			
		
		
		
	Metrics: Show wire-frame mesh and approximate surface area when hovering ImDrawCmd. Amend aeb5795.
				
					
				
			Internals: Added ImTriangleArea()
This commit is contained in:
		| @@ -84,10 +84,11 @@ Other Changes: | ||||
| - 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 | ||||
|   | ||||
							
								
								
									
										97
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										97
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -45,7 +45,7 @@ CODE | ||||
| // [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 @@ void ImGuiIO::ClearInputCharacters() | ||||
| } | ||||
|  | ||||
| //----------------------------------------------------------------------------- | ||||
| // [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 @@ void ImGui::ShowMetricsWindow(bool* p_open) | ||||
|     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 @@ void ImGui::ShowMetricsWindow(bool* p_open) | ||||
|                 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 @@ void ImGui::ShowMetricsWindow(bool* p_open) | ||||
|                 } | ||||
|  | ||||
|                 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 @@ void ImGui::ShowMetricsWindow(bool* p_open) | ||||
|                     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 @@ void ImGui::ShowMetricsWindow(bool* p_open) | ||||
|             } | ||||
|             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(); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -3421,7 +3421,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) | ||||
|                     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); | ||||
|   | ||||
| @@ -194,11 +194,11 @@ extern IMGUI_API ImGuiContext* GImGui;  // Current implicit context pointer | ||||
| //----------------------------------------------------------------------------- | ||||
| // - 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 ImU32     ImHash(const void* data, int size, ImU32 seed = 0) { ret | ||||
| 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 ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_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 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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user