From 5ba77928ba2fc58761a3e64a77a131a4074cec09 Mon Sep 17 00:00:00 2001 From: Stephan Dilly Date: Wed, 8 Apr 2015 22:56:25 +0200 Subject: [PATCH 01/15] fix initialising ints with float literals --- imgui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index e96e75d1..5c48b82c 100644 --- a/imgui.h +++ b/imgui.h @@ -317,7 +317,7 @@ namespace ImGui // Widgets: Drags (tip: ctrl+click on a drag box to input text) // ImGui 1.38+ work-in-progress, may change name or API. IMGUI_API bool DragFloat(const char* label, float* v, float v_step = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f"); // If v_max >= v_max we have no bound - IMGUI_API bool DragInt(const char* label, int* v, int v_step = 1, int v_min = 0.0f, int v_max = 0.0f, const char* display_format = "%.0f"); // If v_max >= v_max we have no bound + IMGUI_API bool DragInt(const char* label, int* v, int v_step = 1, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); // If v_max >= v_max we have no bound // Widgets: Input IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL); From 200d3482dcb94e0cf886863fbb95770f35f9ba43 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 9 Apr 2015 00:49:21 +0100 Subject: [PATCH 02/15] Renamed ImDrawList::AddArc() to ImDrawList::AddArcFast() for compatibility with future API, and changed 2*PI range from 0..12 to 0..16 --- imgui.cpp | 33 +++++++++++++++++---------------- imgui.h | 2 +- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 6a7048cb..7171dd8b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -135,6 +135,7 @@ Occasionally introducing changes that are breaking the API. The breakage are generally minor and easy to fix. Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. + - 2015/04/09 (1.38) - renamed ImDrawList::AddArc() to ImDrawList::AddArcFast() for compatibility with future API, and changed 2*PI range from 0..12 to 0..16 - 2015/04/03 (1.38) - removed ImGuiCol_CheckHovered, ImGuiCol_CheckActive, replaced with the more general ImGuiCol_FrameBgHovered, ImGuiCol_FrameBgActive. - 2014/04/03 (1.38) - removed support for passing -FLT_MAX..+FLT_MAX as the range for a SliderFloat(). Use DragFloat() or Inputfloat() instead. - 2015/03/17 (1.36) - renamed GetItemRectMin()/GetItemRectMax()/IsMouseHoveringBox() to GetItemRectMin()/GetItemRectMax()/IsMouseHoveringRect(). Kept inline redirection function (will obsolete). @@ -3328,7 +3329,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_ else { // FIXME: We should draw 4 triangles and decide on a size that's not dependent on the rounding size (previously used 18) - window->DrawList->AddArc(br - ImVec2(r,r), r, resize_col, 6, 9, true); + window->DrawList->AddArcFast(br - ImVec2(r,r), r, resize_col, 8, 12, true); window->DrawList->AddTriangleFilled(br+ImVec2(0,-2*r),br+ImVec2(0,-r),br+ImVec2(-r,-r), resize_col); window->DrawList->AddTriangleFilled(br+ImVec2(-r,-r), br+ImVec2(-r,0),br+ImVec2(-2*r,0), resize_col); } @@ -7750,18 +7751,18 @@ void ImDrawList::AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thic AddVtxLine(a, b, col, thickness); } -void ImDrawList::AddArc(const ImVec2& center, float rad, ImU32 col, int a_min, int a_max, bool tris, const ImVec2& third_point_offset) +void ImDrawList::AddArcFast(const ImVec2& center, float rad, ImU32 col, int a_min, int a_max, bool tris, const ImVec2& third_point_offset) { if ((col >> 24) == 0) return; - static ImVec2 circle_vtx[12]; + static ImVec2 circle_vtx[16]; static bool circle_vtx_builds = false; if (!circle_vtx_builds) { - for (int i = 0; i < IM_ARRAYSIZE(circle_vtx); i++) + for (int i = 0; i < 16; i++) { - const float a = ((float)i / (float)IM_ARRAYSIZE(circle_vtx)) * 2*PI; + const float a = ((float)i / (float)16.0f) * 2*PI; circle_vtx[i].x = cosf(a + PI); circle_vtx[i].y = sinf(a + PI); } @@ -7773,8 +7774,8 @@ void ImDrawList::AddArc(const ImVec2& center, float rad, ImU32 col, int a_min, i ReserveVertices((unsigned int)(a_max-a_min) * 3); for (int a = a_min; a < a_max; a++) { - AddVtx(center + circle_vtx[a % IM_ARRAYSIZE(circle_vtx)] * rad, col); - AddVtx(center + circle_vtx[(a+1) % IM_ARRAYSIZE(circle_vtx)] * rad, col); + AddVtx(center + circle_vtx[a & 15] * rad, col); + AddVtx(center + circle_vtx[(a+1) & 15] * rad, col); AddVtx(center + third_point_offset, col); } } @@ -7782,7 +7783,7 @@ void ImDrawList::AddArc(const ImVec2& center, float rad, ImU32 col, int a_min, i { ReserveVertices((unsigned int)(a_max-a_min) * 6); for (int a = a_min; a < a_max; a++) - AddVtxLine(center + circle_vtx[a % IM_ARRAYSIZE(circle_vtx)] * rad, center + circle_vtx[(a+1) % IM_ARRAYSIZE(circle_vtx)] * rad, col); + AddVtxLine(center + circle_vtx[a & 15] * rad, center + circle_vtx[(a+1) & 15] * rad, col); } } @@ -7811,10 +7812,10 @@ void ImDrawList::AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float roun AddVtxLine(ImVec2(b.x - ((rounding_corners & 4)?r:0), b.y), ImVec2(a.x + ((rounding_corners & 8)?r:0), b.y), col); AddVtxLine(ImVec2(a.x, b.y - ((rounding_corners & 8)?r:0)), ImVec2(a.x, a.y + ((rounding_corners & 1)?r:0)), col); - if (rounding_corners & 1) AddArc(ImVec2(a.x+r,a.y+r), r, col, 0, 3); - if (rounding_corners & 2) AddArc(ImVec2(b.x-r,a.y+r), r, col, 3, 6); - if (rounding_corners & 4) AddArc(ImVec2(b.x-r,b.y-r), r, col, 6, 9); - if (rounding_corners & 8) AddArc(ImVec2(a.x+r,b.y-r), r, col, 9, 12); + if (rounding_corners & 1) AddArcFast(ImVec2(a.x+r,a.y+r), r, col, 0, 4); + if (rounding_corners & 2) AddArcFast(ImVec2(b.x-r,a.y+r), r, col, 4, 8); + if (rounding_corners & 4) AddArcFast(ImVec2(b.x-r,b.y-r), r, col, 8, 12); + if (rounding_corners & 8) AddArcFast(ImVec2(a.x+r,b.y-r), r, col, 12, 16); } } @@ -7866,10 +7867,10 @@ void ImDrawList::AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, floa AddVtx(ImVec2(b.x,bot_y), col); AddVtx(ImVec2(b.x-r,bot_y), col); - if (rounding_corners & 1) AddArc(ImVec2(a.x+r,a.y+r), r, col, 0, 3, true); - if (rounding_corners & 2) AddArc(ImVec2(b.x-r,a.y+r), r, col, 3, 6, true); - if (rounding_corners & 4) AddArc(ImVec2(b.x-r,b.y-r), r, col, 6, 9, true); - if (rounding_corners & 8) AddArc(ImVec2(a.x+r,b.y-r), r, col, 9, 12,true); + if (rounding_corners & 1) AddArcFast(ImVec2(a.x+r,a.y+r), r, col, 0, 4, true); + if (rounding_corners & 2) AddArcFast(ImVec2(b.x-r,a.y+r), r, col, 4, 8, true); + if (rounding_corners & 4) AddArcFast(ImVec2(b.x-r,b.y-r), r, col, 8, 12, true); + if (rounding_corners & 8) AddArcFast(ImVec2(a.x+r,b.y-r), r, col, 12, 16, true); } } diff --git a/imgui.h b/imgui.h index 5c48b82c..96c374be 100644 --- a/imgui.h +++ b/imgui.h @@ -913,7 +913,7 @@ struct ImDrawList IMGUI_API void AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col); IMGUI_API void AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); IMGUI_API void AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); - IMGUI_API void AddArc(const ImVec2& center, float rad, ImU32 col, int a_min, int a_max, bool tris = false, const ImVec2& third_point_offset = ImVec2(0,0)); + IMGUI_API void AddArcFast(const ImVec2& center, float rad, ImU32 col, int a_min_of_16, int a_max_of_16, bool tris = false, const ImVec2& third_point_offset = ImVec2(0,0)); // Angles in 0..16 range IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec2* cpu_clip_max = NULL); IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv0, const ImVec2& uv1, ImU32 col = 0xFFFFFFFF); From 2bb6e31520861034bcc2a630a90c104ca60815b4 Mon Sep 17 00:00:00 2001 From: Stephan Dilly Date: Thu, 9 Apr 2015 16:50:54 +0200 Subject: [PATCH 03/15] fix unused variable warning by clang --- imgui.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 7171dd8b..935399d6 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9786,7 +9786,6 @@ void ImGui::ShowTestWindow(bool* opened) static float f1=1.123f; static float f2=0; - static float f3=123456789.0f; ImGui::SliderFloat("slider float", &f1, 0.0f, 2.0f); ImGui::SliderFloat("slider log float", &f2, -10.0f, 10.0f, "%.4f", 3.0f); static float angle = 0.0f; From 0fc1f5b17ff271c4e0ef8a3e3330281558406fb4 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 9 Apr 2015 16:45:14 +0100 Subject: [PATCH 04/15] Revert AddArcFast()->AddArc(), removed modulo from function 200d3482dcb94e0cf886863fbb95770f35f9ba43 --- imgui.cpp | 43 ++++++++++++++++++++++++------------------- imgui.h | 2 +- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7171dd8b..9fa96cad 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -135,7 +135,7 @@ Occasionally introducing changes that are breaking the API. The breakage are generally minor and easy to fix. Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. - - 2015/04/09 (1.38) - renamed ImDrawList::AddArc() to ImDrawList::AddArcFast() for compatibility with future API, and changed 2*PI range from 0..12 to 0..16 + - 2015/04/09 (1.38) - renamed ImDrawList::AddArc() to ImDrawList::AddArcFast() for compatibility with future API - 2015/04/03 (1.38) - removed ImGuiCol_CheckHovered, ImGuiCol_CheckActive, replaced with the more general ImGuiCol_FrameBgHovered, ImGuiCol_FrameBgActive. - 2014/04/03 (1.38) - removed support for passing -FLT_MAX..+FLT_MAX as the range for a SliderFloat(). Use DragFloat() or Inputfloat() instead. - 2015/03/17 (1.36) - renamed GetItemRectMin()/GetItemRectMax()/IsMouseHoveringBox() to GetItemRectMin()/GetItemRectMax()/IsMouseHoveringRect(). Kept inline redirection function (will obsolete). @@ -3329,7 +3329,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_ else { // FIXME: We should draw 4 triangles and decide on a size that's not dependent on the rounding size (previously used 18) - window->DrawList->AddArcFast(br - ImVec2(r,r), r, resize_col, 8, 12, true); + window->DrawList->AddArcFast(br - ImVec2(r,r), r, resize_col, 6, 9, true); window->DrawList->AddTriangleFilled(br+ImVec2(0,-2*r),br+ImVec2(0,-r),br+ImVec2(-r,-r), resize_col); window->DrawList->AddTriangleFilled(br+ImVec2(-r,-r), br+ImVec2(-r,0),br+ImVec2(-2*r,0), resize_col); } @@ -7751,18 +7751,19 @@ void ImDrawList::AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thic AddVtxLine(a, b, col, thickness); } -void ImDrawList::AddArcFast(const ImVec2& center, float rad, ImU32 col, int a_min, int a_max, bool tris, const ImVec2& third_point_offset) +void ImDrawList::AddArcFast(const ImVec2& center, float radius, ImU32 col, int a_min, int a_max, bool tris, const ImVec2& third_point_offset) { if ((col >> 24) == 0) return; - static ImVec2 circle_vtx[16]; + const int SAMPLES = 12; + static ImVec2 circle_vtx[SAMPLES]; static bool circle_vtx_builds = false; if (!circle_vtx_builds) { - for (int i = 0; i < 16; i++) + for (int i = 0; i < SAMPLES; i++) { - const float a = ((float)i / (float)16.0f) * 2*PI; + const float a = ((float)i / (float)SAMPLES) * 2*PI; circle_vtx[i].x = cosf(a + PI); circle_vtx[i].y = sinf(a + PI); } @@ -7772,18 +7773,22 @@ void ImDrawList::AddArcFast(const ImVec2& center, float rad, ImU32 col, int a_mi if (tris) { ReserveVertices((unsigned int)(a_max-a_min) * 3); - for (int a = a_min; a < a_max; a++) + for (int a0 = a_min; a0 < a_max; a0++) { - AddVtx(center + circle_vtx[a & 15] * rad, col); - AddVtx(center + circle_vtx[(a+1) & 15] * rad, col); + int a1 = (a0 + 1 == SAMPLES) ? 0 : a0 + 1; + AddVtx(center + circle_vtx[a0] * radius, col); + AddVtx(center + circle_vtx[a1] * radius, col); AddVtx(center + third_point_offset, col); } } else { ReserveVertices((unsigned int)(a_max-a_min) * 6); - for (int a = a_min; a < a_max; a++) - AddVtxLine(center + circle_vtx[a & 15] * rad, center + circle_vtx[(a+1) & 15] * rad, col); + for (int a0 = a_min; a0 < a_max; a0++) + { + int a1 = (a0 + 1 == SAMPLES) ? 0 : a0 + 1; + AddVtxLine(center + circle_vtx[a0] * radius, center + circle_vtx[a1] * radius, col); + } } } @@ -7812,10 +7817,10 @@ void ImDrawList::AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float roun AddVtxLine(ImVec2(b.x - ((rounding_corners & 4)?r:0), b.y), ImVec2(a.x + ((rounding_corners & 8)?r:0), b.y), col); AddVtxLine(ImVec2(a.x, b.y - ((rounding_corners & 8)?r:0)), ImVec2(a.x, a.y + ((rounding_corners & 1)?r:0)), col); - if (rounding_corners & 1) AddArcFast(ImVec2(a.x+r,a.y+r), r, col, 0, 4); - if (rounding_corners & 2) AddArcFast(ImVec2(b.x-r,a.y+r), r, col, 4, 8); - if (rounding_corners & 4) AddArcFast(ImVec2(b.x-r,b.y-r), r, col, 8, 12); - if (rounding_corners & 8) AddArcFast(ImVec2(a.x+r,b.y-r), r, col, 12, 16); + if (rounding_corners & 1) AddArcFast(ImVec2(a.x+r,a.y+r), r, col, 0, 3); + if (rounding_corners & 2) AddArcFast(ImVec2(b.x-r,a.y+r), r, col, 3, 6); + if (rounding_corners & 4) AddArcFast(ImVec2(b.x-r,b.y-r), r, col, 6, 9); + if (rounding_corners & 8) AddArcFast(ImVec2(a.x+r,b.y-r), r, col, 9, 12); } } @@ -7867,10 +7872,10 @@ void ImDrawList::AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, floa AddVtx(ImVec2(b.x,bot_y), col); AddVtx(ImVec2(b.x-r,bot_y), col); - if (rounding_corners & 1) AddArcFast(ImVec2(a.x+r,a.y+r), r, col, 0, 4, true); - if (rounding_corners & 2) AddArcFast(ImVec2(b.x-r,a.y+r), r, col, 4, 8, true); - if (rounding_corners & 4) AddArcFast(ImVec2(b.x-r,b.y-r), r, col, 8, 12, true); - if (rounding_corners & 8) AddArcFast(ImVec2(a.x+r,b.y-r), r, col, 12, 16, true); + if (rounding_corners & 1) AddArcFast(ImVec2(a.x+r,a.y+r), r, col, 0, 3, true); + if (rounding_corners & 2) AddArcFast(ImVec2(b.x-r,a.y+r), r, col, 3, 6, true); + if (rounding_corners & 4) AddArcFast(ImVec2(b.x-r,b.y-r), r, col, 6, 8, true); + if (rounding_corners & 8) AddArcFast(ImVec2(a.x+r,b.y-r), r, col, 9, 12, true); } } diff --git a/imgui.h b/imgui.h index 96c374be..0188146a 100644 --- a/imgui.h +++ b/imgui.h @@ -913,7 +913,7 @@ struct ImDrawList IMGUI_API void AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col); IMGUI_API void AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); IMGUI_API void AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); - IMGUI_API void AddArcFast(const ImVec2& center, float rad, ImU32 col, int a_min_of_16, int a_max_of_16, bool tris = false, const ImVec2& third_point_offset = ImVec2(0,0)); // Angles in 0..16 range + IMGUI_API void AddArcFast(const ImVec2& center, float radius, ImU32 col, int a_min_12, int a_max_12, bool tris = false, const ImVec2& third_point_offset = ImVec2(0,0)); // Angles in 0..12 range IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec2* cpu_clip_max = NULL); IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv0, const ImVec2& uv1, ImU32 col = 0xFFFFFFFF); From aa2935968ed73072b515003715e36ba9c8ee2dc8 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 9 Apr 2015 16:47:20 +0100 Subject: [PATCH 05/15] Renamed AddArcFast() parameter 'tris' to 'filled' --- imgui.cpp | 4 ++-- imgui.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 536bc7a6..b222dfd1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7751,7 +7751,7 @@ void ImDrawList::AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thic AddVtxLine(a, b, col, thickness); } -void ImDrawList::AddArcFast(const ImVec2& center, float radius, ImU32 col, int a_min, int a_max, bool tris, const ImVec2& third_point_offset) +void ImDrawList::AddArcFast(const ImVec2& center, float radius, ImU32 col, int a_min, int a_max, bool filled, const ImVec2& third_point_offset) { if ((col >> 24) == 0) return; @@ -7770,7 +7770,7 @@ void ImDrawList::AddArcFast(const ImVec2& center, float radius, ImU32 col, int a circle_vtx_builds = true; } - if (tris) + if (filled) { ReserveVertices((unsigned int)(a_max-a_min) * 3); for (int a0 = a_min; a0 < a_max; a0++) diff --git a/imgui.h b/imgui.h index 0188146a..67761308 100644 --- a/imgui.h +++ b/imgui.h @@ -913,7 +913,7 @@ struct ImDrawList IMGUI_API void AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col); IMGUI_API void AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); IMGUI_API void AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); - IMGUI_API void AddArcFast(const ImVec2& center, float radius, ImU32 col, int a_min_12, int a_max_12, bool tris = false, const ImVec2& third_point_offset = ImVec2(0,0)); // Angles in 0..12 range + IMGUI_API void AddArcFast(const ImVec2& center, float radius, ImU32 col, int a_min_12, int a_max_12, bool filled = false, const ImVec2& third_point_offset = ImVec2(0,0)); // Angles in 0..12 range IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec2* cpu_clip_max = NULL); IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv0, const ImVec2& uv1, ImU32 col = 0xFFFFFFFF); From 15f82e0debdc9ab00aaa0186291d8b0f84071767 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 9 Apr 2015 17:20:57 +0100 Subject: [PATCH 06/15] Fix rounded frames to follow previous change --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index b222dfd1..3f0d3a86 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7874,7 +7874,7 @@ void ImDrawList::AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, floa if (rounding_corners & 1) AddArcFast(ImVec2(a.x+r,a.y+r), r, col, 0, 3, true); if (rounding_corners & 2) AddArcFast(ImVec2(b.x-r,a.y+r), r, col, 3, 6, true); - if (rounding_corners & 4) AddArcFast(ImVec2(b.x-r,b.y-r), r, col, 6, 8, true); + if (rounding_corners & 4) AddArcFast(ImVec2(b.x-r,b.y-r), r, col, 6, 9, true); if (rounding_corners & 8) AddArcFast(ImVec2(a.x+r,b.y-r), r, col, 9, 12, true); } } From 742808d835b8003e6d14ca53b0f16800ca98d7a4 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 9 Apr 2015 17:24:09 +0100 Subject: [PATCH 07/15] Tweaks. --- imgui.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 3f0d3a86..7b90d2fc 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7700,13 +7700,10 @@ void ImDrawList::PopTextureID() void ImDrawList::ReserveVertices(unsigned int vtx_count) { - if (vtx_count > 0) - { - ImDrawCmd& draw_cmd = commands.back(); - draw_cmd.vtx_count += vtx_count; - vtx_buffer.resize(vtx_buffer.size() + vtx_count); - vtx_write = &vtx_buffer[vtx_buffer.size() - vtx_count]; - } + ImDrawCmd& draw_cmd = commands.back(); + draw_cmd.vtx_count += vtx_count; + vtx_buffer.resize(vtx_buffer.size() + vtx_count); + vtx_write = &vtx_buffer[vtx_buffer.size() - vtx_count]; } void ImDrawList::AddVtx(const ImVec2& pos, ImU32 col) @@ -7931,6 +7928,8 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, if (text_end == NULL) text_end = text_begin + strlen(text_begin); + if (text_begin == text_end) + return; IM_ASSERT(font->ContainerAtlas->TexID == texture_id_stack.back()); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font. From 707df6c7b70ce9b0ae38a5803791ea0127a10d20 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 9 Apr 2015 17:32:03 +0100 Subject: [PATCH 08/15] ImDrawList: internal refactoring toward a following commit for indexed rendering. --- imgui.cpp | 181 ++++++++++++++++++++++++++++-------------------------- imgui.h | 21 ++++--- 2 files changed, 106 insertions(+), 96 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7b90d2fc..6d9d4328 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7698,45 +7698,71 @@ void ImDrawList::PopTextureID() UpdateTextureID(); } -void ImDrawList::ReserveVertices(unsigned int vtx_count) +void ImDrawList::PrimReserve(unsigned int vtx_count) { ImDrawCmd& draw_cmd = commands.back(); draw_cmd.vtx_count += vtx_count; - vtx_buffer.resize(vtx_buffer.size() + vtx_count); - vtx_write = &vtx_buffer[vtx_buffer.size() - vtx_count]; + + size_t vtx_buffer_size = vtx_buffer.size(); + vtx_buffer.resize(vtx_buffer_size + vtx_count); + vtx_write = &vtx_buffer[vtx_buffer_size]; } -void ImDrawList::AddVtx(const ImVec2& pos, ImU32 col) +void ImDrawList::PrimTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col) { - vtx_write->pos = pos; - vtx_write->col = col; - vtx_write->uv = GImGui->FontTexUvWhitePixel; - vtx_write++; + const ImVec2 uv = GImGui->FontTexUvWhitePixel; + AddVtx(a, uv, col); + AddVtx(b, uv, col); + AddVtx(c, uv, col); } -void ImDrawList::AddVtxUV(const ImVec2& pos, ImU32 col, const ImVec2& uv) +void ImDrawList::PrimRect(const ImVec2& a, const ImVec2& c, ImU32 col) { - vtx_write->pos = pos; - vtx_write->col = col; - vtx_write->uv = uv; - vtx_write++; + const ImVec2 uv = GImGui->FontTexUvWhitePixel; + ImVec2 b(c.x, a.y); + ImVec2 d(a.x, c.y); + AddVtx(a, uv, col); + AddVtx(b, uv, col); + AddVtx(c, uv, col); + AddVtx(a, uv, col); + AddVtx(c, uv, col); + AddVtx(d, uv, col); } -// NB: memory should be reserved for 6 vertices by the caller. -void ImDrawList::AddVtxLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness) +void ImDrawList::PrimRectUV(const ImVec2& a, const ImVec2& c, const ImVec2& uv_a, const ImVec2& uv_c, ImU32 col) +{ + ImVec2 b(c.x, a.y); + ImVec2 d(a.x, c.y); + ImVec2 uv_b(uv_c.x, uv_a.y); + ImVec2 uv_d(uv_a.x, uv_c.y); + AddVtx(a, uv_a, col); + AddVtx(b, uv_b, col); + AddVtx(c, uv_c, col); + AddVtx(a, uv_a, col); + AddVtx(c, uv_c, col); + AddVtx(d, uv_d, col); +} + +void ImDrawList::PrimQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col) +{ + const ImVec2 uv = GImGui->FontTexUvWhitePixel; + AddVtx(a, uv, col); + AddVtx(b, uv, col); + AddVtx(c, uv, col); + AddVtx(a, uv, col); + AddVtx(c, uv, col); + AddVtx(d, uv, col); +} + +// FIXME-OPT: In many instances the caller could provide a normal. +void ImDrawList::PrimLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness) { const float inv_length = 1.0f / sqrtf(ImLengthSqr(b - a)); - const ImVec2 hn = (b - a) * (thickness * 0.5f * inv_length);// half normal + const ImVec2 hn = (b - a) * (thickness * 0.5f * inv_length);// half normalized const ImVec2 hp0 = ImVec2(+hn.y, -hn.x); // half perpendiculars + user offset const ImVec2 hp1 = ImVec2(-hn.y, +hn.x); - // Two triangles makes up one line. Using triangles allows us to reduce amount of draw calls. - AddVtx(a + hp0, col); - AddVtx(b + hp0, col); - AddVtx(a + hp1, col); - AddVtx(b + hp0, col); - AddVtx(b + hp1, col); - AddVtx(a + hp1, col); + PrimQuad(a + hp0, b + hp0, b + hp1, a + hp1, col); } void ImDrawList::AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness) @@ -7744,8 +7770,8 @@ void ImDrawList::AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thic if ((col >> 24) == 0) return; - ReserveVertices(6); - AddVtxLine(a, b, col, thickness); + PrimReserve(6); + PrimLine(a, b, col, thickness); } void ImDrawList::AddArcFast(const ImVec2& center, float radius, ImU32 col, int a_min, int a_max, bool filled, const ImVec2& third_point_offset) @@ -7767,24 +7793,25 @@ void ImDrawList::AddArcFast(const ImVec2& center, float radius, ImU32 col, int a circle_vtx_builds = true; } + const ImVec2 uv = GImGui->FontTexUvWhitePixel; if (filled) { - ReserveVertices((unsigned int)(a_max-a_min) * 3); + PrimReserve((unsigned int)(a_max-a_min) * 3); for (int a0 = a_min; a0 < a_max; a0++) { int a1 = (a0 + 1 == SAMPLES) ? 0 : a0 + 1; - AddVtx(center + circle_vtx[a0] * radius, col); - AddVtx(center + circle_vtx[a1] * radius, col); - AddVtx(center + third_point_offset, col); + AddVtx(center + circle_vtx[a0] * radius, uv, col); + AddVtx(center + circle_vtx[a1] * radius, uv, col); + AddVtx(center + third_point_offset, uv, col); } } else { - ReserveVertices((unsigned int)(a_max-a_min) * 6); + PrimReserve((unsigned int)(a_max-a_min) * 6); for (int a0 = a_min; a0 < a_max; a0++) { int a1 = (a0 + 1 == SAMPLES) ? 0 : a0 + 1; - AddVtxLine(center + circle_vtx[a0] * radius, center + circle_vtx[a1] * radius, col); + PrimLine(center + circle_vtx[a0] * radius, center + circle_vtx[a1] * radius, col); } } } @@ -7800,19 +7827,19 @@ void ImDrawList::AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float roun if (r == 0.0f || rounding_corners == 0) { - ReserveVertices(4*6); - AddVtxLine(ImVec2(a.x,a.y), ImVec2(b.x,a.y), col); - AddVtxLine(ImVec2(b.x,a.y), ImVec2(b.x,b.y), col); - AddVtxLine(ImVec2(b.x,b.y), ImVec2(a.x,b.y), col); - AddVtxLine(ImVec2(a.x,b.y), ImVec2(a.x,a.y), col); + PrimReserve(4*6); + PrimLine(ImVec2(a.x,a.y), ImVec2(b.x,a.y), col); + PrimLine(ImVec2(b.x,a.y), ImVec2(b.x,b.y), col); + PrimLine(ImVec2(b.x,b.y), ImVec2(a.x,b.y), col); + PrimLine(ImVec2(a.x,b.y), ImVec2(a.x,a.y), col); } else { - ReserveVertices(4*6); - AddVtxLine(ImVec2(a.x + ((rounding_corners & 1)?r:0), a.y), ImVec2(b.x - ((rounding_corners & 2)?r:0), a.y), col); - AddVtxLine(ImVec2(b.x, a.y + ((rounding_corners & 2)?r:0)), ImVec2(b.x, b.y - ((rounding_corners & 4)?r:0)), col); - AddVtxLine(ImVec2(b.x - ((rounding_corners & 4)?r:0), b.y), ImVec2(a.x + ((rounding_corners & 8)?r:0), b.y), col); - AddVtxLine(ImVec2(a.x, b.y - ((rounding_corners & 8)?r:0)), ImVec2(a.x, a.y + ((rounding_corners & 1)?r:0)), col); + PrimReserve(4*6); + PrimLine(ImVec2(a.x + ((rounding_corners & 1)?r:0), a.y), ImVec2(b.x - ((rounding_corners & 2)?r:0), a.y), col); + PrimLine(ImVec2(b.x, a.y + ((rounding_corners & 2)?r:0)), ImVec2(b.x, b.y - ((rounding_corners & 4)?r:0)), col); + PrimLine(ImVec2(b.x - ((rounding_corners & 4)?r:0), b.y), ImVec2(a.x + ((rounding_corners & 8)?r:0), b.y), col); + PrimLine(ImVec2(a.x, b.y - ((rounding_corners & 8)?r:0)), ImVec2(a.x, a.y + ((rounding_corners & 1)?r:0)), col); if (rounding_corners & 1) AddArcFast(ImVec2(a.x+r,a.y+r), r, col, 0, 3); if (rounding_corners & 2) AddArcFast(ImVec2(b.x-r,a.y+r), r, col, 3, 6); @@ -7830,44 +7857,25 @@ void ImDrawList::AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, floa r = ImMin(r, fabsf(b.x-a.x) * ( ((rounding_corners&(1|2))==(1|2)) || ((rounding_corners&(4|8))==(4|8)) ? 0.5f : 1.0f )); r = ImMin(r, fabsf(b.y-a.y) * ( ((rounding_corners&(1|8))==(1|8)) || ((rounding_corners&(2|4))==(2|4)) ? 0.5f : 1.0f )); + const ImVec2 uv = GImGui->FontTexUvWhitePixel; if (r == 0.0f || rounding_corners == 0) { // Use triangle so we can merge more draw calls together (at the cost of extra vertices) - ReserveVertices(6); - AddVtx(ImVec2(a.x,a.y), col); - AddVtx(ImVec2(b.x,a.y), col); - AddVtx(ImVec2(b.x,b.y), col); - AddVtx(ImVec2(a.x,a.y), col); - AddVtx(ImVec2(b.x,b.y), col); - AddVtx(ImVec2(a.x,b.y), col); + PrimReserve(6); + PrimRect(a, b, col); } else { - ReserveVertices(6+6*2); - AddVtx(ImVec2(a.x+r,a.y), col); - AddVtx(ImVec2(b.x-r,a.y), col); - AddVtx(ImVec2(b.x-r,b.y), col); - AddVtx(ImVec2(a.x+r,a.y), col); - AddVtx(ImVec2(b.x-r,b.y), col); - AddVtx(ImVec2(a.x+r,b.y), col); + PrimReserve(6+6*2); + PrimRect(ImVec2(a.x+r,a.y), ImVec2(b.x-r,b.y), col); float top_y = (rounding_corners & 1) ? a.y+r : a.y; float bot_y = (rounding_corners & 8) ? b.y-r : b.y; - AddVtx(ImVec2(a.x,top_y), col); - AddVtx(ImVec2(a.x+r,top_y), col); - AddVtx(ImVec2(a.x+r,bot_y), col); - AddVtx(ImVec2(a.x,top_y), col); - AddVtx(ImVec2(a.x+r,bot_y), col); - AddVtx(ImVec2(a.x,bot_y), col); + PrimRect(ImVec2(a.x,top_y), ImVec2(a.x+r,bot_y), col); top_y = (rounding_corners & 2) ? a.y+r : a.y; bot_y = (rounding_corners & 4) ? b.y-r : b.y; - AddVtx(ImVec2(b.x-r,top_y), col); - AddVtx(ImVec2(b.x,top_y), col); - AddVtx(ImVec2(b.x,bot_y), col); - AddVtx(ImVec2(b.x-r,top_y), col); - AddVtx(ImVec2(b.x,bot_y), col); - AddVtx(ImVec2(b.x-r,bot_y), col); + PrimRect(ImVec2(b.x-r,top_y), ImVec2(b.x,bot_y), col); if (rounding_corners & 1) AddArcFast(ImVec2(a.x+r,a.y+r), r, col, 0, 3, true); if (rounding_corners & 2) AddArcFast(ImVec2(b.x-r,a.y+r), r, col, 3, 6, true); @@ -7881,10 +7889,8 @@ void ImDrawList::AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec if ((col >> 24) == 0) return; - ReserveVertices(3); - AddVtx(a, col); - AddVtx(b, col); - AddVtx(c, col); + PrimReserve(3); + PrimTriangle(a, b, c, col); } void ImDrawList::AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments) @@ -7892,13 +7898,13 @@ void ImDrawList::AddCircle(const ImVec2& centre, float radius, ImU32 col, int nu if ((col >> 24) == 0) return; - ReserveVertices((unsigned int)num_segments*6); + PrimReserve((unsigned int)num_segments*6); const float a_step = 2*PI/(float)num_segments; float a0 = 0.0f; for (int i = 0; i < num_segments; i++) { const float a1 = (i + 1) == num_segments ? 0.0f : a0 + a_step; - AddVtxLine(centre + ImVec2(cosf(a0), sinf(a0))*radius, centre + ImVec2(cosf(a1), sinf(a1))*radius, col); + PrimLine(centre + ImVec2(cosf(a0), sinf(a0))*radius, centre + ImVec2(cosf(a1), sinf(a1))*radius, col); a0 = a1; } } @@ -7908,15 +7914,16 @@ void ImDrawList::AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, if ((col >> 24) == 0) return; - ReserveVertices((unsigned int)num_segments*3); + const ImVec2 uv = GImGui->FontTexUvWhitePixel; + PrimReserve((unsigned int)num_segments*3); const float a_step = 2*PI/(float)num_segments; float a0 = 0.0f; for (int i = 0; i < num_segments; i++) { const float a1 = (i + 1) == num_segments ? 0.0f : a0 + a_step; - AddVtx(centre + ImVec2(cosf(a0), sinf(a0))*radius, col); - AddVtx(centre + ImVec2(cosf(a1), sinf(a1))*radius, col); - AddVtx(centre, col); + AddVtx(centre + ImVec2(cosf(a0), sinf(a0))*radius, uv, col); + AddVtx(centre + ImVec2(cosf(a1), sinf(a1))*radius, uv, col); + AddVtx(centre, uv, col); a0 = a1; } } @@ -7937,9 +7944,9 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, const unsigned int char_count = (unsigned int)(text_end - text_begin); const unsigned int vtx_count_max = char_count * 6; const size_t vtx_begin = vtx_buffer.size(); - ReserveVertices(vtx_count_max); + PrimReserve(vtx_count_max); - font->RenderText(font_size, pos, col, clip_rect_stack.back(), text_begin, text_end, vtx_write, wrap_width, cpu_clip_max); + font->RenderText(font_size, pos, col, clip_rect_stack.back(), text_begin, text_end, this, wrap_width, cpu_clip_max); // give back unused vertices vtx_buffer.resize((size_t)(vtx_write - &vtx_buffer.front())); @@ -7958,13 +7965,8 @@ void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& a, const Im if (push_texture_id) PushTextureID(user_texture_id); - ReserveVertices(6); - AddVtxUV(ImVec2(a.x,a.y), col, uv0); - AddVtxUV(ImVec2(b.x,a.y), col, ImVec2(uv1.x,uv0.y)); - AddVtxUV(ImVec2(b.x,b.y), col, uv1); - AddVtxUV(ImVec2(a.x,a.y), col, ImVec2(uv0.x,uv0.y)); - AddVtxUV(ImVec2(b.x,b.y), col, uv1); - AddVtxUV(ImVec2(a.x,b.y), col, ImVec2(uv0.x,uv1.y)); + PrimReserve(6); + PrimRectUV(a, b, uv0, uv1, col); if (push_texture_id) PopTextureID(); @@ -8980,7 +8982,7 @@ ImVec2 ImFont::CalcTextSizeW(float size, float max_width, const ImWchar* text_be return text_size; } -void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect_ref, const char* text_begin, const char* text_end, ImDrawVert*& out_vertices, float wrap_width, const ImVec2* cpu_clip_max) const +void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect_ref, const char* text_begin, const char* text_end, ImDrawList* draw_list, float wrap_width, const ImVec2* cpu_clip_max) const { if (!text_end) text_end = text_begin + strlen(text_begin); @@ -9004,6 +9006,8 @@ void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_re float x = pos.x; float y = pos.y; + ImDrawVert* out_vertices = draw_list->vtx_write; + const char* s = text_begin; while (s < text_end) { @@ -9091,6 +9095,7 @@ void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_re } } + // NB: we are not calling PrimRectUV() here because non-inlined causes too much overhead in a debug build. out_vertices[0].pos = ImVec2(x1, y1); out_vertices[0].uv = ImVec2(u1, v1); out_vertices[0].col = col; @@ -9118,6 +9123,8 @@ void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_re x += char_width; } + + draw_list->vtx_write = out_vertices; } //----------------------------------------------------------------------------- diff --git a/imgui.h b/imgui.h index 67761308..9866b2a6 100644 --- a/imgui.h +++ b/imgui.h @@ -908,8 +908,8 @@ struct ImDrawList // Primitives IMGUI_API void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f); - IMGUI_API void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners=0x0F); - IMGUI_API void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners=0x0F); + IMGUI_API void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners = 0x0F); + IMGUI_API void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners = 0x0F); IMGUI_API void AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col); IMGUI_API void AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); IMGUI_API void AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); @@ -918,16 +918,19 @@ struct ImDrawList IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv0, const ImVec2& uv1, ImU32 col = 0xFFFFFFFF); // Advanced - IMGUI_API void AddCallback(ImDrawCallback callback, void* callback_data); // Your rendering function must check for 'user_callback' in ImDrawCmd and call the function instead of rendering triangles. - IMGUI_API void AddDrawCmd(); // This is useful if you need to forcefully create a new draw call (to allow for dependent rendering / blending). Otherwise primitives are merged into the same draw-call as much as possible + IMGUI_API void AddCallback(ImDrawCallback callback, void* callback_data); // Your rendering function must check for 'user_callback' in ImDrawCmd and call the function instead of rendering triangles. + IMGUI_API void AddDrawCmd(); // This is useful if you need to forcefully create a new draw call (to allow for dependent rendering / blending). Otherwise primitives are merged into the same draw-call as much as possible // Internal helpers - IMGUI_API void ReserveVertices(unsigned int vtx_count); - IMGUI_API void AddVtx(const ImVec2& pos, ImU32 col); - IMGUI_API void AddVtxUV(const ImVec2& pos, ImU32 col, const ImVec2& uv); - IMGUI_API void AddVtxLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f); + IMGUI_API void PrimReserve(unsigned int vtx_count); + IMGUI_API void PrimTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col); + IMGUI_API void PrimRect(const ImVec2& a, const ImVec2& b, ImU32 col); + IMGUI_API void PrimRectUV(const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col); + IMGUI_API void PrimQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col); + IMGUI_API void PrimLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f); IMGUI_API void UpdateClipRect(); IMGUI_API void UpdateTextureID(); + inline IMGUI_API void AddVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { vtx_write->pos = pos; vtx_write->uv = uv; vtx_write->col = col; vtx_write++; } }; // Load and rasterize multiple TTF fonts into a same texture. @@ -1021,7 +1024,7 @@ struct ImFont // 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable. IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8 IMGUI_API ImVec2 CalcTextSizeW(float size, float max_width, const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL) const; // wchar - IMGUI_API void RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, ImDrawVert*& out_vertices, float wrap_width = 0.0f, const ImVec2* cpu_clip_max = NULL) const; + IMGUI_API void RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, ImDrawList* draw_list, float wrap_width = 0.0f, const ImVec2* cpu_clip_max = NULL) const; IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const; }; From 334fba2f567713370e56665660ad05ecd5502811 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 9 Apr 2015 17:33:17 +0100 Subject: [PATCH 09/15] Spacing --- imgui.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/imgui.h b/imgui.h index 9866b2a6..4f4f8395 100644 --- a/imgui.h +++ b/imgui.h @@ -1014,18 +1014,18 @@ struct ImFont // Methods IMGUI_API ImFont(); IMGUI_API ~ImFont(); - IMGUI_API void Clear(); - IMGUI_API void BuildLookupTable(); - IMGUI_API const Glyph* FindGlyph(unsigned short c) const; - IMGUI_API void SetFallbackChar(ImWchar c); - IMGUI_API bool IsLoaded() const { return ContainerAtlas != NULL; } + IMGUI_API void Clear(); + IMGUI_API void BuildLookupTable(); + IMGUI_API const Glyph* FindGlyph(unsigned short c) const; + IMGUI_API void SetFallbackChar(ImWchar c); + IMGUI_API bool IsLoaded() const { return ContainerAtlas != NULL; } // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable. // 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable. - IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8 - IMGUI_API ImVec2 CalcTextSizeW(float size, float max_width, const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL) const; // wchar - IMGUI_API void RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, ImDrawList* draw_list, float wrap_width = 0.0f, const ImVec2* cpu_clip_max = NULL) const; - IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const; + IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8 + IMGUI_API ImVec2 CalcTextSizeW(float size, float max_width, const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL) const; // wchar + IMGUI_API void RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, ImDrawList* draw_list, float wrap_width = 0.0f, const ImVec2* cpu_clip_max = NULL) const; + IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const; }; //---- Include imgui_user.h at the end of imgui.h From aa1a96f907084c7d85b94a760b8304bf36d254b4 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 9 Apr 2015 18:34:31 +0100 Subject: [PATCH 10/15] ImDrawList: inline AddVtx() calls for profit in highly debug builds --- imgui.cpp | 58 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 6d9d4328..c67303cb 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7711,47 +7711,51 @@ void ImDrawList::PrimReserve(unsigned int vtx_count) void ImDrawList::PrimTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col) { const ImVec2 uv = GImGui->FontTexUvWhitePixel; - AddVtx(a, uv, col); - AddVtx(b, uv, col); - AddVtx(c, uv, col); + vtx_write[0].pos = a; vtx_write[0].uv = uv; vtx_write[0].col = col; + vtx_write[1].pos = b; vtx_write[1].uv = uv; vtx_write[1].col = col; + vtx_write[2].pos = c; vtx_write[2].uv = uv; vtx_write[2].col = col; + vtx_write += 3; } void ImDrawList::PrimRect(const ImVec2& a, const ImVec2& c, ImU32 col) { const ImVec2 uv = GImGui->FontTexUvWhitePixel; - ImVec2 b(c.x, a.y); - ImVec2 d(a.x, c.y); - AddVtx(a, uv, col); - AddVtx(b, uv, col); - AddVtx(c, uv, col); - AddVtx(a, uv, col); - AddVtx(c, uv, col); - AddVtx(d, uv, col); + const ImVec2 b(c.x, a.y); + const ImVec2 d(a.x, c.y); + vtx_write[0].pos = a; vtx_write[0].uv = uv; vtx_write[0].col = col; + vtx_write[1].pos = b; vtx_write[1].uv = uv; vtx_write[1].col = col; + vtx_write[2].pos = c; vtx_write[2].uv = uv; vtx_write[2].col = col; + vtx_write[3].pos = a; vtx_write[3].uv = uv; vtx_write[3].col = col; + vtx_write[4].pos = c; vtx_write[4].uv = uv; vtx_write[4].col = col; + vtx_write[5].pos = d; vtx_write[5].uv = uv; vtx_write[5].col = col; + vtx_write += 6; } void ImDrawList::PrimRectUV(const ImVec2& a, const ImVec2& c, const ImVec2& uv_a, const ImVec2& uv_c, ImU32 col) { - ImVec2 b(c.x, a.y); - ImVec2 d(a.x, c.y); - ImVec2 uv_b(uv_c.x, uv_a.y); - ImVec2 uv_d(uv_a.x, uv_c.y); - AddVtx(a, uv_a, col); - AddVtx(b, uv_b, col); - AddVtx(c, uv_c, col); - AddVtx(a, uv_a, col); - AddVtx(c, uv_c, col); - AddVtx(d, uv_d, col); + const ImVec2 b(c.x, a.y); + const ImVec2 d(a.x, c.y); + const ImVec2 uv_b(uv_c.x, uv_a.y); + const ImVec2 uv_d(uv_a.x, uv_c.y); + vtx_write[0].pos = a; vtx_write[0].uv = uv_a; vtx_write[0].col = col; + vtx_write[1].pos = b; vtx_write[1].uv = uv_b; vtx_write[1].col = col; + vtx_write[2].pos = c; vtx_write[2].uv = uv_c; vtx_write[2].col = col; + vtx_write[3].pos = a; vtx_write[3].uv = uv_a; vtx_write[3].col = col; + vtx_write[4].pos = c; vtx_write[4].uv = uv_c; vtx_write[4].col = col; + vtx_write[5].pos = d; vtx_write[5].uv = uv_d; vtx_write[5].col = col; + vtx_write += 6; } void ImDrawList::PrimQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col) { const ImVec2 uv = GImGui->FontTexUvWhitePixel; - AddVtx(a, uv, col); - AddVtx(b, uv, col); - AddVtx(c, uv, col); - AddVtx(a, uv, col); - AddVtx(c, uv, col); - AddVtx(d, uv, col); + vtx_write[0].pos = a; vtx_write[0].uv = uv; vtx_write[0].col = col; + vtx_write[1].pos = b; vtx_write[1].uv = uv; vtx_write[1].col = col; + vtx_write[2].pos = c; vtx_write[2].uv = uv; vtx_write[2].col = col; + vtx_write[3].pos = a; vtx_write[3].uv = uv; vtx_write[3].col = col; + vtx_write[4].pos = c; vtx_write[4].uv = uv; vtx_write[4].col = col; + vtx_write[5].pos = d; vtx_write[5].uv = uv; vtx_write[5].col = col; + vtx_write += 6; } // FIXME-OPT: In many instances the caller could provide a normal. From 4fa3eee84e972ea37aefa7fc52a28e3bf6fc11da Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 9 Apr 2015 19:47:41 +0100 Subject: [PATCH 11/15] Renamed io.MetricsVertices to io.MetricsRenderVertices --- imgui.cpp | 6 +++--- imgui.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c67303cb..bc7923ad 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1673,7 +1673,7 @@ static inline void AddDrawListToRenderList(ImVector& out_render_lis if (draw_list->commands.back().vtx_count == 0) draw_list->commands.pop_back(); out_render_list.push_back(draw_list); - GImGui->IO.MetricsVertices += (int)draw_list->vtx_buffer.size(); + GImGui->IO.MetricsRenderVertices += (int)draw_list->vtx_buffer.size(); } } @@ -2207,7 +2207,7 @@ void ImGui::Render() } // Gather windows to render - g.IO.MetricsVertices = 0; + g.IO.MetricsRenderVertices = 0; for (size_t i = 0; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) g.RenderDrawLists[i].resize(0); for (size_t i = 0; i != g.Windows.size(); i++) @@ -10410,7 +10410,7 @@ void ImGui::ShowMetricsWindow(bool* opened) { ImGui::Text("ImGui %s", ImGui::GetVersion()); ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - ImGui::Text("%d vertices", ImGui::GetIO().MetricsVertices); + ImGui::Text("%d vertices", ImGui::GetIO().MetricsRenderVertices); ImGui::Separator(); struct Funcs diff --git a/imgui.h b/imgui.h index 4f4f8395..07d07717 100644 --- a/imgui.h +++ b/imgui.h @@ -670,7 +670,7 @@ struct ImGuiIO bool WantCaptureMouse; // Mouse is hovering a window or widget is active (= ImGui will use your mouse input) bool WantCaptureKeyboard; // Widget is active (= ImGui will use your keyboard input) float Framerate; // Framerate estimation, in frame per second. Rolling average estimation based on IO.DeltaTime over 120 frames - int MetricsVertices; // Vertices processed during last call to Render() + int MetricsRenderVertices; // Vertices processed during last call to Render() //------------------------------------------------------------------ // [Internal] ImGui will maintain those fields for you From 500a8a0e02b113ec27a60c47da20796fe4ee7ee2 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 9 Apr 2015 21:00:45 +0100 Subject: [PATCH 12/15] ImDrawList: bits of renaming. --- imgui.cpp | 12 ++++++------ imgui.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index bc7923ad..678c4f07 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7804,9 +7804,9 @@ void ImDrawList::AddArcFast(const ImVec2& center, float radius, ImU32 col, int a for (int a0 = a_min; a0 < a_max; a0++) { int a1 = (a0 + 1 == SAMPLES) ? 0 : a0 + 1; - AddVtx(center + circle_vtx[a0] * radius, uv, col); - AddVtx(center + circle_vtx[a1] * radius, uv, col); - AddVtx(center + third_point_offset, uv, col); + PrimVtx(center + circle_vtx[a0] * radius, uv, col); + PrimVtx(center + circle_vtx[a1] * radius, uv, col); + PrimVtx(center + third_point_offset, uv, col); } } else @@ -7925,9 +7925,9 @@ void ImDrawList::AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, for (int i = 0; i < num_segments; i++) { const float a1 = (i + 1) == num_segments ? 0.0f : a0 + a_step; - AddVtx(centre + ImVec2(cosf(a0), sinf(a0))*radius, uv, col); - AddVtx(centre + ImVec2(cosf(a1), sinf(a1))*radius, uv, col); - AddVtx(centre, uv, col); + PrimVtx(centre + ImVec2(cosf(a0), sinf(a0))*radius, uv, col); + PrimVtx(centre + ImVec2(cosf(a1), sinf(a1))*radius, uv, col); + PrimVtx(centre, uv, col); a0 = a1; } } diff --git a/imgui.h b/imgui.h index 07d07717..1ff50c6e 100644 --- a/imgui.h +++ b/imgui.h @@ -930,7 +930,7 @@ struct ImDrawList IMGUI_API void PrimLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f); IMGUI_API void UpdateClipRect(); IMGUI_API void UpdateTextureID(); - inline IMGUI_API void AddVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { vtx_write->pos = pos; vtx_write->uv = uv; vtx_write->col = col; vtx_write++; } + IMGUI_API void PrimVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { vtx_write->pos = pos; vtx_write->uv = uv; vtx_write->col = col; vtx_write++; } }; // Load and rasterize multiple TTF fonts into a same texture. From 37f1715bfa3122e7c8cc7cc03f9dd9959b86faaa Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 9 Apr 2015 21:14:52 +0100 Subject: [PATCH 13/15] Examples: DirectX11: Removed unnecessary vertices conversion and CUSTOMVERTEX types. --- .../directx11_example/imgui_impl_dx11.cpp | 31 +++++-------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index ba8d3d8b..4b5513ad 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -29,13 +29,6 @@ static ID3D11ShaderResourceView*g_pFontTextureView = NULL; static ID3D11BlendState* g_blendState = NULL; static int VERTEX_BUFFER_SIZE = 30000; // TODO: Make vertex buffer smaller and grow dynamically as needed. -struct CUSTOMVERTEX -{ - float pos[2]; - float uv[2]; - unsigned int col; -}; - struct VERTEX_CONSTANT_BUFFER { float mvp[4][4]; @@ -50,21 +43,13 @@ static void ImGui_ImplDX11_RenderDrawLists(ImDrawList** const cmd_lists, int cmd D3D11_MAPPED_SUBRESOURCE mappedResource; if (g_pd3dDeviceContext->Map(g_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource) != S_OK) return; - CUSTOMVERTEX* vtx_dst = (CUSTOMVERTEX*)mappedResource.pData; + ImDrawVert* vtx_dst = (ImDrawVert*)mappedResource.pData; for (int n = 0; n < cmd_lists_count; n++) { const ImDrawList* cmd_list = cmd_lists[n]; const ImDrawVert* vtx_src = &cmd_list->vtx_buffer[0]; - for (size_t i = 0; i < cmd_list->vtx_buffer.size(); i++) - { - vtx_dst->pos[0] = vtx_src->pos.x; - vtx_dst->pos[1] = vtx_src->pos.y; - vtx_dst->uv[0] = vtx_src->uv.x; - vtx_dst->uv[1] = vtx_src->uv.y; - vtx_dst->col = vtx_src->col; - vtx_dst++; - vtx_src++; - } + memcpy(vtx_dst, vtx_src, cmd_list->vtx_buffer.size() * sizeof(ImDrawVert)); + vtx_dst += cmd_list->vtx_buffer.size(); } g_pd3dDeviceContext->Unmap(g_pVB, 0); @@ -104,7 +89,7 @@ static void ImGui_ImplDX11_RenderDrawLists(ImDrawList** const cmd_lists, int cmd } // Bind shader and vertex buffers - unsigned int stride = sizeof(CUSTOMVERTEX); + unsigned int stride = sizeof(ImDrawVert); unsigned int offset = 0; g_pd3dDeviceContext->IASetInputLayout(g_pInputLayout); g_pd3dDeviceContext->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset); @@ -293,9 +278,9 @@ bool ImGui_ImplDX11_CreateDeviceObjects() // Create the input layout D3D11_INPUT_ELEMENT_DESC localLayout[] = { - { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, (size_t)(&((CUSTOMVERTEX*)0)->pos), D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((CUSTOMVERTEX*)0)->col), D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((CUSTOMVERTEX*)0)->uv), D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; if (g_pd3dDevice->CreateInputLayout(localLayout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK) @@ -359,7 +344,7 @@ bool ImGui_ImplDX11_CreateDeviceObjects() D3D11_BUFFER_DESC bufferDesc; memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); bufferDesc.Usage = D3D11_USAGE_DYNAMIC; - bufferDesc.ByteWidth = VERTEX_BUFFER_SIZE * sizeof(CUSTOMVERTEX); + bufferDesc.ByteWidth = VERTEX_BUFFER_SIZE * sizeof(ImDrawVert); bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; bufferDesc.MiscFlags = 0; From 90766141b3316fbd87c1e8d167b30b7735a1991d Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 9 Apr 2015 21:18:43 +0100 Subject: [PATCH 14/15] Examples: OpenGL3: Tweaks. --- examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 1cd2faf0..b7f225ea 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -23,7 +23,7 @@ static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; -static size_t g_VboMaxSize = 20000; +static size_t g_VboSize = 0; static unsigned int g_VboHandle = 0, g_VaoHandle = 0; // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) @@ -62,11 +62,10 @@ static void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawList** const cmd_lists, int for (int n = 0; n < cmd_lists_count; n++) total_vtx_count += cmd_lists[n]->vtx_buffer.size(); glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); - size_t neededBufferSize = total_vtx_count * sizeof(ImDrawVert); - if (neededBufferSize > g_VboMaxSize) + size_t needed_vtx_size = total_vtx_count * sizeof(ImDrawVert); + if (g_VboSize < needed_vtx_size) { - g_VboMaxSize = neededBufferSize + 5000; // Grow buffer - glBufferData(GL_ARRAY_BUFFER, g_VboMaxSize, NULL, GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, g_VboSize, NULL, GL_STREAM_DRAW); } // Copy and convert all vertices into a single contiguous buffer From 4f51b77937b395d61a84d94837e5c195fc053c66 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 9 Apr 2015 21:19:21 +0100 Subject: [PATCH 15/15] Examples: OpenGL3: Tweaks (argh, github ui) --- examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index b7f225ea..3bba00d6 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -65,6 +65,7 @@ static void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawList** const cmd_lists, int size_t needed_vtx_size = total_vtx_count * sizeof(ImDrawVert); if (g_VboSize < needed_vtx_size) { + g_VboSize = needed_vtx_size + 5000 * sizeof(ImDrawVert); // Grow buffer glBufferData(GL_ARRAY_BUFFER, g_VboSize, NULL, GL_STREAM_DRAW); } @@ -216,8 +217,6 @@ bool ImGui_ImplGlfwGL3_CreateDeviceObjects() g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); glGenBuffers(1, &g_VboHandle); - glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); - glBufferData(GL_ARRAY_BUFFER, g_VboMaxSize, NULL, GL_DYNAMIC_DRAW); glGenVertexArrays(1, &g_VaoHandle); glBindVertexArray(g_VaoHandle);