From 741ab74b5575f0b4b5db82db549f07fda130d244 Mon Sep 17 00:00:00 2001 From: Ben Carter Date: Wed, 15 Jan 2020 16:33:09 +0900 Subject: [PATCH] Texture-based thick lines: Improvements to code for drawing anti-aliased lines using textures Moved line width into a constant Removed test code (now in imgui-tests) Improved matching between geometry and texture rendering at non-integer sizes --- imgui.h | 1 - imgui_demo.cpp | 56 ------------------------------------------------ imgui_draw.cpp | 14 +++++------- imgui_internal.h | 3 +++ 4 files changed, 8 insertions(+), 66 deletions(-) diff --git a/imgui.h b/imgui.h index 09d92309..cc4be5e0 100644 --- a/imgui.h +++ b/imgui.h @@ -2323,7 +2323,6 @@ struct ImFontAtlas // [Internal] Packing data int PackIdMouseCursors; // Custom texture rectangle ID for white pixel and mouse cursors - int AALineMaxWidth; // Maximum line width to build anti-aliased textures for ImVector AALineRectIds; // Custom texture rectangle IDs for anti-aliased lines ImVector TexUvAALines; // UVs for anti-aliased line textures diff --git a/imgui_demo.cpp b/imgui_demo.cpp index f06d8526..2afa7a4f 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -297,62 +297,6 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(550, 680), ImGuiCond_FirstUseEver); - // Test lines - - if (ImGui::Begin("Lines")) - { - ImDrawList* draw_list = ImGui::GetWindowDrawList(); - - const int num_cols = 16; - const int num_rows = 3; - const float line_len = 64.0f; - const float line_spacing = 128.0f; - - static float base_rot = 0.0f; - ImGui::SliderFloat("Base rotation", &base_rot, 0.0f, 360.0f); - static float line_width = 1.0f; - ImGui::SliderFloat("Line width", &line_width, 1.0f, 10.0f); - - ImVec2 window_pos = ImGui::GetWindowPos(); - ImVec2 cursor_pos = ImGui::GetCursorPos(); - ImVec2 base_pos(window_pos.x + cursor_pos.x + (line_spacing * 0.5f), window_pos.y + cursor_pos.y); - - for (int i = 0; i < num_rows; i++) - { - const char* name = ""; - switch (i) - { - case 0: name = "No AA"; draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; break; - case 1: name = "AA no texturing"; draw_list->Flags |= ImDrawListFlags_AntiAliasedLines; draw_list->Flags &= ~ImDrawListFlags_TexturedAALines; break; - case 2: name = "AA with texturing"; draw_list->Flags |= ImDrawListFlags_AntiAliasedLines; draw_list->Flags |= ImDrawListFlags_TexturedAALines; break; - } - - int initial_vtx_count = draw_list->VtxBuffer.Size; - int initial_idx_count = draw_list->IdxBuffer.Size; - - for (int j = 0; j < num_cols; j++) - { - const float pi = 3.14159265359f; - float r = (base_rot * pi / 180.0f) + ((j * pi * 0.5f) / (num_cols - 1)); - - ImVec2 center = ImVec2(base_pos.x + (line_spacing * (j * 0.5f)), base_pos.y + (line_spacing * (i + 0.5f))); - ImVec2 start = ImVec2(center.x + (sinf(r) * line_len * 0.5f), center.y + (cosf(r) * line_len * 0.5f)); - ImVec2 end = ImVec2(center.x - (sinf(r) * line_len * 0.5f), center.y - (cosf(r) * line_len * 0.5f)); - - draw_list->AddLine(start, end, IM_COL32(255, 255, 255, 255), line_width); - } - - ImGui::SetCursorPosY(cursor_pos.y + (i * line_spacing)); - ImGui::Text("%s - %d vertices, %d indices", name, draw_list->VtxBuffer.Size - initial_vtx_count, draw_list->IdxBuffer.Size - initial_idx_count); - } - - ImGui::SetCursorPosY(cursor_pos.y + (num_rows * line_spacing)); - - //ImGui::Spacing(); ImGui::Spacing(); ImGui::Spacing(); - //ImGui::Image(ImGui::GetFont()->ContainerAtlas->TexID, ImVec2((float)ImGui::GetFont()->ContainerAtlas->TexWidth, (float)ImGui::GetFont()->ContainerAtlas->TexHeight)); - } - ImGui::End(); - // Main body of the Demo window starts here. if (!ImGui::Begin("Dear ImGui Demo", p_open, window_flags)) { diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 7c845f94..72ccb963 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -676,13 +676,11 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 const float AA_SIZE = 1.0f; const ImU32 col_trans = col & ~IM_COL32_A_MASK; - const int integer_thickness = (int)thickness; + // The -0.5f here is to better match the geometry-based code, and also shift the transition point from one width texture to another off the integer values (where it will be less noticeable) + const int integer_thickness = ImMax((int)(thickness - 0.5f), 1); // Do we want to draw this line using a texture? - bool use_textures = (Flags & ImDrawListFlags_TexturedAALines) && - (integer_thickness >= 1) && - (integer_thickness <= _Data->Font->ContainerAtlas->AALineMaxWidth) && - ImGui::GetIO().KeyShift; // FIXME-AALINES: Remove this debug code + bool use_textures = (Flags & ImDrawListFlags_TexturedAALines) && (integer_thickness <= IM_DRAWLIST_TEX_AA_LINES_WIDTH_MAX); // We should never hit this, because NewFrame() doesn't set ImDrawListFlags_TexturedAALines unless ImFontAtlasFlags_NoAALines is off IM_ASSERT_PARANOID((!use_textures) || (!(_Data->Font->ContainerAtlas->Flags & ImFontAtlasFlags_NoAALines))); @@ -1707,8 +1705,6 @@ ImFontAtlas::ImFontAtlas() TexUvScale = ImVec2(0.0f, 0.0f); TexUvWhitePixel = ImVec2(0.0f, 0.0f); PackIdMouseCursors = -1; - - AALineMaxWidth = 8; } ImFontAtlas::~ImFontAtlas() @@ -2401,7 +2397,7 @@ void ImFontAtlasBuildRegisterAALineCustomRects(ImFontAtlas* atlas) if ((atlas->Flags & ImFontAtlasFlags_NoAALines)) return; - const int max = atlas->AALineMaxWidth; + const int max = IM_DRAWLIST_TEX_AA_LINES_WIDTH_MAX; for (int n = 0; n < max; n++) { @@ -2420,7 +2416,7 @@ void ImFontAtlasBuildAALinesTexData(ImFontAtlas* atlas) return; const int w = atlas->TexWidth; - const unsigned int max = atlas->AALineMaxWidth; + const unsigned int max = IM_DRAWLIST_TEX_AA_LINES_WIDTH_MAX; for (unsigned int n = 0; n < max; n++) { diff --git a/imgui_internal.h b/imgui_internal.h index 2035f324..643aea4d 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -529,6 +529,9 @@ struct IMGUI_API ImChunkStream #define IM_DRAWLIST_ARCFAST_TESSELLATION_MULTIPLIER 1 #endif +// The maximum line width to build anti-aliased textures for +#define IM_DRAWLIST_TEX_AA_LINES_WIDTH_MAX 65 + // Data shared between all ImDrawList instances // You may want to create your own instance of this if you want to use ImDrawList completely without ImGui. In that case, watch out for future changes to this structure. struct IMGUI_API ImDrawListSharedData