@@ -39,171 +39,208 @@ HOW TO UPDATE?
VERSION 1.93.0 WIP (In Progress)
-----------------------------------------------------------------------
- In 1.93, the ImDrawList rendering has been improved to be more robust and more consistent over
the whole range of shapes. The rendering now matches much closer to common vector drawing APIs,
like html canvas. Improvements, like anti-aliased line endings and stroke position were added,
and t he coordinates passed to the API are now consistent.
Some details are now rendered slightly differently (even if generally more consistent) .
The difference in rendering is in the range of half a pixel, but that can lead to issues like
some lines now look blurrier or more transpa rent.
The r end ering of common shapes was optimized when the shapes fall on integer coordinates
(which is most of the UI). This includes skipping anti-aliasing when not needed, or using
textures instead of tessellated geometry to draw round corn ers .
- Most of the work courtesy of @memononen, with bits from @ocornut, @thedmd, @potocpav.
- Refer to our fu ll guid es:
- ImDrawList Vector Rendering Reference:
https://github.com/ocornut/imgui/wiki/Draw-List
- Pixel Perfect Anti-aliased Rendering:
https://github.com/ocornut/imgui/wiki/Pixel-Perfect-Rendering
- How Anti-aliased Polyline Rendering is Implemented:
https://github.com/ocornut/imgui/wiki/Polyline-Rendering
- (Breaking) AddLine: removed the (+0.5f,+0.5f) offset that was sneakily added to input coordinates.
- This fixes inconsistencies in the API and matches the PathXXX API.
- By default, stroke thickness extends on both side of the given segment.
e.g for a "pixel-perfect" looking line with thickness=1.0f, coords should be passed as center of each end s of the line .
- Use `ImDrawFlags_StrokeLegacy` to use old offset if required. But you might as well apply the offset manually!
- Generally better to use to newly introduced `AddLineH()`, `AddLineV()` functions .
READ IF YOU ARE MINDFUL OF PIXEL-PERFECTNESS IN YOUR CUSTOM RENDERING/WIDGETS:
- TRANSITION GUIDE FOR AXIS-ALIGNED LINES:
- When switching from legacy `AddLine()` values to `AddLineV()`, `AddLineH()` you can keep same inputs coordinates as before.
- Old `AddLine({x, y1}, {x, y2}, col)` --> `AddLineV(x, y1, y2, col);` // Vertical line.
- Old `AddLine({x1, y}, {x2, y}, col)` --> `AddLineH(x1, x2, y, col);` // Horizontal line.
- This will be equivalent and faster for thickness=1.0f lines .
- Since `AddLine()` use default stroke pos C ent er and `AddLineV()`, `AddLineH()` use Inside, thickness>1.0f strokes will differ.
Using `ImDrawFlags_StrokeCenter` will match old result more closely (aka look centered), but is more likely
to look blurry as it already did before. Read table below about StrokePos and the
"Pixel-Perfect Rendering" guide if you care about pixel-perfect lines.
- TRANSITION GUIDE FOR DIAGONAL LINES:
- Your lines will appear offset by -0.5f pixels on each axis.
Being anti-aliased diagonal lines, they won't look particularly better or worse, just slightly offset.
It'll likely only be noticeable if you carefully combined them with other primitives for a pixel-perfect result.
- Old AddLine({x1, y1}, {x2, y2}, col) == AddLine({x1, y1}, {x2, y2}, col, thickness, ImDrawFlags_StrokeLegacy); // Offset by +0.5f + disable AA ends.
== AddLine({x1 + 0.5f, y1 + 0.5f}, {x2+ 0.5f, y2 + 0.5f}, col, thickness); // Same
This reapplies the old offset, and should get you exactly the same result you previously got for thickness=1.0f lines.
But said result was sometimes ambiguous and renderer dependent. (#3116, #3258, #2441)
- Old `AddLine()` did not have anti-aliased ends, which could create gaps when rendering shapes out
of multiple contiguous lines instead of using AddPolyline(). There is a possibility that you could
have added fudge offsets here and there which are not necessary anymore or may be simplified.
- AddPolyline(), PathStroke(), AddTriangle(): the algorithm to render lines got overhauled.
(#2183, #2964, #7972)
- Generally fixed rendering of thick strokes/paths.
- The new stroke expansion now uses corner miter calculation, which keeps thickness along
the line segments consistent. If the corner becomes too sharp, it will be bevelled to avoid
long spikes at corners.
- There are also some robustness measures for the case where the line thickness is larger
than the features being drawn.
- Rendering artifacts are still possible when the path features are smaller than line thickness,
but the artifacts should be more localized. The new implementation attempted to favor simple
implementation and robustness over the corner case accuracy.
- New rendering code fixes (subtle) inconsistencies between graphics API (e.g. DirectX vs OpenGL)
using different diamond exits rules. New code should work precisely the same regardless
of graphics API. (#3116, #3258, #2441)
- Added `ImDrawFlags_AALineEnds` flag to enable anti-aliased line ends.
- Most noticeable for thick lines.
- Helps fills minor gaps if combining multiple individual lines.
- Enabling AA Ends by default would be more "correct", but it is slower and increase vertex/index data.s
- Added `ImDrawFlags_MiterOnly` flag to disable using beveled corner (closer to legacy
rendering, slightly faster, but corners sharper than 90 degrees may expand far out).
Automatically used by AddRect(), AddCircle(), AddNgon(), AddEllipse() etc functions
since we know that the input path does not contains sharper corners.
- Added `ImDrawFlags_SquareCap` flag to use extend lines ends using square caps.
- AddConvexPolyFilled()/PathFillConvex(): improved to handle input geometry more robustly.
The rendering of sharp corners was improved. Earlier there were issues with sharp corners
either creating long spikes, or messing up the adjacent edge’ s anti-aliasing. Now the
anti-aliasing fringe calculation is more consistent, and sharp corners get bevelled to
avoid spikes. There might still be issues when the smallest extent of a long thin polygon
is less than a pixel. Also supports `ImDrawFlags_MiterOnly`, to facilitate matching
a stroke using the same flag.
- AddRect(), AddRectFilled(): various optimization for rounded rectangles. (#1962)
- Integer-aligned coordinates and thicknesses will automatically use baked textures,
saving on both CPU and vertex/index data.
- Added `ImFontAtlasFlags_NoBakedRoundCorners` to disable baking round corners in font atlas.
- Added `ImDrawFlags_UseTexForRoundCorners` to enable using round corners.
- AddRectFilled(): non-integer coordinates will now display anti-aliased edges. (#6971)
- Improved minor mismatches when overlapping strokes and filled shapes,
e.g. when using inside strokes,
- `AddRect()` and `AddRectFilled()` with rounding now overlap better. (#3656)
- `AddCircle()` and `AddCircleFilled()` now overlap better.
- Added flags to specify stroke position in all `ImDrawList` stroking functions:
- `ImDrawFlags_StrokeInside` (default for closed primitives and AddLineH, AddLineV)
- `ImDrawFlags_StrokeCenter` (default for paths, bezier and AddLine)
- `ImDrawFlags_StrokeCenterBiased`
- `ImDrawFlags_StrokeOutside`
- `ImDrawFlags_StrokeLegacy` (may be set as default for a given scope using PushDrawFlag()).
- Legacy code was generally applying +0.50f offset which meant that,
- with thickness=1.0f: the stroke would appear inside.
- with thickness>1.0f: the stroke would start expanding on both sides but starting from that slightly initial offset.
- with thickness>1.0f for even integer values, the stroke would look blurry.
- TL;DR; the logic didn't make much sense for thickness>1.0f.
- Defaulting to Inside for closed shapes ensure that rectangles and lines are never blurry,
regardless of thickness, as long as input coordinates/sizes are integers. (#9359)
- Read our Wiki guides! Recap:
------------------------------------------------------------------------
Legacy Inside Outside Center CenterBiased
--------------------------------------------------------------------------------
Thickness=1.0f sharp sharp sharp blurry sharp
Thickness=2.0f blurry sharp sharp sharp sharp
Thickness=3.0f sharp sharp sharp blurry sharp
------------------------------------------------------------------------
- Added ImDrawList::PushDrawFlag()/PopDrawFlag() to alter certain flags for a scope,
e.g. `PushDrawFlag(ImDrawFlags_StrokeLegacy, true);` enforce legacy tweaks.
- (Breaking) AddRect, AddCircle, AddNgon, AddEllipse: defaulting to "inside" stroke.
- All closed shapes with thickness=1.0f will appear identical.
- The difference for thickness>1.0f shapes may be minimal since very large strokes
were not well supported for widgets, but stroke will default inside widgets.
- (Breaking) Merged `ImDrawListFlags` into `ImDrawFlags`.
`ImDrawListFlags` was very rarely used directly. Keep inline redirection (will obsolete).
- `ImDrawListFlags_AntiAliasedLines` -> `ImDrawFlags_AALines`
- `ImDrawListFlags_AntiAliasedFill` -> `ImDrawFlags_AAFill`
- `ImDrawListFlags_AntiAliasedLinesUseTex` -> `ImDrawFlags_UseTexForStrokeLegacy`
- `ImDrawListFlags_AllowVtxOffset` -> `ImDrawFlags_UseVtxOffset`
- `ImDrawListFlags_TextNoPixelSnap` -> `ImDrawFlags_TextNoPixelSnap`
Unifying them allows easily using them for both per-primitives and scope alterations.
- (Breaking) Enabling `ImFontAtlasFlags_NoBakedLines` in the font atlas will disable
support for anti-aliased lines.
- About `ImDrawFlags_StrokeLegacy`:
- This is designed to emulate old coordinates:
- Most shapes are "StrokeCenter".
- AddLine() adds a +0.5f,+0.5f offset.
- Closed shapes user miter angles.
- But there are known difference between legacy code and ImDrawFlags_StrokeLegacy:
- Thick shapes with acute angles will now preserve thickness.
- Thick shapes with acute angles will protrude a little more.
- About disabling anti-aliasing:
- Disabling anti-aliasing is now emulated by using different UV coordinates.
It does not result in a performance increase any more (however the tendency
is that the new code behave better than old code).
- Many thick shapes had broken corners with old no-AA code, and the old no-AA code
was wildly different from the AA code. Not the case any more. (#288)
- Tweaked line rendering in various locations to avoid blurryness:
- Windows: title-bar and menu-bar border (when thickness>1.0f).
- Tables: borders (when thickness>1.0f).
- SeparatorText: border (when thickness>1.0f).
- Tree: hierarchy lines (when thickness>1.0f).
- TabBar: selected overline border ((when thickness>1.0f).
- Demo: Custom Rendering: canvas lines.
- Checkbox, Menus: check marks use anti-aliased ends.
- Demo: Custom Rendering: exposed new flags; Showcasing overlapping strokes and
filled shapes; Added an option to animation thickness; Added new shapes to
showcase new rendering features that previously hit limitations.
In 1.93.0 , the ` ImDrawList` rendering API has been improved to be more robust and
more consistent over the whole range of shapes. The rendering now matches much closer
to common vector drawing APIs, like html canvas. Improvements, like anti-aliased line
endings and stroke position were added. T he coordinates passed to the API are now
consistently describing shape outlines .
For code using custom rendering: some details are now rendered slightly diffe rently
(even if g enerally more consistent). The difference in rendering is in the range of
half a pixel, but that can lead to issues like some lines now look blurrier or more
transparent. All ImGui widgets should appear identical or bett er.
The rendering of common shapes was optimized when the shapes fa ll on integer coordinat es
(which is most of the UI). This includes skipping anti-aliasing when not needed, or
using textures instead of tessellated geometry to draw round corners.
New rendering code fixes some inconsistencies between graphics APIs (e.g. DirectX vs OpenGL)
which are using different diamond exits rules. New code should work precisely the same
regardless of graphics API.
While the current version doesn't make lots of visible use of the new features and
facilities, they are among the pillars that will make it easier to create prettier
contents, both for custom rendering and future version s of the library .
Most of the work courtesy of @memononen .
Misc reviewing/guiding/fixing by @ocornut.
With legacy bits from @thedmd, @potocpav.
Refer to our guides:
- ImDrawList Vector Rendering Reference: https://github.com/ocornut/imgui/wiki/Draw-List
(includes a precise list of differences between 1.92.9 and 1.93.0) .
- Pixel Perfect Anti-aliased R end ering: https://github.com/ocornut/imgui/wiki/Pixel-Perfect-Rendering
- How Anti-aliased Polyline Rendering is Implemented: https://github.com/ocornut/imgui/wiki/Polyline-Rendering
Breaking Changes:
- ImDrawList:
- AddLine(): removed the (+0.5f,+0.5f) offset that was sneakily added to input coordinates.
- This fixes inconsistencies in the API and matches the PathXXX API.
- By default, stroke thickness extends on both side of the given segment.
e.g for a "pixel-perfect" looking line with thickness=1.0f, coords should be passed as center of each ends of the line.
- Use `ImDrawFlags_StrokeLegacy` to use old offset if required. Or you can apply the offset manually!
- Generally better to use the recently introduced `AddLineH()`, `AddLineV()` functions added in 1.92.8.
READ IF YOU ARE MINDFUL OF PIXEL-PERFECTNESS IN YOUR CUSTOM RENDERING/WIDGETS:
- TRANSITION GUIDE FOR AXIS-ALIGNED LINES:
- When switching from legacy `AddLine()` values to `AddLineV()`, `AddLineH()` you can keep same inputs coordinates as before:
- Old `AddLine({x, y1}, {x, y2}, col)` --> `AddLineV(x, y1, y2, col);` // Vertical line.
- Old `AddLine({x1, y}, {x2, y}, col)` --> `AddLineH(x1, x2, y, col);` // Horizontal line.
- This will be equivalent and faster for thickness=1.0f lines.
- Since `AddLine()` use default stroke pos Center and `AddLineV()`, `AddLineH()` use Inside, thickness>1.0f strokes will differ.
Using `ImDrawFlags_StrokeCenter` will match old result more closely (aka look centered),
but is more likely to look blurry as it already did before.
- Read table below about StrokePos and the "Pixel-Perfect Rendering" guide if you care about pixel-perfect lines.
- TRANSITION GUIDE FOR DIAGONAL LINES:
- Your lines will appear offset by -0.5f pixels on each axis.
Being anti-aliased diagonal lines, they won't look particularly better or worse, just slightly offset.
It'll likely only be noticeable if you carefully combined them with other primitives for a pixel-perfect result.
- Old `AddLine({x1, y1}, {x2, y2}, col)` --> `AddLine({x1 + 0.5f, y1 + 0.5f}, {x2+ 0.5f, y2 + 0.5f}, col);` // Same
or use `ImDrawFlags_StrokeLegacy` --> `AddLine({x1, y1}, {x2, y2}, col, thickness, ImDrawFlags_StrokeLegacy); // Offset by +0.5f + disable AA ends.
This reapplies the old offset, and should get you exactly the same result you previously
got for thickness=1.0f lines. But said result were previously sometimes ambiguous and
renderer-dependent. (#3116, #3258, #2441)
- Old code did not support anti-aliased ends, which could create gaps when rendering shapes out
of multiple contiguous lines instead of using `AddPolyline()`. There is a possibility that you
legacy code added fudge offsets here and there; which may not be necessary anymore if you use
`_AALineEnds`, or if you combine rendering of contiguous lines using `AddPolyline()`.
- AddRect, AddCircle, AddNgon, AddEllipse, AddTriangle, AddQuad: defaulting to "inside" stroke.
- All closed shapes with thickness=1.0f will appear identical.
- The difference for thickness>1.0f shapes may be minimal since very large strokes
were not well supported for widgets, but stroke will default inside widgets.
- Merged `ImDrawListFlags` into `ImDrawFlags`. `ImDrawListFlags` was rarely used directly
and generally setup by the ImGui context. Keep inline redirection enums (will obsolete).
- `ImDrawListFlags_AntiAliasedLines` -> `ImDrawFlags_AALines`
- `ImDrawListFlags_AntiAliasedFill` -> `ImDrawFlags_AAFill`
- `ImDrawListFlags_AllowVtxOffset` -> `ImDrawFlags_UseVtxOffset`
- `ImDrawListFlags_TextNoPixelSnap` -> `ImDrawFlags_TextNoPixelSnap`
Unifying them allows easily using them for both per-primitives and scope alterations.
- Marked `ImDrawListFlags_AntiAliasedLinesUseTex` and `style.AntiAliasedLinesUseTex` as
obsolete, as the new line rendering code always needs textures.
- Enabling `ImFontAtlasFlags_NoBakedLines` in the font atlas will now disable support for
anti-aliased lines by clearing `style.AntiAliasedLines`/`style.AntiAliasedLineEnds`.
- Style: obsoleted `style.CurveTessellationTol (default 1.25)` which was in Pixels² unit in
favor of `style.CurveTesselationMaxError` (default 1.12)` which is in Pixels unit. It is
easier to tweak + this allows us to easily scale error threshold on high density screens.
- style.CurveTesselationMaxError == sqrf(style.CurveTessellationTol).
Other Changes:
- ImDrawList:
- Added flags to specify stroke position in all `ImDrawList` stroking functions: [@memononen]
- `ImDrawFlags_StrokeInside` (default for Rect, Circle/Ellipse, Triangle, Quad, Ngon + AddLineH, AddLineV)
- `ImDrawFlags_StrokeCenter` (default for Line, Polyline, Beziers, Paths function)
- `ImDrawFlags_StrokeCenterBiased` (center w/ bias for pixel perfect alignment)
- `ImDrawFlags_StrokeOutside`
- `ImDrawFlags_StrokeLegacy` (match old behavior)
- Legacy mode may be set as default for a given scope using `PushDrawFlag(ImDrawFlags_StrokeLegacy, true)`.
- Legacy code was generally applying +0.50f offsets which meant that,
- with thickness=1.0f: the stroke would appear inside.
- with thickness>1.0f: the stroke would start expanding on both sides but starting from that small initial offset.
- with thickness>1.0f for even integer values, the stroke would look blurry.
- TL;DR; the logic didn't make much sense for thickness>1.0f.
- Defaulting to Inside for closed shapes ensure that rectangles and lines are
never blurry, regardless of thickness, as long as input coordinates/sizes
are integers. (#9359) Recap:
------------------------------------------------------------------------
Thickness Legacy Inside Outside Center CenterBiased
------------------------------------------------------------------------
1.0f sharp sharp sharp blurry sharp
2.0f blurry sharp sharp sharp sharp
3.0f sharp sharp sharp blurry sharp
------------------------------------------------------------------------
- Read our Wiki guides for more details: https://github.com/ocornut/imgui/wiki/Draw-List
- AddPolyline(), PathStroke(), AddTriangle(): the algorithm to render lines got overhauled.
(#2183, #2964, #7972 + #9360, #6331, #4250, #4091) [@memononen]
- Generally fixed rendering of thick strokes/paths.
- The new stroke expansion now uses corner miter calculation, which keeps thickness along
the line segments consistent. If the corner becomes too sharp, it will be bevelled to
avoid long spikes at corners.
- There are also some robustness measures for the case where the line thickness is larger
than the features being drawn.
- Rendering artifacts are still possible when the path features are smaller than line thickness,
but the artifacts should be more localized. The new implementation attempted to favor simple
implementation and robustness over the corner case accuracy.
- All functions: new rendering code fixes some inconsistencies between graphics APIs
(e.g. DirectX vs OpenGL) which are using different diamond exits rules. New code should
work precisely the same regardless of graphics API. (#3116, #3258, #2441) [@memononen]
- Added `ImDrawFlags_AALineEnds` flag to enable anti-aliased line ends.
- Most noticeable for thick lines.
- Also helps fill minor gaps if combining multiple individual lines. For best looking
continuous lines you should use AddPolyline(), it creates joins between line segments
to avoid any gaps.
- Added `style.AntiAliasedLineEnds` in ImGui to set default state.
- Enabling AA Ends by default would be more "correct", but since it is very slightly
slower and increases vertex/index data we decided to not enable it by default.
This keeps situations such as "throw tens of thousands of lines at ImDrawList"
optimal. You can opt-in for a given shape or in a scope using `PushDrawFlag()`.
- Added `ImDrawFlags_MiterOnly` flag to disable using beveled corner.
- Closer to legacy rendering and slightly faster, but corners sharper than
90 degrees may expand far out.
- Automatically used by AddRect(), AddCircle(), AddNgon(), AddEllipse() functions
since we know that the input path does not contain sharper corners.
- Added `ImDrawFlags_SquareCap` flag to extend lines ends using square caps. (#9360)
- AddConvexPolyFilled()/PathFillConvex(): improved to handle input geometry more robustly.
The rendering of sharp corners was improved. Earlier there were issues with sharp corners
either creating long spikes, or messing up the adjacent edge's anti-aliasing. Now the
anti-aliasing fringe calculation is more consistent, and sharp corners get bevelled to
avoid spikes. There might still be issues when the smallest extent of a long thin polygon
is less than a pixel. Also supports `ImDrawFlags_MiterOnly`, to facilitate matching
a stroke using the same flag.
- AddRect(), AddRectFilled(): various optimizations for rounded rectangles. (#1962)
- Integer-aligned coordinates and thicknesses will automatically use baked textures,
saving on both CPU and vertex/index data.
- Enabled by default. Use `ImFontAtlasFlags_NoBakedRoundCorners` to disable baking
round corners in font atlas.
- Added `ImDrawFlags_UseTexForRoundCorners` flag to enable in scope or per-shape.
Added for consistency and debugging, not really needed in practice.
- AddRectFilled(): non-integer coordinates will now display anti-aliased edges.
Previously, non-integer coordinates rendered with aliased edges snapped by the
rasterizer. (#6971)
- Improved debug-build performance in various locations.
- Improved minor mismatches when overlapping strokes and filled shapes.
For example, when using inside strokes,
- `AddRect()` and `AddRectFilled()` with rounding now overlap better. (#3656)
- `AddCircle()` and `AddCircleFilled()` now overlap better.
- Added ImDrawList::PushDrawFlag()/PopDrawFlag() to alter certain flags for a
scope and a given `ImDrawList`. (#9489)
- e.g. `PushDrawFlag(ImDrawFlags_StrokeLegacy, true);` enforce legacy tweaks.
- About `ImDrawFlags_StrokeLegacy`:
- This is designed to emulate old behavior:
- Most shapes use `ImDrawFlags_StrokeCenter`.
- AddLine() add +0.5f,+0.5f offset to position.
- AddCircle(), AddNgon() add a -0.5f offset to radius.
- Closed shapes use miter corners.
- Lines don't have anti-aliased ends.
- But there are known difference between legacy code and ImDrawFlags_StrokeLegacy:
- Thick shapes with acute angles will now preserve thickness better,
which may make them appear as protruding a little more.
- About disabling anti-aliasing:
- Disabling anti-aliasing is now emulated by applying different UV coordinates.
- It does not result in a performance increase or vertex/index data decrease any more.
(however the tendency is that the new code behaves better than old code).
- But may be a useful stylistic choice in some circumstances.
- Many thick shapes had broken corners with old no-AA code, and the old no-AA code
was wildly different from the AA code. Not the case any more. (#288)
- Per-viewport FramebufferScale for Apple/Retina screen is applied to draw lists:
- AA Fringe is scaled accordingly.
- Circle and Curves tessellation error are scaled accordingly.
- Fonts:
- Reworked `AddFontDefault()` to use `io.DisplayFrameBufferScale` as part of the heuristic
to select `AddFontDefaultVector()` by default, effectively using ProggyForever instead of
ProggyClean on most Apple/Retina setups by default.
- ImDrawList :
- Per-viewport FramebufferScale for Apple/Retina screen is applied to draw lists:
- AA F ringe is scaled accordingly.
- Circle and Curves tessellation error are scaled accordingly .
- Widgets :
- Checkbox, Menus: check marks use anti-aliased ends.
- Tweaked rende ring in various locations to avoid blurryness:
- Windows: title-bar and menu-bar border (when thickness>1.0f) .
- SeparatorText: border (when thickness>1.0f).
- Tree: hierarchy lines (when thickness>1.0f).
- InputText: input caret (when thickness>1.0f).
- TabBar: selected overline border (when thickness>1.0f).
- Demo: Custom Rendering: exposed new flags; showcasing overlapping strokes
and filled shapes; added an option to animate thickness; added new shapes
to showcase new rendering features that previously hit limitations.
- Backends:
- QNX: added QNX Screen backend. (#9492) [@mgorchak-blackberry]
- Examples: