Texture-based round corners: Adding style/drawlist flags for rounded corner textures

This commit is contained in:
Ben Carter 2019-11-29 15:35:23 +09:00 committed by ocornut
parent a1efd8fc06
commit 3f671bd282
4 changed files with 20 additions and 4 deletions

View File

@ -1070,6 +1070,7 @@ ImGuiStyle::ImGuiStyle()
AntiAliasedLines = true; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU. AntiAliasedLines = true; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU.
AntiAliasedLinesUseTex = true; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering. AntiAliasedLinesUseTex = true; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering.
AntiAliasedFill = true; // Enable anti-aliased filled shapes (rounded rectangles, circles, etc.). AntiAliasedFill = true; // Enable anti-aliased filled shapes (rounded rectangles, circles, etc.).
TexturedRoundCorners = true; // Enable using textures instead of strokes to draw rounded corners/circles where possible.
CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
CircleTessellationMaxError = 0.30f; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry. CircleTessellationMaxError = 0.30f; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry.
@ -4297,6 +4298,8 @@ void ImGui::NewFrame()
g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedFill; g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedFill;
if (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset) if (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset)
g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AllowVtxOffset; g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AllowVtxOffset;
if (g.Style.TexturedRoundCorners && !(g.Font->ContainerAtlas->Flags & ImFontAtlasFlags_NoBakedRoundCorners))
g.DrawListSharedData.InitialFlags |= ImDrawListFlags_TexturedRoundCorners;
// Mark rendering data as invalid to prevent user who may have a handle on it to use it. // Mark rendering data as invalid to prevent user who may have a handle on it to use it.
for (int n = 0; n < g.Viewports.Size; n++) for (int n = 0; n < g.Viewports.Size; n++)

View File

@ -1875,6 +1875,7 @@ struct ImGuiStyle
bool AntiAliasedLines; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList). bool AntiAliasedLines; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList).
bool AntiAliasedLinesUseTex; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering. Latched at the beginning of the frame (copied to ImDrawList). bool AntiAliasedLinesUseTex; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering. Latched at the beginning of the frame (copied to ImDrawList).
bool AntiAliasedFill; // Enable anti-aliased edges around filled shapes (rounded rectangles, circles, etc.). Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList). bool AntiAliasedFill; // Enable anti-aliased edges around filled shapes (rounded rectangles, circles, etc.). Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList).
bool TexturedRoundCorners; // Enable using textures instead of strokes to draw rounded corners/circles where possible.
float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
float CircleTessellationMaxError; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry. float CircleTessellationMaxError; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry.
ImVec4 Colors[ImGuiCol_COUNT]; ImVec4 Colors[ImGuiCol_COUNT];
@ -2484,7 +2485,8 @@ enum ImDrawListFlags_
ImDrawListFlags_AntiAliasedLines = 1 << 0, // Enable anti-aliased lines/borders (*2 the number of triangles for 1.0f wide line or lines thin enough to be drawn using textures, otherwise *3 the number of triangles) ImDrawListFlags_AntiAliasedLines = 1 << 0, // Enable anti-aliased lines/borders (*2 the number of triangles for 1.0f wide line or lines thin enough to be drawn using textures, otherwise *3 the number of triangles)
ImDrawListFlags_AntiAliasedLinesUseTex = 1 << 1, // Enable anti-aliased lines/borders using textures when possible. Require backend to render with bilinear filtering. ImDrawListFlags_AntiAliasedLinesUseTex = 1 << 1, // Enable anti-aliased lines/borders using textures when possible. Require backend to render with bilinear filtering.
ImDrawListFlags_AntiAliasedFill = 1 << 2, // Enable anti-aliased edge around filled shapes (rounded rectangles, circles). ImDrawListFlags_AntiAliasedFill = 1 << 2, // Enable anti-aliased edge around filled shapes (rounded rectangles, circles).
ImDrawListFlags_AllowVtxOffset = 1 << 3 // Can emit 'VtxOffset > 0' to allow large meshes. Set when 'ImGuiBackendFlags_RendererHasVtxOffset' is enabled. ImDrawListFlags_AllowVtxOffset = 1 << 3, // Can emit 'VtxOffset > 0' to allow large meshes. Set when 'ImGuiBackendFlags_RendererHasVtxOffset' is enabled.
ImDrawListFlags_TexturedRoundCorners = 1 << 4 // Enable using textures instead of strokes to draw rounded corners/circles where possible.
}; };
// Draw command list // Draw command list

View File

@ -6399,6 +6399,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
HelpMarker("Faster lines using texture data. Require backend to render with bilinear filtering (not point/nearest filtering)."); HelpMarker("Faster lines using texture data. Require backend to render with bilinear filtering (not point/nearest filtering).");
ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill); ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill);
ImGui::Checkbox("Rounded corner textures", &style.TexturedRoundCorners);
ImGui::PushItemWidth(ImGui::GetFontSize() * 8); ImGui::PushItemWidth(ImGui::GetFontSize() * 8);
ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, 10.0f, "%.2f"); ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, 10.0f, "%.2f");
if (style.CurveTessellationTol < 0.10f) style.CurveTessellationTol = 0.10f; if (style.CurveTessellationTol < 0.10f) style.CurveTessellationTol = 0.10f;

