mirror of
https://github.com/ocornut/imgui.git
synced 2026-08-21 06:41:09 +00:00
DrawList: Textured Round Corners: Added flags to disable textured rounded corners (1962)
- added ImFontAtlasFlags_NoBakedRoundCorners which controls if rounded corners should be baked to texture - added ImDrawListFlags_RoundCornersUseTex which controls if we should try to use textured roudned corners - fixed how _FringeScaleIsInteger is calculated (we want to detect integer pixel scale) - fixed how _FringeScale is used with textured rounded corners
This commit is contained in:
@@ -5779,6 +5779,8 @@ static void SetupDrawListSharedData()
|
||||
g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLines;
|
||||
if (g.Style.AntiAliasedLinesUseTex && !(g.IO.Fonts->Flags & ImFontAtlasFlags_NoBakedLines))
|
||||
g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLinesUseTex;
|
||||
if (!(g.IO.Fonts->Flags & ImFontAtlasFlags_NoBakedRoundCorners))
|
||||
g.DrawListSharedData.InitialFlags |= ImDrawListFlags_RoundCornersUseTex;
|
||||
if (g.Style.AntiAliasedFill)
|
||||
g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedFill;
|
||||
if (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset)
|
||||
|
||||
4
imgui.h
4
imgui.h
@@ -3464,6 +3464,7 @@ enum ImDrawListFlags_
|
||||
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_TextNoPixelSnap = 1 << 4, // Disable automatically snapping AddText() calls to pixel boundaries.
|
||||
ImDrawListFlags_RoundCornersUseTex = 1 << 5, // Enable using textures instead of strokes to draw rounded corners/circles where possible.
|
||||
};
|
||||
|
||||
// Draw command list
|
||||
@@ -3496,7 +3497,7 @@ struct ImDrawList
|
||||
ImVector<ImU8> _CallbacksDataBuf; // [Internal]
|
||||
float _FringeScale; // [Internal] anti-alias fringe is scaled by this value, this helps to keep things sharp while zooming at vertex buffer content.
|
||||
float _InvFringeScale; // [internal] 1.0 / _FringeScale // FIXME: Consider renaming to _PixelDensity.
|
||||
bool _FringeScaleIsInteger; // [Internal] true if _FringeScale is a whole number, used to select fast path for rendering
|
||||
bool _FringeScaleIsInteger; // [Internal] true if 1/_FringeScale is a whole number, used to select fast path for rendering
|
||||
const char* _OwnerName; // Pointer to owner window's name for debugging
|
||||
|
||||
// If you want to create ImDrawList instances, pass them ImGui::GetDrawListSharedData().
|
||||
@@ -3860,6 +3861,7 @@ enum ImFontAtlasFlags_
|
||||
ImFontAtlasFlags_NoPowerOfTwoHeight = 1 << 0, // Don't round the height to next power of two
|
||||
ImFontAtlasFlags_NoMouseCursors = 1 << 1, // Don't build software mouse cursors into the atlas (save a little texture memory)
|
||||
ImFontAtlasFlags_NoBakedLines = 1 << 2, // Don't build thick line textures into the atlas (save a little texture memory, allow support for point/nearest filtering). The AntiAliasedLinesUseTex features uses them, otherwise they will be rendered using polygons (more expensive for CPU/GPU).
|
||||
ImFontAtlasFlags_NoBakedRoundCorners= 1 << 3, // Don't build round corners into the atlas.
|
||||
};
|
||||
|
||||
// Load and rasterize multiple TTF/OTF fonts into a same texture. The font atlas will build a single texture holding:
|
||||
|
||||
@@ -731,7 +731,7 @@ void ImDrawList::_SetPixelDensity(float pixel_density)
|
||||
IM_ASSERT(pixel_density > 0.0f);
|
||||
_FringeScale = 1.0f / pixel_density;
|
||||
_InvFringeScale = pixel_density;
|
||||
_FringeScaleIsInteger = ImIsTruncated(_FringeScale);
|
||||
_FringeScaleIsInteger = ImIsTruncated(_InvFringeScale);
|
||||
}
|
||||
|
||||
// Reserve space for a number of vertices and indices.
|
||||
@@ -1525,7 +1525,8 @@ void ImDrawList::AddLineH(float min_x, float max_x, float y, ImU32 col, float th
|
||||
y -= thickness * 0.5f;
|
||||
else if (stroke_pos == ImDrawFlags_StrokeOutside)
|
||||
y -= thickness;
|
||||
if (ImIsTruncated4(min_x, max_x, y, thickness))
|
||||
|
||||
if (_FringeScaleIsInteger && ImIsTruncated4(min_x, max_x, y, thickness))
|
||||
{
|
||||
PrimReserve(6, 4);
|
||||
PrimRect(ImVec2(min_x, y), ImVec2(max_x, y + thickness), col);
|
||||
@@ -1553,10 +1554,11 @@ void ImDrawList::AddLineV(float x, float min_y, float max_y, ImU32 col, float th
|
||||
x += thickness * 0.5f;
|
||||
else if (stroke_pos == ImDrawFlags_StrokeOutside)
|
||||
x -= thickness;
|
||||
if (ImIsTruncated4(x, min_y, max_y, thickness))
|
||||
|
||||
if (_FringeScaleIsInteger && ImIsTruncated4(x, min_y, max_y, thickness))
|
||||
{
|
||||
PrimReserve(6, 4);
|
||||
PrimRect(ImTrunc(ImVec2(x, min_y)), ImTrunc(ImVec2(x + thickness, max_y)), col);
|
||||
PrimRect(ImVec2(x, min_y), ImVec2(x + thickness, max_y), col);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1711,8 +1713,9 @@ void ImDrawList::AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, fl
|
||||
return;
|
||||
}
|
||||
|
||||
const bool is_truncated = _FringeScaleIsInteger && ImIsTruncated4(p_min.x, p_min.y, p_max.x, p_min.y) && ImIsTruncated4(rounding, thickness, 0.0f, 0.0f);
|
||||
ImDrawFlags stroke_pos = (flags & ImDrawFlags_StrokeMask_);
|
||||
if ((stroke_pos == ImDrawFlags_StrokeInside || stroke_pos == ImDrawFlags_StrokeOutside) && ImIsTruncated4(p_min.x, p_min.y, p_max.x, p_min.y) && ImIsTruncated(rounding) && ImIsTruncated(thickness))
|
||||
if ((stroke_pos == ImDrawFlags_StrokeInside || stroke_pos == ImDrawFlags_StrokeOutside) && is_truncated)
|
||||
{
|
||||
if ((flags & ImDrawFlags_RoundCornersMask_) == 0)
|
||||
flags |= ImDrawFlags_RoundCornersAll;
|
||||
@@ -1720,8 +1723,8 @@ void ImDrawList::AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, fl
|
||||
rounding = ImMin(rounding, ImFabs(p_max.x - p_min.x) * (((flags & ImDrawFlags_RoundCornersTop) == ImDrawFlags_RoundCornersTop) || ((flags & ImDrawFlags_RoundCornersBottom) == ImDrawFlags_RoundCornersBottom) ? 0.5f : 1.0f) - 1.0f);
|
||||
rounding = ImMin(rounding, ImFabs(p_max.y - p_min.y) * (((flags & ImDrawFlags_RoundCornersLeft) == ImDrawFlags_RoundCornersLeft) || ((flags & ImDrawFlags_RoundCornersRight) == ImDrawFlags_RoundCornersRight) ? 0.5f : 1.0f) - 1.0f);
|
||||
|
||||
int s_rounding = (int)rounding;
|
||||
int s_thickness = (int)thickness;
|
||||
int s_rounding = (int)(rounding / _FringeScale);
|
||||
int s_thickness = (int)(thickness / _FringeScale);
|
||||
|
||||
ImVec2 s_min = p_min;
|
||||
ImVec2 s_max = p_max;
|
||||
@@ -1734,7 +1737,7 @@ void ImDrawList::AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, fl
|
||||
|
||||
if (s_rounding <= 0 || (flags & ImDrawFlags_RoundCornersMask_) == ImDrawFlags_RoundCornersNone)
|
||||
{
|
||||
const float t = (float)s_thickness;
|
||||
const float t = (float)s_thickness * _FringeScale;
|
||||
PrimReserve(6*4, 4*4);
|
||||
PrimRect(ImVec2(p_min.x, p_min.y), ImVec2(p_max.x, p_min.y + t), col);
|
||||
PrimRect(ImVec2(p_min.x, p_min.y + t), ImVec2(p_min.x + t, p_max.y - t), col);
|
||||
@@ -1742,13 +1745,14 @@ void ImDrawList::AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, fl
|
||||
PrimRect(ImVec2(p_min.x, p_max.y - t), ImVec2(p_max.x, p_max.y), col);
|
||||
return;
|
||||
}
|
||||
if (s_thickness <= IM_DRAWLIST_TEX_CORNERS_THICKNESS_MAX && s_rounding <= IM_DRAWLIST_TEX_CORNERS_ROUNDING_MAX)
|
||||
if ((Flags & ImDrawListFlags_RoundCornersUseTex) && s_thickness <= IM_DRAWLIST_TEX_CORNERS_THICKNESS_MAX && s_rounding <= IM_DRAWLIST_TEX_CORNERS_ROUNDING_MAX)
|
||||
{
|
||||
const int size = ImMax(s_rounding, s_thickness);
|
||||
IM_ASSERT_PARANOID(!(_Data->Font->OwnerAtlas->Flags & ImFontAtlasFlags_NoBakedRoundCorners));
|
||||
const int size = ImMax(s_rounding, s_thickness); // This is matching the baking calculations.
|
||||
const int idx = (s_thickness - 1) * IM_DRAWLIST_TEX_CORNERS_ROUNDING_MAX + s_rounding - 1;
|
||||
IM_ASSERT(idx >= 0 && idx < IM_DRAWLIST_TEX_CORNERS_ROUNDING_MAX * IM_DRAWLIST_TEX_CORNERS_THICKNESS_MAX);
|
||||
IM_ASSERT_PARANOID(idx >= 0 && idx < IM_DRAWLIST_TEX_CORNERS_ROUNDING_MAX * IM_DRAWLIST_TEX_CORNERS_THICKNESS_MAX);
|
||||
const ImVec4 tex_uvs = _Data->TexUvCornerStrokes[idx];
|
||||
_AddRectBaked(s_min, s_max, col, (float)size, (float)thickness, tex_uvs, flags);
|
||||
_AddRectBaked(s_min, s_max, col, (float)size * _FringeScale, (float)thickness, tex_uvs, flags);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1832,16 +1836,21 @@ void ImDrawList::AddRectFilled(const ImVec2& p_min, const ImVec2& p_max, ImU32 c
|
||||
rounding = ImMin(rounding, ImFabs(p_max.x - p_min.x) * (((flags & ImDrawFlags_RoundCornersTop) == ImDrawFlags_RoundCornersTop) || ((flags & ImDrawFlags_RoundCornersBottom) == ImDrawFlags_RoundCornersBottom) ? 0.5f : 1.0f) - 1.0f);
|
||||
rounding = ImMin(rounding, ImFabs(p_max.y - p_min.y) * (((flags & ImDrawFlags_RoundCornersLeft) == ImDrawFlags_RoundCornersLeft) || ((flags & ImDrawFlags_RoundCornersRight) == ImDrawFlags_RoundCornersRight) ? 0.5f : 1.0f) - 1.0f);
|
||||
|
||||
const int s_rounding = (int)rounding;
|
||||
|
||||
const int s_rounding = (int)(rounding / _FringeScale);
|
||||
if (s_rounding <= 0 || (flags & ImDrawFlags_RoundCornersMask_) == ImDrawFlags_RoundCornersNone)
|
||||
{
|
||||
PrimReserve(6, 4);
|
||||
PrimRect(p_min, p_max, col);
|
||||
}
|
||||
else if (s_rounding <= IM_DRAWLIST_TEX_CORNERS_ROUNDING_MAX)
|
||||
else if ((Flags & ImDrawListFlags_RoundCornersUseTex) && s_rounding <= IM_DRAWLIST_TEX_CORNERS_ROUNDING_MAX)
|
||||
{
|
||||
ImVec4 tex_uvs = _Data->TexUvCornerFills[s_rounding - 1];
|
||||
_AddRectFilledBaked(p_min, p_max, col, ImMax(2.0f, (float)s_rounding), tex_uvs, flags);
|
||||
IM_ASSERT_PARANOID(!(_Data->Font->OwnerAtlas->Flags & ImFontAtlasFlags_NoBakedRoundCorners));
|
||||
const int size = ImMax(2, s_rounding); // This is matching the baking calculations.
|
||||
const int idx = s_rounding - 1;
|
||||
IM_ASSERT_PARANOID(idx >= 0 && idx < IM_DRAWLIST_TEX_CORNERS_ROUNDING_MAX);
|
||||
ImVec4 tex_uvs = _Data->TexUvCornerFills[idx];
|
||||
_AddRectFilledBaked(p_min, p_max, col, (float)size * _FringeScale, tex_uvs, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4008,11 +4017,14 @@ static ImU8 SampleCornerStroke(float x, float y, float cx, float cy, float outer
|
||||
const float aa_width = 1.0f;
|
||||
const float outer = 1.0f - (d - outer_r + aa_width * 0.5f) / aa_width;
|
||||
const float inner = (d - inner_r + aa_width * 0.5f) / aa_width;
|
||||
return (ImU8)(ImClamp(ImMin(inner, outer), 0.0f, 1.0f) * 255.f);
|
||||
return (ImU8)(ImClamp(ImMin(inner, outer), 0.0f, 1.0f) * 255.0f);
|
||||
}
|
||||
|
||||
static void ImFontAtlasBuildUpdateTexDataCorners(ImFontAtlas* atlas)
|
||||
{
|
||||
if (atlas->Flags & ImFontAtlasFlags_NoBakedRoundCorners)
|
||||
return;
|
||||
|
||||
// Pack and store identifier so we can refresh UV coordinates on texture resize.
|
||||
ImTextureData* tex = atlas->TexData;
|
||||
ImFontAtlasBuilder* builder = atlas->Builder;
|
||||
|
||||
Reference in New Issue
Block a user