View File

@ -1396,6 +1396,9 @@ void ImDrawList::AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float th
// We are using the textures generated by ImFontAtlasBuildRenderRoundCornersTexData() // We are using the textures generated by ImFontAtlasBuildRenderRoundCornersTexData()
inline bool AddRoundCornerRect(ImDrawList* draw_list, const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, ImDrawFlags flags, bool fill) inline bool AddRoundCornerRect(ImDrawList* draw_list, const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, ImDrawFlags flags, bool fill)
{ {
if (!(draw_list->Flags & ImDrawListFlags_TexturedRoundCorners)) // Disabled by the draw list flags
return false;
#if 1 #if 1
flags = FixRectCornerFlags(flags); flags = FixRectCornerFlags(flags);
rounding = ImMin(rounding, ImFabs(b.x - a.x) * (((flags & ImDrawFlags_RoundCornersTop) == ImDrawFlags_RoundCornersTop) || ((flags & ImDrawFlags_RoundCornersBottom) == ImDrawFlags_RoundCornersBottom) ? 0.5f : 1.0f) - 1.0f); rounding = ImMin(rounding, ImFabs(b.x - a.x) * (((flags & ImDrawFlags_RoundCornersTop) == ImDrawFlags_RoundCornersTop) || ((flags & ImDrawFlags_RoundCornersBottom) == ImDrawFlags_RoundCornersBottom) ? 0.5f : 1.0f) - 1.0f);
@ -1405,6 +1408,9 @@ inline bool AddRoundCornerRect(ImDrawList* draw_list, const ImVec2& a, const ImV
const ImDrawListSharedData* data = draw_list->_Data; const ImDrawListSharedData* data = draw_list->_Data;
const int rad = (int)rounding; const int rad = (int)rounding;
if (data->Font->ContainerAtlas->Flags & ImFontAtlasFlags_NoBakedRoundCorners) // No data in font
return false;
if ((rad <= 0) || // Zero radius causes issues with the [rad - 1] UV lookup below if ((rad <= 0) || // Zero radius causes issues with the [rad - 1] UV lookup below
(rad > data->Font->ContainerAtlas->RoundCornersMaxSize)) (rad > data->Font->ContainerAtlas->RoundCornersMaxSize))
{ {
@ -1414,9 +1420,7 @@ inline bool AddRoundCornerRect(ImDrawList* draw_list, const ImVec2& a, const ImV
// Debug command to force this render path to only execute when shift is held // Debug command to force this render path to only execute when shift is held
if (!ImGui::GetIO().KeyShift) if (!ImGui::GetIO().KeyShift)
{
return false; return false;
}
ImTextureID tex_id = data->Font->ContainerAtlas->TexID; ImTextureID tex_id = data->Font->ContainerAtlas->TexID;
IM_ASSERT(tex_id == draw_list->_TextureIdStack.back()); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font. IM_ASSERT(tex_id == draw_list->_TextureIdStack.back()); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font.
@ -1773,10 +1777,16 @@ void ImDrawList::AddTriangleFilled(const ImVec2& p1, const ImVec2& p2, const ImV
// (in which case the caller should try the regular circle drawing code) // (in which case the caller should try the regular circle drawing code)
inline bool AddRoundCornerCircle(ImDrawList* draw_list, const ImVec2& center, float radius, ImU32 col, bool fill) inline bool AddRoundCornerCircle(ImDrawList* draw_list, const ImVec2& center, float radius, ImU32 col, bool fill)
{ {
if (!(draw_list->Flags & ImDrawListFlags_TexturedRoundCorners)) // Disabled by the draw list flags
return false;
const ImDrawListSharedData* data = draw_list->_Data; const ImDrawListSharedData* data = draw_list->_Data;
ImTextureID tex_id = data->Font->ContainerAtlas->TexID; ImTextureID tex_id = data->Font->ContainerAtlas->TexID;
IM_ASSERT(tex_id == draw_list->_TextureIdStack.back()); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font. IM_ASSERT(tex_id == draw_list->_TextureIdStack.back()); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font.
if (data->Font->ContainerAtlas->Flags & ImFontAtlasFlags_NoBakedRoundCorners) // No data in font
return false;
const int rad = (int)radius; const int rad = (int)radius;
if (rad < 1 || rad > data->Font->ContainerAtlas->RoundCornersMaxSize) // Radius 0 will cause issues with the UV lookup below if (rad < 1 || rad > data->Font->ContainerAtlas->RoundCornersMaxSize) // Radius 0 will cause issues with the UV lookup below
return false; // We can't handle this return false; // We can't handle this
@ -2432,7 +2442,7 @@ ImFontAtlas::ImFontAtlas()
TexGlyphPadding = 1; TexGlyphPadding = 1;
PackIdMouseCursors = PackIdLines = -1; PackIdMouseCursors = PackIdLines = -1;
RoundCornersMaxSize = 60; RoundCornersMaxSize = 32;
} }
ImFontAtlas::~ImFontAtlas() ImFontAtlas::~ImFontAtlas()