mirror of
https://github.com/ocornut/imgui.git
synced 2026-11-06 06:25:54 +01:00
Merge branch 'master' into docking
# Conflicts: # backends/imgui_impl_metal.mm # backends/imgui_impl_vulkan.cpp # imgui.cpp
This commit is contained in:
commit
0cb6f6501c
@ -18,6 +18,7 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2026-XX-XX: Metal: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2026-10-06: Added support for render passes with multiple color attachments: we render to the first one and leave the others untouched. (#9574)
|
||||
// 2026-09-07: Round framebuffer dimensions to the nearest integer instead of truncating them. (#9538, 9515, #8628)
|
||||
// 2026-08-06: Metal: fixed resizing windows losing framebuffer scale. (#6828, #8856)
|
||||
// 2026-04-28: Added support for standard draw callbacks (in platform_io): DrawCallback_SetSamplerLinear and DrawCallback_SetSamplerNearest. (#9378, #9381)
|
||||
@ -67,14 +68,16 @@ static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows();
|
||||
- (instancetype)initWithBuffer:(id<MTLBuffer>)buffer;
|
||||
@end
|
||||
|
||||
#define IMGUI_IMPL_METAL_MAX_COLOR_ATTACHMENTS 8 // Metal's limit (see Metal Feature Set Tables). Not configurable.
|
||||
|
||||
// An object that encapsulates the data necessary to uniquely identify a
|
||||
// render pipeline state. These are used as cache keys.
|
||||
@interface FramebufferDescriptor : NSObject<NSCopying>
|
||||
@property (nonatomic, assign) unsigned long sampleCount;
|
||||
@property (nonatomic, assign) MTLPixelFormat colorPixelFormat;
|
||||
@property (nonatomic, assign) MTLPixelFormat depthPixelFormat;
|
||||
@property (nonatomic, assign) MTLPixelFormat stencilPixelFormat;
|
||||
- (instancetype)initWithRenderPassDescriptor:(MTLRenderPassDescriptor*)renderPassDescriptor;
|
||||
- (MTLPixelFormat)colorPixelFormatAtIndex:(NSUInteger)index;
|
||||
@end
|
||||
|
||||
@interface MetalTexture : NSObject
|
||||
@ -645,23 +648,33 @@ static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows()
|
||||
#pragma mark - FramebufferDescriptor implementation
|
||||
|
||||
@implementation FramebufferDescriptor
|
||||
{
|
||||
MTLPixelFormat _colorPixelFormats[IMGUI_IMPL_METAL_MAX_COLOR_ATTACHMENTS];
|
||||
}
|
||||
|
||||
- (instancetype)initWithRenderPassDescriptor:(MTLRenderPassDescriptor*)renderPassDescriptor
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
_sampleCount = renderPassDescriptor.colorAttachments[0].texture.sampleCount;
|
||||
_colorPixelFormat = renderPassDescriptor.colorAttachments[0].texture.pixelFormat;
|
||||
for (NSUInteger n = 0; n < IMGUI_IMPL_METAL_MAX_COLOR_ATTACHMENTS; n++)
|
||||
_colorPixelFormats[n] = renderPassDescriptor.colorAttachments[n].texture.pixelFormat;
|
||||
_depthPixelFormat = renderPassDescriptor.depthAttachment.texture.pixelFormat;
|
||||
_stencilPixelFormat = renderPassDescriptor.stencilAttachment.texture.pixelFormat;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (MTLPixelFormat)colorPixelFormatAtIndex:(NSUInteger)index
|
||||
{
|
||||
return _colorPixelFormats[index];
|
||||
}
|
||||
|
||||
- (nonnull id)copyWithZone:(nullable NSZone*)zone
|
||||
{
|
||||
FramebufferDescriptor* copy = [[FramebufferDescriptor allocWithZone:zone] init];
|
||||
copy.sampleCount = self.sampleCount;
|
||||
copy.colorPixelFormat = self.colorPixelFormat;
|
||||
memcpy(copy->_colorPixelFormats, _colorPixelFormats, sizeof(_colorPixelFormats));
|
||||
copy.depthPixelFormat = self.depthPixelFormat;
|
||||
copy.stencilPixelFormat = self.stencilPixelFormat;
|
||||
return copy;
|
||||
@ -670,10 +683,12 @@ static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows()
|
||||
- (NSUInteger)hash
|
||||
{
|
||||
NSUInteger sc = _sampleCount & 0x3;
|
||||
NSUInteger cf = _colorPixelFormat & 0x3FF;
|
||||
NSUInteger cf = _colorPixelFormats[0] & 0x3FF;
|
||||
NSUInteger df = _depthPixelFormat & 0x3FF;
|
||||
NSUInteger sf = _stencilPixelFormat & 0x3FF;
|
||||
NSUInteger hash = (sf << 22) | (df << 12) | (cf << 2) | sc;
|
||||
for (NSUInteger n = 1; n < IMGUI_IMPL_METAL_MAX_COLOR_ATTACHMENTS; n++)
|
||||
hash = hash * 31 + _colorPixelFormats[n];
|
||||
return hash;
|
||||
}
|
||||
|
||||
@ -683,7 +698,7 @@ static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows()
|
||||
if (![other isKindOfClass:[FramebufferDescriptor class]])
|
||||
return NO;
|
||||
return other.sampleCount == self.sampleCount &&
|
||||
other.colorPixelFormat == self.colorPixelFormat &&
|
||||
memcmp(other->_colorPixelFormats, _colorPixelFormats, sizeof(_colorPixelFormats)) == 0 &&
|
||||
other.depthPixelFormat == self.depthPixelFormat &&
|
||||
other.stencilPixelFormat == self.stencilPixelFormat;
|
||||
}
|
||||
@ -829,7 +844,7 @@ static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows()
|
||||
pipelineDescriptor.fragmentFunction = fragmentFunction;
|
||||
pipelineDescriptor.vertexDescriptor = vertexDescriptor;
|
||||
pipelineDescriptor.rasterSampleCount = self.framebufferDescriptor.sampleCount;
|
||||
pipelineDescriptor.colorAttachments[0].pixelFormat = self.framebufferDescriptor.colorPixelFormat;
|
||||
pipelineDescriptor.colorAttachments[0].pixelFormat = [self.framebufferDescriptor colorPixelFormatAtIndex:0];
|
||||
pipelineDescriptor.colorAttachments[0].blendingEnabled = YES;
|
||||
pipelineDescriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd;
|
||||
pipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
|
||||
@ -837,6 +852,11 @@ static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows()
|
||||
pipelineDescriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd;
|
||||
pipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne;
|
||||
pipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
|
||||
for (NSUInteger n = 1; n < IMGUI_IMPL_METAL_MAX_COLOR_ATTACHMENTS; n++) // Don't write to other color attachments, if any.
|
||||
{
|
||||
pipelineDescriptor.colorAttachments[n].pixelFormat = [self.framebufferDescriptor colorPixelFormatAtIndex:n];
|
||||
pipelineDescriptor.colorAttachments[n].writeMask = MTLColorWriteMaskNone;
|
||||
}
|
||||
pipelineDescriptor.depthAttachmentPixelFormat = self.framebufferDescriptor.depthPixelFormat;
|
||||
pipelineDescriptor.stencilAttachmentPixelFormat = self.framebufferDescriptor.stencilPixelFormat;
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2026-10-06: Added support for render passes with multiple color attachments: we render to the first one and leave the others untouched. (#9574)
|
||||
// 2026-09-07: Round framebuffer dimensions to the nearest integer instead of truncating them. (#9538, 9515, #8628)
|
||||
// 2026-08-06: Metal 4: fixed resizing windows losing framebuffer scale. (#6828, #8856)
|
||||
// 2026-07-07: Metal 4: Added metal-cpp support. (#9461)
|
||||
@ -59,14 +60,16 @@ struct ImGui_Metal4_ConstantData
|
||||
- (instancetype)initWithBuffer:(id<MTLBuffer>)buffer;
|
||||
@end
|
||||
|
||||
#define IMGUI_IMPL_METAL_MAX_COLOR_ATTACHMENTS 8 // Metal's limit (see Metal Feature Set Tables). Not configurable.
|
||||
|
||||
// An object that encapsulates the data necessary to uniquely identify a
|
||||
// render pipeline state. These are used as cache keys.
|
||||
@interface FramebufferDescriptor : NSObject<NSCopying>
|
||||
@property (nonatomic, assign) unsigned long sampleCount;
|
||||
@property (nonatomic, assign) MTLPixelFormat colorPixelFormat;
|
||||
@property (nonatomic, assign) MTLPixelFormat depthPixelFormat;
|
||||
@property (nonatomic, assign) MTLPixelFormat stencilPixelFormat;
|
||||
- (instancetype)initWithRenderPassDescriptor:(MTL4RenderPassDescriptor*)renderPassDescriptor;
|
||||
- (MTLPixelFormat)colorPixelFormatAtIndex:(NSUInteger)index;
|
||||
@end
|
||||
|
||||
@interface MetalTexture : NSObject
|
||||
@ -567,23 +570,33 @@ void ImGui_ImplMetal4_Shutdown()
|
||||
#pragma mark - FramebufferDescriptor implementation
|
||||
|
||||
@implementation FramebufferDescriptor
|
||||
{
|
||||
MTLPixelFormat _colorPixelFormats[IMGUI_IMPL_METAL_MAX_COLOR_ATTACHMENTS];
|
||||
}
|
||||
|
||||
- (instancetype)initWithRenderPassDescriptor:(MTL4RenderPassDescriptor*)renderPassDescriptor
|
||||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
_sampleCount = renderPassDescriptor.colorAttachments[0].texture.sampleCount;
|
||||
_colorPixelFormat = renderPassDescriptor.colorAttachments[0].texture.pixelFormat;
|
||||
for (NSUInteger n = 0; n < IMGUI_IMPL_METAL_MAX_COLOR_ATTACHMENTS; n++)
|
||||
_colorPixelFormats[n] = renderPassDescriptor.colorAttachments[n].texture.pixelFormat;
|
||||
_depthPixelFormat = renderPassDescriptor.depthAttachment.texture.pixelFormat;
|
||||
_stencilPixelFormat = renderPassDescriptor.stencilAttachment.texture.pixelFormat;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (MTLPixelFormat)colorPixelFormatAtIndex:(NSUInteger)index
|
||||
{
|
||||
return _colorPixelFormats[index];
|
||||
}
|
||||
|
||||
- (nonnull id)copyWithZone:(nullable NSZone*)zone
|
||||
{
|
||||
FramebufferDescriptor* copy = [[FramebufferDescriptor allocWithZone:zone] init];
|
||||
copy.sampleCount = self.sampleCount;
|
||||
copy.colorPixelFormat = self.colorPixelFormat;
|
||||
memcpy(copy->_colorPixelFormats, _colorPixelFormats, sizeof(_colorPixelFormats));
|
||||
copy.depthPixelFormat = self.depthPixelFormat;
|
||||
copy.stencilPixelFormat = self.stencilPixelFormat;
|
||||
return copy;
|
||||
@ -592,10 +605,12 @@ void ImGui_ImplMetal4_Shutdown()
|
||||
- (NSUInteger)hash
|
||||
{
|
||||
NSUInteger sc = _sampleCount & 0x3;
|
||||
NSUInteger cf = _colorPixelFormat & 0x3FF;
|
||||
NSUInteger cf = _colorPixelFormats[0] & 0x3FF;
|
||||
NSUInteger df = _depthPixelFormat & 0x3FF;
|
||||
NSUInteger sf = _stencilPixelFormat & 0x3FF;
|
||||
NSUInteger hash = (sf << 22) | (df << 12) | (cf << 2) | sc;
|
||||
for (NSUInteger n = 1; n < IMGUI_IMPL_METAL_MAX_COLOR_ATTACHMENTS; n++)
|
||||
hash = hash * 31 + _colorPixelFormats[n];
|
||||
return hash;
|
||||
}
|
||||
|
||||
@ -605,7 +620,7 @@ void ImGui_ImplMetal4_Shutdown()
|
||||
if (![other isKindOfClass:[FramebufferDescriptor class]])
|
||||
return NO;
|
||||
return other.sampleCount == self.sampleCount &&
|
||||
other.colorPixelFormat == self.colorPixelFormat &&
|
||||
memcmp(other->_colorPixelFormats, _colorPixelFormats, sizeof(_colorPixelFormats)) == 0 &&
|
||||
other.depthPixelFormat == self.depthPixelFormat &&
|
||||
other.stencilPixelFormat == self.stencilPixelFormat;
|
||||
}
|
||||
@ -761,7 +776,7 @@ fragment half4 fragment_main(VertexOut in [[stage_in]],
|
||||
pipelineDescriptor.fragmentFunction = fragmentFunction;
|
||||
pipelineDescriptor.vertexDescriptor = vertexDescriptor;
|
||||
pipelineDescriptor.rasterSampleCount = self.framebufferDescriptor.sampleCount;
|
||||
pipelineDescriptor.colorAttachments[0].pixelFormat = self.framebufferDescriptor.colorPixelFormat;
|
||||
pipelineDescriptor.colorAttachments[0].pixelFormat = [self.framebufferDescriptor colorPixelFormatAtIndex:0];
|
||||
pipelineDescriptor.colorAttachments[0].blendingEnabled = YES;
|
||||
pipelineDescriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd;
|
||||
pipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
|
||||
@ -769,6 +784,11 @@ fragment half4 fragment_main(VertexOut in [[stage_in]],
|
||||
pipelineDescriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd;
|
||||
pipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne;
|
||||
pipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
|
||||
for (NSUInteger n = 1; n < IMGUI_IMPL_METAL_MAX_COLOR_ATTACHMENTS; n++) // Don't write to other color attachments, if any.
|
||||
{
|
||||
pipelineDescriptor.colorAttachments[n].pixelFormat = [self.framebufferDescriptor colorPixelFormatAtIndex:n];
|
||||
pipelineDescriptor.colorAttachments[n].writeMask = MTLColorWriteMaskNone;
|
||||
}
|
||||
pipelineDescriptor.depthAttachmentPixelFormat = self.framebufferDescriptor.depthPixelFormat;
|
||||
pipelineDescriptor.stencilAttachmentPixelFormat = self.framebufferDescriptor.stencilPixelFormat;
|
||||
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2026-10-06: Added support for dynamic rendering with multiple color attachments (PipelineRenderingCreateInfo.colorAttachmentCount > 1): we render to the first one and leave the others untouched. (#9574)
|
||||
// 2026-09-07: Round framebuffer dimensions to the nearest integer instead of truncating them. (#9538, 9515, #8628)
|
||||
// 2026-09-03: Added for support for multiple Vulkan contexts with custom loaders. (#6616)
|
||||
// 2026-07-15: [Docking] Vulkan: fixed use-after-free when using multi-viewport with dynamic rendering path: deep-copy SurfaceFormat.format into the persistent buffer instead of storing a pointer to the viewport's wd->SurfaceFormat which dangles after the viewport is destroyed. (#9390, #9468)
|
||||
@ -1094,7 +1095,14 @@ static VkPipeline ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAlloc
|
||||
ms_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||
ms_info.rasterizationSamples = (info->MSAASamples != 0) ? info->MSAASamples : VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
VkPipelineColorBlendAttachmentState color_attachment[1] = {};
|
||||
// Blend into the first color attachment. With dynamic rendering, other color attachments of the rendering are left untouched (requires independentBlend feature).
|
||||
int color_attachment_count = 1;
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
if (bd->VulkanInitInfo.UseDynamicRendering && info->PipelineRenderingCreateInfo.colorAttachmentCount > 1)
|
||||
color_attachment_count = (int)info->PipelineRenderingCreateInfo.colorAttachmentCount;
|
||||
#endif
|
||||
ImVector<VkPipelineColorBlendAttachmentState> color_attachment;
|
||||
color_attachment.resize(color_attachment_count, VkPipelineColorBlendAttachmentState()); // colorWriteMask = 0
|
||||
color_attachment[0].blendEnable = VK_TRUE;
|
||||
color_attachment[0].srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||
color_attachment[0].dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
@ -1109,8 +1117,8 @@ static VkPipeline ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAlloc
|
||||
|
||||
VkPipelineColorBlendStateCreateInfo blend_info = {};
|
||||
blend_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
||||
blend_info.attachmentCount = 1;
|
||||
blend_info.pAttachments = color_attachment;
|
||||
blend_info.attachmentCount = (uint32_t)color_attachment.Size;
|
||||
blend_info.pAttachments = color_attachment.Data;
|
||||
|
||||
ImVector<VkDynamicState> dynamic_states = info->ExtraDynamicStates;
|
||||
dynamic_states.push_back(VK_DYNAMIC_STATE_VIEWPORT);
|
||||
|
||||
@ -108,6 +108,7 @@ struct ImGui_ImplVulkan_PipelineInfo
|
||||
// - As an convenience, by setting DescriptorPoolSize > 0 the backend will create one for you.
|
||||
// - About dynamic rendering:
|
||||
// - When using dynamic rendering, set UseDynamicRendering=true + fill PipelineInfoMain.PipelineRenderingCreateInfo structure.
|
||||
// - PipelineRenderingCreateInfo may describe multiple color attachments: we render to the first one and leave the others untouched. This requires the 'independentBlend' device feature.
|
||||
struct ImGui_ImplVulkan_InitInfo
|
||||
{
|
||||
uint32_t ApiVersion; // Fill with API version of Instance, e.g. VK_API_VERSION_1_3 or your value of VkApplicationInfo::apiVersion. May be lower than header version (VK_HEADER_VERSION_COMPLETE)
|
||||
|
||||
@ -39,8 +39,138 @@ HOW TO UPDATE?
|
||||
VERSION 1.93.0 WIP (In Progress)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
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. The coordinates passed to the API are now
|
||||
consistently describing shape outlines.
|
||||
|
||||
For code using custom rendering: 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
|
||||
transparent. All Dear ImGui widgets should appear identical or better.
|
||||
|
||||
The rendering 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 corners.
|
||||
The varying code-paths are designed to look indistinguishable from each others.
|
||||
|
||||
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.
|
||||
(note that using _StrokeLegacy mode can lead to similar inconsistencies)
|
||||
|
||||
New rendering code also deals better with animating thickness and rounding
|
||||
(integer values are recommended).
|
||||
|
||||
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 versions of the library.
|
||||
|
||||
Use `ImDrawFlags_StrokeLegacy` mode to emulate old rendering:
|
||||
- Per-primitive: draw_list->AddLine(..., ..., ImDrawFlags_StrokeLegacy);
|
||||
- For a given scope: draw_list->PushDrawFlag(ImDrawFlags_StrokeLegacy, true); draw_list->AddLine(...); draw_list->PopDrawFlag();
|
||||
- Globally: ImGui::Checkbox("DefaultsToStrokeLegacy", &io.ConfigDebugDrawListDefaultsToStrokeLegacy); // Map to a checkbox
|
||||
- Globally: io.ConfigDebugDrawListDefaultsToStrokeLegacy = io.KeyShift; // Map on Shift
|
||||
|
||||
Main work courtesy of @memononen.
|
||||
Additional work/reviewing/guidance 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).
|
||||
|
||||
- ImDrawList 1.92.9 vs 1.93.0 Interactive Testbed
|
||||
https://www.dearimgui.com/docs/drawlist_v193
|
||||
(interactively discuss and compare differences between 1.92.9 and 1.93.9)
|
||||
(downloadable HTML file, may be used offline)
|
||||
|
||||
- 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
|
||||
|
||||
- Main topic:
|
||||
https://github.com/ocornut/imgui/issues/9504
|
||||
(if you have a problem to discuss, please open a new issue)
|
||||
|
||||
Breaking Changes:
|
||||
|
||||
- DrawList:
|
||||
- AddLine(): removed the (+0.5f,+0.5f) offset that was sneakily added to input coordinates. (#9504)
|
||||
- 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, simple and faster to use `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.
|
||||
- AddCircle(), AddNgon(): removed +0.5f offset added to radius.
|
||||
- This fixes inconsistencies in the API.
|
||||
- Use `ImDrawFlags_StrokeLegacy` to use old method if required. Or you can apply the offset manually!
|
||||
- AddRectFilled(): non-integer coordinates will now display anti-aliased edges.
|
||||
Previously, non-integer coordinates rendered with aliased edges snapped by the
|
||||
rasterizer. (#6971)
|
||||
- AddRect(), AddRectFilled(): rectangles with inverted coordinates won't be visible
|
||||
unless using ImDrawList_StrokeLegacy mode. With inverted coordinates (min > max):
|
||||
- Legacy `AddRect()` rounding off -> visible but incorrect outer size.
|
||||
- Legacy `AddRect()` rounding on -> visible but very glitchy.
|
||||
- Legacy `AddRectFilled()` rounding off -> visible and correct.
|
||||
- Legacy `AddRectFilled()` rounding on -> visible but very glitchy.
|
||||
- Use `ImDrawFlags_StrokeLegacy` to use old rendering for cases without rounding, or fix coordinates.
|
||||
- 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.
|
||||
Kept redirection enums (will obsolete).
|
||||
- Renamed all `ImDrawFlags_RoundCornersXXX` flags to `ImDrawFlags_RoundXXX`.
|
||||
- `ImDrawFlags_RoundCornersAll` -> `ImDrawFlags_RoundAll`
|
||||
- `ImDrawFlags_RoundCornersNone` -> `ImDrawFlags_RoundNone`
|
||||
- `ImDrawFlags_RoundCornersTopLeft` -> `ImDrawFlags_RoundTopLeft`
|
||||
- `ImDrawFlags_RoundCornersTopRight` -> `ImDrawFlags_RoundTopRight`
|
||||
- `ImDrawFlags_RoundCornersBottomLeft` -> `ImDrawFlags_RoundBottomLeft`
|
||||
- `ImDrawFlags_RoundCornersBottomRight` -> `ImDrawFlags_RoundBottomRight`
|
||||
- `ImDrawFlags_RoundCornersTop` -> `ImDrawFlags_RoundTop`
|
||||
- `ImDrawFlags_RoundCornersBottom` -> `ImDrawFlags_RoundBottom`
|
||||
- `ImDrawFlags_RoundCornersLeft` -> `ImDrawFlags_RoundLeft`
|
||||
- `ImDrawFlags_RoundCornersRight` -> `ImDrawFlags_RoundRight`
|
||||
Kept redirection enums (will obsolete).
|
||||
- Marked `ImDrawListFlags_AntiAliasedLinesUseTex` and `style.AntiAliasedLinesUseTex` as
|
||||
obsolete, as the new line rendering code always uses 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.CurveTessellationMaxError` (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.
|
||||
@ -57,8 +187,127 @@ Breaking Changes:
|
||||
sub-optimal and not reliable on some setup. Use `ImGui_ImplOpenGL3_SetClipOrigin(0)`
|
||||
to enable auto-detection, or e.g. `ImGui_ImplOpenGL3_SetClipOrigin(GL_UPPER_LEFT)`.
|
||||
|
||||
|
||||
Other Changes:
|
||||
|
||||
- DrawList:
|
||||
- Added flags to specify stroke position in all `ImDrawList` stroking functions: (#9504) [@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
|
||||
- And interactive 1.92.9 vs 1.93.0 comparing testbed:
|
||||
https://www.dearimgui.com/docs/drawlist_v193
|
||||
- AddPolyline(), PathStroke(), AddTriangle(): the algorithm to render lines got overhauled.
|
||||
(#9504, #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]
|
||||
- Debug: added `io.ConfigDebugDrawListDefaultsToStrokeLegacy` to facilitate comparing old/new
|
||||
behaviors. This is equivalent to calling `PushDrawFlag(ImDrawFlags_StrokeLegacy, true)`
|
||||
on every drawlist.
|
||||
Suggested uses, e.g.
|
||||
- `io.ConfigDebugDrawListDefaultsToStrokeLegacy = io.KeyShift; // Map on holding Shift`
|
||||
- `ImGui::Checkbox("DefaultsToStrokeLegacy", &io.ConfigDebugDrawListDefaultsToStrokeLegacy);`
|
||||
- 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.
|
||||
- This is disabled by default! 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_JoinMiter` 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_CapSquare` 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_JoinMiter`, to facilitate matching
|
||||
a stroke using the same flag.
|
||||
- AddRect(), AddRectFilled(): various optimizations for rounded rectangles. (#1962, #9504)
|
||||
- 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.
|
||||
- AddCircle, AddCircleFilled: fixed large circles being under-tessellated
|
||||
(when above ~140 with default CircleTessellationMaxError).
|
||||
- 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.
|
||||
- AddRect() and AddRectFilled() allow inverted positions.
|
||||
- AddRectFilled() has no AA when passed non-integer coordinates.
|
||||
- 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.
|
||||
- Reworked assert in PushTexture() to allow convenience grace period of using a
|
||||
texture that was queue for destroy during the frame. Make it safe to stick to
|
||||
an existing texture during the frame. (#9528, #8465)
|
||||
- Added optional `platform_io.DrawCallback_SetSamplerFromTex` standard backend-agnostic
|
||||
draw callback for requesting to use the sampler associated already associated to a texture.
|
||||
Currently only supported by the OpenGL2/3 and SDLRenderer3 backend. (#9378)
|
||||
- Fixed dangling ImDrawList::_OwnerName when using animated label. (#9552) [@ubi-dcastonguay]
|
||||
|
||||
- Drags, Sliders:
|
||||
- Fixed an overflow using `ImGuiSliderFlags_Logarithmic` with S32/S64 types which
|
||||
leads to clamped interactions. (#9526, #3361, #1823, #1316, #642) [@lailoken]
|
||||
@ -136,22 +385,25 @@ Other Changes:
|
||||
the hashed data. (#9557, #9560) [@sthalik]
|
||||
- IO: restore default clipboard/ime/shell platform handlers on ClearPlatformHandlers(), fixing
|
||||
issues switching backends mid-session to one relying on default. (#9537, #8945, #2769) [@lstalmir]
|
||||
- DrawList:
|
||||
- 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.
|
||||
- Reworked assert in PushTexture() to allow convenience grace period of using a
|
||||
texture that was queue for destroy during the frame. Make it safe to stick to
|
||||
an existing texture during the frame. (#9528, #8465)
|
||||
- Added optional `platform_io.DrawCallback_SetSamplerFromTex` standard backend-agnostic
|
||||
draw callback for requesting to use the sampler associated already associated to a texture.
|
||||
Currently only supported by the OpenGL2/3 and SDLRenderer3 backend. (#9378)
|
||||
- Fixed dangling ImDrawList::_OwnerName when using animated label. (#9552) [@ubi-dcastonguay]
|
||||
- Widgets:
|
||||
- Checkbox, Menus: check marks use anti-aliased ends.
|
||||
- Tweaked rendering 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:
|
||||
- Added `Widgets->Mixed Values` section. (#5518, #5677, #6865)
|
||||
- Custom Rendering section: 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.
|
||||
- Style Editor: fixed style/colors combo box applying style when opening Combo.
|
||||
- Backends:
|
||||
- QNX: added QNX Screen backend. (#9492) [@mgorchak-blackberry]
|
||||
- Metal, Metal4: added support for rendering inside a render pass with multiple color
|
||||
attachments (e.g. when merged with other passes): we render to the first color attachment
|
||||
and leave the other ones untouched. (#9574) [@tqjxlm]
|
||||
- OpenGL2, OpenGL3: added support for `platform_io.DrawCallback_SetSamplerFromTex` draw
|
||||
callback to request using the sampler associated already associated to a texture. (#9378)
|
||||
- OpenGL2, OpenGL3: fixed `DrawCallback_ResetRenderState` handler not reseting all states
|
||||
@ -171,6 +423,9 @@ Other Changes:
|
||||
Note: this callback is only supported by selected rendering backends: most other graphics API
|
||||
don't have the equivalent of `SDL_SetTextureScaleMode()` and the callback won't work with them.
|
||||
- Vulkan: added for support for multiple Vulkan contexts with custom loaders. (#6616) [@lstalmir]
|
||||
- Vulkan: added support for rendering inside a render pass with multiple color attachments
|
||||
(e.g. when merged with other passes): we render to the first color attachment and leave the
|
||||
other ones untouched. (#9574) [@tqjxlm]
|
||||
- WebGPU: fixed passing non-integer sizes to `wgpuRenderPassEncoderSetViewport()`
|
||||
when `FramebufferScale` is >1.0f. (#9515, #8628) [@WayU]
|
||||
- WebGPU: update to build with wgpu-native 29.0+. (#9377, #9532, #9530) [@lucascompython, @ivan-enzhaev]
|
||||
|
||||
94
imgui.cpp
94
imgui.cpp
@ -403,6 +403,47 @@ IMPLEMENTING SUPPORT for ImGuiBackendFlags_RendererHasTextures:
|
||||
- likewise io.MousePos and GetMousePos() will use OS coordinates.
|
||||
If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos.
|
||||
|
||||
2026/10/07 (1.93.0) - large cleanup/refactor of ImDrawList. many issues and inconsistencies fixed! (#9504)
|
||||
BELOW IS A SIMPLIFIED/SHORTENED RECAP OF CHANGES. READ CHANGELOG AND LINKS ABOVE FOR MORE DETAILS!
|
||||
useful links:
|
||||
- ImDrawList 1.92.9 <> 1.93 Interactive Testbed: https://www.dearimgui.com/docs/drawlist_v193 (<-- you can download this locally)
|
||||
- ImDrawList Wiki Reference: https://github.com/ocornut/imgui/wiki/Draw-List
|
||||
- Discussion thread: https://github.com/ocornut/imgui/issues/9504
|
||||
- use ImDrawFlags_StrokeLegacy mode to emulate old rendering:
|
||||
- Per-primitive: draw_list->AddLine(..., ..., ImDrawFlags_StrokeLegacy);
|
||||
- For a given scope: draw_list->PushDrawFlag(ImDrawFlags_StrokeLegacy, true); draw_list->AddLine(...); draw_list->PopDrawFlag();
|
||||
- Globally: ImGui::Checkbox("DefaultsToStrokeLegacy", &io.ConfigDebugDrawListDefaultsToStrokeLegacy); // Map to a checkbox
|
||||
- Globally: io.ConfigDebugDrawListDefaultsToStrokeLegacy = io.KeyShift; // Map on Shift
|
||||
- AddLine: removed the (+0.5f,+0.5f) offset that was sneakily added to input coordinates by this function, and led to lots of inconsistencies.
|
||||
- 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, simpler and faster to use `AddLineH()`, `AddLineV()` functions added in 1.92.8.
|
||||
- IF YOU ARE MINDFUL OF PIXEL-PERFECTNESS IN YOUR CUSTOM RENDERING/WIDGETS read Changelog and links above for details.
|
||||
- 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.
|
||||
- AddCircle(), AddNgon(): removed +0.5f offset added to radius. This fixes inconsistencies in the API. Use `ImDrawFlags_StrokeLegacy` to use old method if required. Or you can apply the offset manually!
|
||||
- AddRectFilled(): non-integer coordinates will now display anti-aliased edges. Previously, non-integer coordinates rendered with aliased edges snapped by the rasterizer.
|
||||
- AddRect(), AddRectFilled(): rectangles with inverted coordinates won't be visible unless using ImDrawList_StrokeLegacy mode.
|
||||
With inverted coordinates:
|
||||
- Legacy `AddRect()` rounding off -> visible but incorrect outer size.
|
||||
- Legacy `AddRect()` rounding on -> visible but very glitchy.
|
||||
- Legacy `AddRectFilled()` rounding off -> visible and correct.
|
||||
- Legacy `AddRectFilled()` rounding on -> visible but very glitchy.
|
||||
- merged ImDrawListFlags into ImDrawFlags. obsoleted ImDrawListFlags (which were rarely used directly):
|
||||
- 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 alterations and scope alterations.
|
||||
- renamed ImDrawFlags_RoundCornersXXXX to ImDrawFlags_RoundXXXX.
|
||||
- ImDrawFlags_RoundCornersAll -> ImDrawFlags_RoundAll,
|
||||
- ImDrawFlags_RoundCornersNone -> ImDrawFlags_RoundNone,
|
||||
- ImDrawFlags_RoundCornersTopLeft -> ImDrawFlags_RoundTopLeft,
|
||||
- ImDrawFlags_RoundCornersTopRight -> ImDrawFlags_RoundTopRight,
|
||||
- ImDrawFlags_RoundCornersTop -> ImDrawFlags_RoundTop,
|
||||
- ImDrawFlags_RoundCornersBottom -> ImDrawFlags_RoundBottom,
|
||||
etc. kept redirection enums (will obsolete).
|
||||
- obsoleted style.AntiAliasedLinesUseTex and ImDrawListFlags_AntiAliasedLinesUseTex, as the new line rendering code always uses textures.
|
||||
- 2026/09/30 (1.93.0) - ImFont: renamed `AddRemapChar()` to `AddRemapCodepoint()` (rarely used, marked internal). (#609, #5748)
|
||||
- 2026/09/18 (1.93.0) - ImGuiTextFilter: removed `float width` parameter of `Draw(const char* filter, float width)`: prefer using `SetNextItemWidth(float)` which is standard. Kept inline redirection function.
|
||||
- 2026/08/03 (1.93.0) - Style: obsoleted `style.CurveTessellationTol (default 1.25)` which was in Pixels² unit in favor of `style.CurveTessellationMaxError` (default 1.12)` which is in Pixels unit.
|
||||
@ -1606,9 +1647,9 @@ ImGuiStyle::ImGuiStyle()
|
||||
MouseCursorScale = 1.0f; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later.
|
||||
|
||||
// Rendering & Tessellation
|
||||
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 (NOT point/nearest filtering).
|
||||
AntiAliasedFill = true; // Enable anti-aliased filled shapes (rounded rectangles, circles, etc.).
|
||||
AntiAliasedLines = true; // Enable anti-aliased lines/borders. Used at the beginning of the frame to set ImDrawFlags_AALines in all draw-lists.
|
||||
AntiAliasedLineEnds = false; // Enable anti-aliased lines/borders ends. Nicer for thick lines but more expensive. Used at the beginning of the frame to set ImDrawFlags_AALineEnds in all draw-lists.
|
||||
AntiAliasedFill = true; // Enable anti-aliased edges around filled shapes (rounded rectangles, circles, etc.). Used at the beginning of the frame to set ImDrawFlags_AAFill in all draw-lists.
|
||||
CurveTessellationMaxError = 1.12f; // Maximum error (in pixels) 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.
|
||||
|
||||
@ -1624,6 +1665,7 @@ ImGuiStyle::ImGuiStyle()
|
||||
_NextFrameFontSizeBase = 0.0f;
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
CurveTessellationTol = 0.0f; // Old CurveTessellationTol = CurveTessellationMaxError*CurveTessellationMaxError.
|
||||
AntiAliasedLinesUseTex = true; // Enable anti-aliased lines/borders using textures for legacy strokes. Require backend to render with bilinear filtering (NOT point/nearest filtering).
|
||||
#endif
|
||||
|
||||
// Default theme
|
||||
@ -5805,15 +5847,21 @@ static void SetupDrawListSharedData()
|
||||
g.DrawListSharedData.ClipRectFullscreen = virtual_space.ToVec4();
|
||||
g.DrawListSharedData.CurveTessellationMaxError = g.Style.CurveTessellationMaxError;
|
||||
g.DrawListSharedData.SetCircleTessellationMaxError(g.Style.CircleTessellationMaxError);
|
||||
g.DrawListSharedData.InitialFlags = ImDrawListFlags_None;
|
||||
if (g.Style.AntiAliasedLines)
|
||||
g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLines;
|
||||
if (g.Style.AntiAliasedLinesUseTex && !(g.IO.Fonts->Flags & ImFontAtlasFlags_NoBakedLines))
|
||||
g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLinesUseTex;
|
||||
g.DrawListSharedData.InitialDrawFlags = ImDrawFlags_None;
|
||||
if (g.IO.Fonts->Flags & ImFontAtlasFlags_NoBakedLines)
|
||||
g.Style.AntiAliasedLines = g.Style.AntiAliasedLineEnds = false;
|
||||
if (g.Style.AntiAliasedFill)
|
||||
g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedFill;
|
||||
g.DrawListSharedData.InitialDrawFlags |= ImDrawFlags_AAFill;
|
||||
if (g.Style.AntiAliasedLines)
|
||||
g.DrawListSharedData.InitialDrawFlags |= ImDrawFlags_AALines;
|
||||
if (g.Style.AntiAliasedLineEnds)
|
||||
g.DrawListSharedData.InitialDrawFlags |= ImDrawFlags_AALineEnds;
|
||||
if (g.IO.ConfigDebugDrawListDefaultsToStrokeLegacy)
|
||||
g.DrawListSharedData.InitialDrawFlags |= ImDrawFlags_StrokeLegacy;
|
||||
if (!(g.IO.Fonts->Flags & ImFontAtlasFlags_NoBakedRoundCorners))
|
||||
g.DrawListSharedData.InitialDrawFlags |= ImDrawFlags_UseTexForRoundCorners | ImDrawFlags_AllowTexForRoundCorners_;
|
||||
if (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset)
|
||||
g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AllowVtxOffset;
|
||||
g.DrawListSharedData.InitialDrawFlags |= ImDrawFlags_UseVtxOffset;
|
||||
}
|
||||
|
||||
void ImGui::NewFrame()
|
||||
@ -7623,7 +7671,7 @@ static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
|
||||
if (g.Style.FrameBorderSize > 0 && !(window->Flags & ImGuiWindowFlags_NoTitleBar) && !window->DockIsActive)
|
||||
{
|
||||
float y = window->Pos.y + window->TitleBarHeight - 1;
|
||||
window->DrawList->AddLineH(window->Pos.x + border_size * 0.5f, window->Pos.x + window->Size.x - border_size * 0.5f, y, border_col, g.Style.FrameBorderSize);
|
||||
window->DrawList->AddLineH(window->Pos.x + border_size, window->Pos.x + window->Size.x - border_size, y, border_col, g.Style.FrameBorderSize, ImDrawFlags_StrokeCenterBiased);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7703,7 +7751,7 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar
|
||||
if (window->DockIsActive)
|
||||
bg_rounding_flags = CalcRoundingFlagsForRectInRect(bg_rect, window->DockNode->HostWindow->Rect(), 0.0f);
|
||||
else
|
||||
bg_rounding_flags = (flags & ImGuiWindowFlags_NoTitleBar) ? ImDrawFlags_RoundCornersAll : ImDrawFlags_RoundCornersBottom;
|
||||
bg_rounding_flags = (flags & ImGuiWindowFlags_NoTitleBar) ? ImDrawFlags_RoundAll : ImDrawFlags_RoundBottom;
|
||||
ImDrawList* bg_draw_list = window->DockIsActive ? window->DockNode->HostWindow->DrawList : window->DrawList;
|
||||
if (window->DockIsActive)
|
||||
bg_draw_list->ChannelsSetCurrent(DOCKING_HOST_DRAW_CHANNEL_BG);
|
||||
@ -7723,7 +7771,7 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar
|
||||
ImU32 title_bar_col = GetColorU32(title_bar_is_highlight ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg);
|
||||
if (window->ViewportOwned)
|
||||
title_bar_col |= IM_COL32_A_MASK; // No alpha
|
||||
window->DrawList->AddRectFilled(title_bar_rect.Min, title_bar_rect.Max, title_bar_col, window_rounding, ImDrawFlags_RoundCornersTop);
|
||||
window->DrawList->AddRectFilled(title_bar_rect.Min, title_bar_rect.Max, title_bar_col, window_rounding, ImDrawFlags_RoundTop);
|
||||
}
|
||||
|
||||
// Menu bar
|
||||
@ -7731,9 +7779,9 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar
|
||||
{
|
||||
ImRect menu_bar_rect = window->MenuBarRect();
|
||||
menu_bar_rect.ClipWith(window->Rect()); // Soft clipping, in particular child window don't have minimum size covering the menu bar so this is useful for them.
|
||||
window->DrawList->AddRectFilled(menu_bar_rect.Min, menu_bar_rect.Max, GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImDrawFlags_RoundCornersTop);
|
||||
window->DrawList->AddRectFilled(menu_bar_rect.Min, menu_bar_rect.Max, GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImDrawFlags_RoundTop);
|
||||
if (style.FrameBorderSize > 0.0f && menu_bar_rect.Max.y < window->Pos.y + window->Size.y)
|
||||
window->DrawList->AddLineH(menu_bar_rect.Min.x + window_border_size * 0.5f, menu_bar_rect.Max.x - window_border_size * 0.5f, menu_bar_rect.Max.y, GetColorU32(ImGuiCol_Border), style.FrameBorderSize);
|
||||
window->DrawList->AddLineH(menu_bar_rect.Min.x + window_border_size, menu_bar_rect.Max.x - window_border_size, menu_bar_rect.Max.y, GetColorU32(ImGuiCol_Border), style.FrameBorderSize, ImDrawFlags_StrokeCenterBiased);
|
||||
}
|
||||
|
||||
// Docking: Unhide tab bar (small triangle in the corner), drag from small triangle to quickly undock
|
||||
@ -23615,10 +23663,9 @@ void ImGui::DebugNodeDrawList(ImGuiWindow* window, ImGuiViewportP* viewport, con
|
||||
Selectable(buf, false);
|
||||
if (fg_draw_list && IsItemHovered())
|
||||
{
|
||||
ImDrawListFlags backup_flags = fg_draw_list->Flags;
|
||||
fg_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines is more readable for very large and thin triangles.
|
||||
fg_draw_list->PushDrawFlag(ImDrawFlags_AALines, false); // Disable AA on triangle outlines is more readable for very large and thin triangles.
|
||||
fg_draw_list->AddPolyline(triangle, 3, IM_COL32(255, 255, 0, 255), 1.0f, ImDrawFlags_Closed);
|
||||
fg_draw_list->Flags = backup_flags;
|
||||
fg_draw_list->PopDrawFlag();
|
||||
}
|
||||
}
|
||||
TreePop();
|
||||
@ -23634,8 +23681,7 @@ void ImGui::DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList* out_draw_list, co
|
||||
// Draw wire-frame version of all triangles
|
||||
ImRect clip_rect = draw_cmd->ClipRect;
|
||||
ImRect vtxs_rect(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX);
|
||||
ImDrawListFlags backup_flags = out_draw_list->Flags;
|
||||
out_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines is more readable for very large and thin triangles.
|
||||
out_draw_list->PushDrawFlag(ImDrawFlags_AALines, false); // Disable AA on triangle outlines is more readable for very large and thin triangles.
|
||||
for (unsigned int idx_n = draw_cmd->IdxOffset, idx_end = draw_cmd->IdxOffset + draw_cmd->ElemCount; idx_n < idx_end; )
|
||||
{
|
||||
ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL; // We don't hold on those pointers past iterations as ->AddPolyline() may invalidate them if out_draw_list==draw_list
|
||||
@ -23653,7 +23699,7 @@ void ImGui::DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList* out_draw_list, co
|
||||
out_draw_list->AddRect(ImTrunc(clip_rect.Min), ImTrunc(clip_rect.Max), IM_COL32(255, 0, 255, 255)); // In pink: clipping rectangle submitted to GPU
|
||||
out_draw_list->AddRect(ImTrunc(vtxs_rect.Min), ImTrunc(vtxs_rect.Max), IM_COL32(0, 255, 255, 255)); // In cyan: bounding box of triangles
|
||||
}
|
||||
out_draw_list->Flags = backup_flags;
|
||||
out_draw_list->PopDrawFlag();
|
||||
}
|
||||
|
||||
// [DEBUG] Compute mask of inputs with the same codepoint.
|
||||
@ -24303,9 +24349,9 @@ void ImGui::DebugDrawLineExtents(ImU32 col)
|
||||
float curr_x = window->DC.CursorPos.x;
|
||||
float line_y1 = (window->DC.IsSameLine ? window->DC.CursorPosPrevLine.y : window->DC.CursorPos.y);
|
||||
float line_y2 = line_y1 + (window->DC.IsSameLine ? window->DC.PrevLineSize.y : window->DC.CurrLineSize.y);
|
||||
window->DrawList->AddLineH(curr_x - 5.0f, curr_x + 5.0f, line_y1, col, 1.0f);
|
||||
window->DrawList->AddLineV(curr_x - 0.5f, line_y1, line_y2, col, 1.0f);
|
||||
window->DrawList->AddLineH(curr_x - 5.0f, curr_x + 5.0f, line_y2, col, 1.0f);
|
||||
window->DrawList->AddLineH(curr_x - 4.0f, curr_x + 5.0f, line_y1, col, 1.0f);
|
||||
window->DrawList->AddLineV(curr_x, line_y1, line_y2, col, 1.0f);
|
||||
window->DrawList->AddLineH(curr_x - 4.0f, curr_x + 5.0f, line_y2, col, 1.0f);
|
||||
}
|
||||
|
||||
// Draw last item rect in ForegroundDrawList (so it is always visible)
|
||||
|
||||
221
imgui.h
221
imgui.h
@ -30,7 +30,7 @@
|
||||
// Library Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||
#define IMGUI_VERSION "1.93.0 WIP"
|
||||
#define IMGUI_VERSION_NUM 19297
|
||||
#define IMGUI_VERSION_NUM 19298
|
||||
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
|
||||
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
|
||||
#define IMGUI_HAS_VIEWPORT // In 'docking' WIP branch.
|
||||
@ -51,7 +51,7 @@ Index of this file:
|
||||
// [SECTION] Misc data structures (ImGuiInputTextCallbackData, ImGuiSizeCallbackData, ImGuiWindowClass, ImGuiPayload)
|
||||
// [SECTION] Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, Math Operators, ImColor)
|
||||
// [SECTION] Multi-Select API flags and structures (ImGuiMultiSelectFlags, ImGuiMultiSelectIO, ImGuiSelectionRequest, ImGuiSelectionBasicStorage, ImGuiSelectionExternalStorage)
|
||||
// [SECTION] Drawing API (ImDrawCallback, ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawFlags, ImDrawListFlags, ImDrawList, ImDrawData)
|
||||
// [SECTION] Drawing API (ImDrawCallback, ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawFlags, ImDrawList, ImDrawData)
|
||||
// [SECTION] Texture API (ImTextureFormat, ImTextureStatus, ImTextureRect, ImTextureData)
|
||||
// [SECTION] Font API (ImFontConfig, ImFontGlyph, ImFontGlyphRangesBuilder, ImFontAtlasFlags, ImFontAtlas, ImFontBaked, ImFont)
|
||||
// [SECTION] Viewports (ImGuiViewportFlags, ImGuiViewport)
|
||||
@ -250,7 +250,6 @@ typedef int ImGuiTableBgTarget; // -> enum ImGuiTableBgTarget_ // Enum: A
|
||||
// - In Visual Studio w/ Visual Assist installed: Alt+G ("VAssistX.GoToImplementation") can also follow symbols inside comments.
|
||||
// - In VS Code, CLion, etc.: Ctrl+Click can follow symbols inside comments.
|
||||
typedef int ImDrawFlags; // -> enum ImDrawFlags_ // Flags: for ImDrawList functions
|
||||
typedef int ImDrawListFlags; // -> enum ImDrawListFlags_ // Flags: for ImDrawList instance
|
||||
typedef int ImDrawTextFlags; // -> enum ImDrawTextFlags_ // Internal, do not use!
|
||||
typedef int ImFontFlags; // -> enum ImFontFlags_ // Flags: for ImFont
|
||||
typedef int ImFontAtlasFlags; // -> enum ImFontAtlasFlags_ // Flags: for ImFontAtlas
|
||||
@ -2484,9 +2483,9 @@ struct ImGuiStyle
|
||||
float MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). We apply per-monitor DPI scaling over this scale. May be removed later.
|
||||
|
||||
// Rendering & Tessellation
|
||||
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 (NOT point/nearest 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 AntiAliasedLines; // Enable anti-aliased lines/borders. Used at the beginning of the frame to set ImDrawFlags_AALines in all draw-lists.
|
||||
bool AntiAliasedLineEnds; // Enable anti-aliased lines/borders ends. Nicer for thick lines but more expensive. Used at the beginning of the frame to set ImDrawFlags_AALineEnds in all draw-lists.
|
||||
bool AntiAliasedFill; // Enable anti-aliased edges around filled shapes (rounded rectangles, circles, etc.). Used at the beginning of the frame to set ImDrawFlags_AAFill in all draw-lists.
|
||||
float CurveTessellationMaxError; // Maximum error (in pixels) 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.
|
||||
|
||||
@ -2511,6 +2510,7 @@ struct ImGuiStyle
|
||||
|
||||
// Obsolete names
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
bool AntiAliasedLinesUseTex; // [OBSOLETE] Enable anti-aliased lines/borders using textures for legacy strokes. Require backend to render with bilinear filtering (NOT point/nearest filtering). Latched at the beginning of the frame (copied to ImDrawList).
|
||||
float CurveTessellationTol; // [OBSOLETE] Old CurveTessellationTol = New CurveTessellationMaxError*CurveTessellationMaxError. // Changed in 1.93.0
|
||||
// TabMinWidthForCloseButton = TabCloseButtonMinWidthUnselected // Renamed in 1.91.9.
|
||||
#endif
|
||||
@ -2667,6 +2667,11 @@ struct ImGuiIO
|
||||
// - Backends may have other side-effects on focus loss, so this will reduce side-effects but not necessary remove all of them.
|
||||
bool ConfigDebugIgnoreFocusLoss; // = false // Ignore io.AddFocusEvent(false), consequently not calling io.ClearInputKeys()/io.ClearInputMouse() in input processing.
|
||||
|
||||
// Option to compare < 1.93.0 rendering details vs 1.93.0 rendering details. (#9504)
|
||||
// - Equivalent to calling PushDrawFlag(ImDrawList_StrokeLegacy,true) on every draw list instances.
|
||||
// - Suggested use, e.g. io.ConfigDebugDrawListDefaultsToStrokeLegacy = io.KeyShift; // Map to SHIFT modifier
|
||||
bool ConfigDebugDrawListDefaultsToStrokeLegacy; // false // Default all ImDrawList to ImDrawList_StrokeLegacy mode, mimicking pre-1.93.0 rendering.
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Platform Identifiers
|
||||
// (the imgui_impl_xxxx backend files are setting those up for you)
|
||||
@ -3019,6 +3024,20 @@ struct ImGuiStorage
|
||||
#endif
|
||||
};
|
||||
|
||||
// [Internal] Used for small stacks. Do not use.
|
||||
template<typename T, int Capacity, typename SZ_T = ImU16>
|
||||
struct ImSmallStack_
|
||||
{
|
||||
T LocalData[Capacity]; // FIXME: should evolve into using heap, e.g union {} with T* HeapData + add SZ_T Capacity.
|
||||
SZ_T Size = 0;
|
||||
|
||||
inline void clear() { Size = 0; }
|
||||
inline T& back() { IM_ASSERT(Size > 0); return LocalData[Size - 1]; }
|
||||
inline void push_back(const T& v) { IM_ASSERT(Size < Capacity); memcpy(&LocalData[Size], &v, sizeof(v)); Size++; }
|
||||
inline void pop_back() { IM_ASSERT(Size > 0); Size--; }
|
||||
inline int capacity() const { return Capacity; }
|
||||
};
|
||||
|
||||
// Flags for ImGuiListClipper (currently not fully exposed in function calls: a future refactor will likely add this to ImGuiListClipper::Begin function equivalent)
|
||||
enum ImGuiListClipperFlags_
|
||||
{
|
||||
@ -3332,15 +3351,10 @@ struct ImGuiSelectionExternalStorage
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Drawing API (ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawListFlags, ImDrawList, ImDrawData)
|
||||
// [SECTION] Drawing API (ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawFlags, ImDrawList, ImDrawData)
|
||||
// Hold a series of drawing commands. The user provides a renderer for ImDrawData which essentially contains an array of ImDrawList.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// The maximum line width to bake anti-aliased textures for. Build atlas with ImFontAtlasFlags_NoBakedLines to disable baking.
|
||||
#ifndef IM_DRAWLIST_TEX_LINES_WIDTH_MAX
|
||||
#define IM_DRAWLIST_TEX_LINES_WIDTH_MAX (32)
|
||||
#endif
|
||||
|
||||
// ImDrawIdx: vertex index. [Compile-time configurable type]
|
||||
// - To use 16-bit indices + allow large meshes: backend need to set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset' and handle ImDrawCmd::VtxOffset (recommended).
|
||||
// - To use 32-bit indices: override with '#define ImDrawIdx unsigned int' in your imconfig.h file.
|
||||
@ -3434,40 +3448,82 @@ struct ImDrawListSplitter
|
||||
// Flags for ImDrawList functions
|
||||
enum ImDrawFlags_
|
||||
{
|
||||
ImDrawFlags_None = 0,
|
||||
ImDrawFlags_None = 0,
|
||||
//ImDrawFlags_Closed = 1, // -> FLAG MOVED BELOW. Prior to 1.92.8 (May 2026): ImDrawFlags_Closed was guaranteed to be == (1<<0) == 1, for legacy compatibility reason. Hardcoded use of 1 or true should be replaced with 'ImDrawFlags_Closed'.
|
||||
|
||||
// Rounding for AddRect(), AddRectFilled(), PathRect()
|
||||
// - When not specified, we defaults to ImDrawFlags_RoundCornersAll! So you only need to use those flags if you want another configuration.
|
||||
ImDrawFlags_RoundCornersTopLeft = 1 << 4, // Round top-left corner only (when rounding > 0.0f, we default to all corners).
|
||||
ImDrawFlags_RoundCornersTopRight = 1 << 5, // Round top-right corner only (when rounding > 0.0f, we default to all corners).
|
||||
ImDrawFlags_RoundCornersBottomLeft = 1 << 6, // Round bottom-left corner only (when rounding > 0.0f, we default to all corners).
|
||||
ImDrawFlags_RoundCornersBottomRight = 1 << 7, // Round bottom-right corner only (when rounding > 0.0f, we default to all corners).
|
||||
ImDrawFlags_RoundCornersNone = 1 << 8, // Disable rounding even if `float rounding > 0.0f`. This is NOT zero, NOT an implicit flag!
|
||||
ImDrawFlags_RoundCornersAll = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight | ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight, // (Default!!)
|
||||
ImDrawFlags_RoundCornersDefault_ = ImDrawFlags_RoundCornersAll, // Default to ALL corners if none of the _RoundCornersXX flags are specified!
|
||||
ImDrawFlags_RoundCornersTop = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight,
|
||||
ImDrawFlags_RoundCornersBottom = ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight,
|
||||
ImDrawFlags_RoundCornersLeft = ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersTopLeft,
|
||||
ImDrawFlags_RoundCornersRight = ImDrawFlags_RoundCornersBottomRight | ImDrawFlags_RoundCornersTopRight,
|
||||
ImDrawFlags_RoundCornersMask_ = ImDrawFlags_RoundCornersAll | ImDrawFlags_RoundCornersNone,
|
||||
// About usage of flags:
|
||||
// - "Prim" column: 'OK' = flag can be used to configure an individual AddXXX() call.
|
||||
// - "Scope" column: 'OK' = initialized by ImGui based on Style options (e.g. whether anti-aliased is enabled) + may be modified using ImDrawList::PushDrawFlag().
|
||||
// OK(0)/OK(1) indicates whether this flag is set in the default ImGui Style settings.
|
||||
|
||||
// Stroke options
|
||||
ImDrawFlags_Closed = 1 << 9, // PathStroke(), AddPolyline(): specify that shape should be closed.
|
||||
//ImDrawFlags_Closed = 1, // Prior to 1.92.8 (May 2026), ImDrawFlags_Closed was guaranteed to be == 1<<0 == 1 for legacy compatibility reason. Hardcoded use of 1 or true should be replaced.
|
||||
// - Rounding default to ImDrawFlags_RoundAll when 'rounding > 0'.
|
||||
// - So you only need to use the ImDrawFlags_RoundXXX flags if you want a special configuration (e.g. a rectangle with one rounded corner).
|
||||
// Rounding for AddRectXXX(), PathRect() ------ // Prim/Scope?
|
||||
ImDrawFlags_RoundTopLeft = 1 << 4, // OK -- // Round top-left corner only (when 'rounding > 0.0f', we default to all corners).
|
||||
ImDrawFlags_RoundTopRight = 1 << 5, // OK -- // Round top-right corner only (when 'rounding > 0.0f', we default to all corners).
|
||||
ImDrawFlags_RoundBottomLeft = 1 << 6, // OK -- // Round bottom-left corner only (when 'rounding > 0.0f', we default to all corners).
|
||||
ImDrawFlags_RoundBottomRight = 1 << 7, // OK -- // Round bottom-right corner only (when 'rounding > 0.0f', we default to all corners).
|
||||
ImDrawFlags_RoundNone = 1 << 8, // OK -- // Disable rounding even when 'rounding > 0.0f'. This value is NOT zero, it is NOT an implicit flag!
|
||||
ImDrawFlags_RoundAll = ImDrawFlags_RoundTopLeft | ImDrawFlags_RoundTopRight | ImDrawFlags_RoundBottomLeft | ImDrawFlags_RoundBottomRight, // (Default!!)
|
||||
ImDrawFlags_RoundTop = ImDrawFlags_RoundTopLeft | ImDrawFlags_RoundTopRight,
|
||||
ImDrawFlags_RoundBottom = ImDrawFlags_RoundBottomLeft | ImDrawFlags_RoundBottomRight,
|
||||
ImDrawFlags_RoundLeft = ImDrawFlags_RoundBottomLeft | ImDrawFlags_RoundTopLeft,
|
||||
ImDrawFlags_RoundRight = ImDrawFlags_RoundBottomRight | ImDrawFlags_RoundTopRight,
|
||||
|
||||
ImDrawFlags_InvalidMask_ = ~0x7FFFFFF0, // == 0x8000000F,
|
||||
};
|
||||
// Stroke Options ----------------------------- // Prim/Scope?
|
||||
ImDrawFlags_Closed = 1 << 9, // OK -- // PathStroke(), AddPolyline(): specify that shape should be closed.
|
||||
ImDrawFlags_JoinMiter = 1 << 10, // OK -- // PathStroke(), AddPolyline(): use miter joins/corners only. This assumes that the input polyline does not have corners sharper than 90 degrees. Slightly faster.
|
||||
ImDrawFlags_CapSquare = 1 << 11, // OK -- // PathStroke(), AddPolyline(): use square cap line ends.
|
||||
|
||||
// Flags for ImDrawList instance. Those are set automatically by ImGui:: functions from ImGuiIO settings, and generally not manipulated directly.
|
||||
// It is however possible to temporarily alter flags between calls to ImDrawList:: functions.
|
||||
enum ImDrawListFlags_
|
||||
{
|
||||
ImDrawListFlags_None = 0,
|
||||
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 (NOT point/nearest filtering).
|
||||
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.
|
||||
// About Stroke Ends:
|
||||
// - Rendering is optimized for fast pixel-perfect UI, so line ends are not anti-aliased by default. It's cheaper (we can emit less vertices).
|
||||
// - For more free-form drawings, light graphs and markers, or when using thick strokes: you can turn them on using the ImDrawFlags_AALineEnds flag.
|
||||
// - See 'Demo->Examples->Custom Rendering' to interactively toy with those flags.
|
||||
// - 'OK*' indicates using this at the AddXXX() call site is unlikely: it would only makes sense if (1) the option is disabled in style/scope and (2) you want to forcefully enable it for a single primitives. Possible but unlikely! Only supported for functions taking flags inputs.
|
||||
// Stroke/Fill Anti-aliasing ------------------ // Prim/Scope?
|
||||
ImDrawFlags_AAFill = 1 << 12, // OK* OK(1) // Enable anti-aliasing for Filled shapes.
|
||||
ImDrawFlags_AALines = 1 << 13, // OK* OK(1) // Enable anti-aliasing for Strokes (lines, borders).
|
||||
ImDrawFlags_AALineEnds = 1 << 14, // OK OK(0) // Enable anti-aliasing for Strokes Ends. Requires AALines to also be enabled. Useful on thick strokes or for precise continuity of multiple lines. A little more costly.
|
||||
//ImDrawFlags_NoAA = 1 << 15, // OK -- // Disable anti-aliasing for a given primitive.
|
||||
//ImDrawFlags_NoAALineEnds = 1 << 16, // OK -- // Disable anti-aliasing ends for a given primitive.
|
||||
|
||||
// About Stroke Position:
|
||||
// - Read https://github.com/ocornut/imgui/wiki/Draw-List (this guide includes a precise list of differences between 1.92.9 and 1.93.0)
|
||||
// - Read https://github.com/ocornut/imgui/wiki/Pixel-Perfect-Rendering
|
||||
// Stroke Position relative to shape outline -- // Prim/Scope?
|
||||
ImDrawFlags_StrokeInside = 1 << 17, // OK -- // Draw stroke inside of the shape outline (default for closed shapes and AddLineH, AddLineV functions)
|
||||
ImDrawFlags_StrokeCenter = 2 << 17, // OK -- // Draw stroke at the center of the shape outline (default for paths, bezier, and AddLine functions)
|
||||
ImDrawFlags_StrokeCenterBiased = 3 << 17, // OK -- // Draw stroke at the center of the shape outline, so that half thickness rounded down will be outside, and the rest inside the shape outline. Useful for axis-aligned shapes: AddLineH, AddLineV, AddRect. Does not animate well!
|
||||
ImDrawFlags_StrokeOutside = 4 << 17, // OK -- // Draw stroke outside of the shape outline
|
||||
ImDrawFlags_StrokeLegacy = 7 << 17, // OK OK(0) // Use legacy positioning + enable JoinMiter + disable AALineEnds. Must be all bits set.
|
||||
|
||||
// Other Options ------------------------------ // Prim/Scope?
|
||||
ImDrawFlags_TextNoPixelSnap = 1 << 20, // OK OK(0) // Disable automatically snapping AddText() calls to pixel boundaries.
|
||||
ImDrawFlags_UseTexForRoundCorners = 1 << 21, // -- OK(1) // Enable using textures instead of strokes to draw rounded corners/circles where possible (faster). Used by default unless 'ImFontAtlasFlags_NoBakedRoundCorners' is enabled in the font atlas.
|
||||
ImDrawFlags_UseVtxOffset = 1 << 22, // -- OK(1) // Can emit 'VtxOffset > 0' to allow large meshes with 16-bit ImDrawIdx. Used by default when 'ImGuiBackendFlags_RendererHasVtxOffset' is enabled by the backend.
|
||||
ImDrawFlags_AllowTexForRoundCorners_= 1 << 23, // -- OK(1) // [Internal]
|
||||
|
||||
// [Internal]
|
||||
ImDrawFlags_RoundMask_ = ImDrawFlags_RoundAll | ImDrawFlags_RoundNone, // [Internal]
|
||||
ImDrawFlags_AllowInPushScope_ = ImDrawFlags_AAFill | ImDrawFlags_AALines | ImDrawFlags_AALineEnds | ImDrawFlags_StrokeLegacy | ImDrawFlags_TextNoPixelSnap | ImDrawFlags_UseTexForRoundCorners | ImDrawFlags_UseVtxOffset | ImDrawFlags_RoundMask_, // [Internal] Values allowed in PushDrawFlag() scope.
|
||||
ImDrawFlags_AllowInFrameScope_ = ImDrawFlags_AllowInPushScope_ | ImDrawFlags_AllowTexForRoundCorners_,
|
||||
ImDrawFlags_StrokeMask_ = 0x07 << 17, // [Internal]
|
||||
ImDrawFlags_InvalidMask_ = ~0x7FFFFFF0, // [Internal] == 0x8000000F. Reserved to detect misuses.
|
||||
|
||||
// Obsolete names
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
// RENAMED in 1.93.0 (Oct 2026): ImDrawFlags_RoundCornersXXXX -> ImDrawFlags_RoundXXXX.
|
||||
ImDrawFlags_RoundCornersTopLeft = ImDrawFlags_RoundTopLeft,
|
||||
ImDrawFlags_RoundCornersTopRight = ImDrawFlags_RoundTopRight,
|
||||
ImDrawFlags_RoundCornersBottomLeft = ImDrawFlags_RoundBottomLeft,
|
||||
ImDrawFlags_RoundCornersBottomRight = ImDrawFlags_RoundBottomRight,
|
||||
ImDrawFlags_RoundCornersNone = ImDrawFlags_RoundNone,
|
||||
ImDrawFlags_RoundCornersAll = ImDrawFlags_RoundAll,
|
||||
ImDrawFlags_RoundCornersTop = ImDrawFlags_RoundTop,
|
||||
ImDrawFlags_RoundCornersBottom = ImDrawFlags_RoundBottom,
|
||||
ImDrawFlags_RoundCornersLeft = ImDrawFlags_RoundLeft,
|
||||
ImDrawFlags_RoundCornersRight = ImDrawFlags_RoundRight,
|
||||
#endif
|
||||
};
|
||||
|
||||
// Draw command list
|
||||
@ -3485,7 +3541,7 @@ struct ImDrawList
|
||||
ImVector<ImDrawCmd> CmdBuffer; // Draw commands. Typically 1 command = 1 GPU draw call, unless the command is a callback.
|
||||
ImVector<ImDrawIdx> IdxBuffer; // Index buffer. Each command consume ImDrawCmd::ElemCount of those
|
||||
ImVector<ImDrawVert> VtxBuffer; // Vertex buffer.
|
||||
ImDrawListFlags Flags; // Flags, you may poke into these to adjust anti-aliasing settings per-primitive.
|
||||
ImDrawFlags Flags; // Current flags for drawing primitives. Alter with PushDrawFlag()/PopDrawFlags() to adjust defaults to a given scope.
|
||||
|
||||
// [Internal, used while building lists]
|
||||
unsigned int _VtxCurrentIdx; // [Internal] generally == VtxBuffer.Size unless we are past 64K vertices, in which case this gets reset to 0.
|
||||
@ -3498,8 +3554,10 @@ struct ImDrawList
|
||||
ImVector<ImVec4> _ClipRectStack; // [Internal]
|
||||
ImVector<ImTextureRef> _TextureStack; // [Internal]
|
||||
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.
|
||||
ImSmallStack_<ImDrawFlags,3> _DrawFlagsStack;// [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 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().
|
||||
@ -3512,6 +3570,8 @@ struct ImDrawList
|
||||
IMGUI_API void PopClipRect();
|
||||
IMGUI_API void PushTexture(ImTextureRef tex_ref);
|
||||
IMGUI_API void PopTexture();
|
||||
IMGUI_API void PushDrawFlag(ImDrawFlags flags, bool enabled); // [BETA] Please notify me if you are using this.
|
||||
IMGUI_API void PopDrawFlag();
|
||||
inline ImVec2 GetClipRectMin() const { const ImVec4& cr = _ClipRectStack.back(); return ImVec2(cr.x, cr.y); }
|
||||
inline ImVec2 GetClipRectMax() const { const ImVec4& cr = _ClipRectStack.back(); return ImVec2(cr.z, cr.w); }
|
||||
|
||||
@ -3522,32 +3582,32 @@ struct ImDrawList
|
||||
// In older versions (until Dear ImGui 1.77) the AddCircle functions defaulted to num_segments == 12.
|
||||
// In future versions we will use textures to provide cheaper and higher-quality circles.
|
||||
// Use AddNgon() and AddNgonFilled() functions if you need to guarantee a specific number of sides.
|
||||
IMGUI_API void AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness = 1.0f);
|
||||
IMGUI_API void AddLineH(float min_x, float max_x, float y, ImU32 col, float thickness = 1.0f);
|
||||
IMGUI_API void AddLineV(float x, float min_y, float max_y, ImU32 col, float thickness = 1.0f);
|
||||
IMGUI_API void AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness = 1.0f, ImDrawFlags flags = 0);
|
||||
IMGUI_API void AddLineH(float min_x, float max_x, float y, ImU32 col, float thickness = 1.0f, ImDrawFlags flags = 0);
|
||||
IMGUI_API void AddLineV(float x, float min_y, float max_y, ImU32 col, float thickness = 1.0f, ImDrawFlags flags = 0);
|
||||
IMGUI_API void AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding = 0.0f, float thickness = 1.0f, ImDrawFlags flags = 0); // a: upper-left, b: lower-right (== upper-left + size)
|
||||
IMGUI_API void AddRectFilled(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding = 0.0f, ImDrawFlags flags = 0); // a: upper-left, b: lower-right (== upper-left + size)
|
||||
IMGUI_API void AddRectFilledMultiColor(const ImVec2& p_min, const ImVec2& p_max, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left);
|
||||
IMGUI_API void AddQuad(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness = 1.0f);
|
||||
IMGUI_API void AddQuad(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness = 1.0f, ImDrawFlags flags = 0);
|
||||
IMGUI_API void AddQuadFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col);
|
||||
IMGUI_API void AddTriangle(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness = 1.0f);
|
||||
IMGUI_API void AddTriangle(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness = 1.0f, ImDrawFlags flags = 0);
|
||||
IMGUI_API void AddTriangleFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col);
|
||||
IMGUI_API void AddCircle(const ImVec2& center, float radius, ImU32 col, int num_segments = 0, float thickness = 1.0f);
|
||||
IMGUI_API void AddCircle(const ImVec2& center, float radius, ImU32 col, int num_segments = 0, float thickness = 1.0f, ImDrawFlags flags = 0);
|
||||
IMGUI_API void AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments = 0);
|
||||
IMGUI_API void AddNgon(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness = 1.0f);
|
||||
IMGUI_API void AddNgon(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness = 1.0f, ImDrawFlags flags = 0);
|
||||
IMGUI_API void AddNgonFilled(const ImVec2& center, float radius, ImU32 col, int num_segments);
|
||||
IMGUI_API void AddEllipse(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot = 0.0f, int num_segments = 0, float thickness = 1.0f);
|
||||
IMGUI_API void AddEllipse(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot = 0.0f, int num_segments = 0, float thickness = 1.0f, ImDrawFlags flags = 0);
|
||||
IMGUI_API void AddEllipseFilled(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot = 0.0f, int num_segments = 0);
|
||||
IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL);
|
||||
IMGUI_API void AddText(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 ImVec4* cpu_fine_clip_rect = NULL);
|
||||
IMGUI_API void AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0); // Cubic Bezier (4 control points)
|
||||
IMGUI_API void AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness, int num_segments = 0); // Quadratic Bezier (3 control points)
|
||||
IMGUI_API void AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0, ImDrawFlags flags = 0); // Cubic Bezier (4 control points)
|
||||
IMGUI_API void AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness, int num_segments = 0, ImDrawFlags flags = 0); // Quadratic Bezier (3 control points)
|
||||
|
||||
// General polygon
|
||||
// - Only simple polygons are supported by filling functions (no self-intersections, no holes).
|
||||
// - Concave polygon fill is more expensive than convex one: it has O(N^2) complexity. Provided as a convenience for the user but not used by the main library.
|
||||
IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, float thickness, ImDrawFlags flags = 0);
|
||||
IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col);
|
||||
inline void AddPolyline(const ImVec2* points, int num_points, ImU32 col, float thickness, ImDrawFlags flags = 0) { _AddPolyline(points, num_points, col, thickness, flags, FLT_MAX); }
|
||||
IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags = 0);
|
||||
IMGUI_API void AddConcavePolyFilled(const ImVec2* points, int num_points, ImU32 col);
|
||||
|
||||
// Image primitives
|
||||
@ -3564,9 +3624,9 @@ struct ImDrawList
|
||||
inline void PathClear() { _Path.Size = 0; }
|
||||
inline void PathLineTo(const ImVec2& pos) { _Path.push_back(pos); }
|
||||
inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || memcmp(&_Path.Data[_Path.Size - 1], &pos, 8) != 0) _Path.push_back(pos); }
|
||||
inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col); _Path.Size = 0; }
|
||||
inline void PathFillConvex(ImU32 col, ImDrawFlags flags = 0) { AddConvexPolyFilled(_Path.Data, _Path.Size, col, flags); _Path.Size = 0; }
|
||||
inline void PathFillConcave(ImU32 col) { AddConcavePolyFilled(_Path.Data, _Path.Size, col); _Path.Size = 0; }
|
||||
inline void PathStroke(ImU32 col, float thickness = 1.0f, ImDrawFlags flags = 0) { AddPolyline(_Path.Data, _Path.Size, col, thickness, flags); _Path.Size = 0; }
|
||||
inline void PathStroke(ImU32 col, float thickness = 1.0f, ImDrawFlags flags = 0) { _AddPolyline(_Path.Data, _Path.Size, col, thickness, flags, FLT_MAX); _Path.Size = 0; }
|
||||
IMGUI_API void PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments = 0);
|
||||
IMGUI_API void PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle
|
||||
IMGUI_API void PathEllipticalArcTo(const ImVec2& center, const ImVec2& radius, float rot, float a_min, float a_max, int num_segments = 0); // Ellipse
|
||||
@ -3644,6 +3704,13 @@ struct ImDrawList
|
||||
IMGUI_API int _CalcCircleAutoSegmentCount(float radius) const;
|
||||
IMGUI_API void _PathArcToFastEx(const ImVec2& center, float radius, int a_min_sample, int a_max_sample, int a_step);
|
||||
IMGUI_API void _PathArcToN(const ImVec2& center, float radius, float a_min, float a_max, int num_segments);
|
||||
IMGUI_API void _AddRectFilledBaked(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float r, const ImVec4& tex_uvs, ImDrawFlags flags);
|
||||
IMGUI_API void _AddRectBaked(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float r, float t, const ImVec4& tex_uvs, ImDrawFlags flags);
|
||||
IMGUI_API void _AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness, ImDrawFlags flags);
|
||||
IMGUI_API void _AddRectTinyRounding(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, float thickness, ImDrawFlags flags);
|
||||
IMGUI_API void _SelectLineTexture(float screen_thickness, ImVec2* out_uv0, ImVec2* out_uv1, float* out_fringe, ImDrawFlags flags);
|
||||
IMGUI_API float _CalculateCenterBiasedOffset(float thickness);
|
||||
IMGUI_API void _AddPolyline(const ImVec2* points, int num_points, ImU32 col, float thickness, ImDrawFlags flags, float max_inner_offset);
|
||||
};
|
||||
|
||||
// All draw data to render a Dear ImGui frame
|
||||
@ -3860,7 +3927,8 @@ enum ImFontAtlasFlags_
|
||||
ImFontAtlasFlags_None = 0,
|
||||
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_NoBakedLines = 1 << 2, // Don't build anti-aliased line textures into the atlas (save a little texture memory). SINCE 1.93.0 THIS PREVENTS ANTI-ALIASED LINES FROM WORKING AND WILL DISABLE THEM.
|
||||
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:
|
||||
@ -3977,7 +4045,7 @@ struct ImFontAtlas
|
||||
// Input
|
||||
ImFontAtlasFlags Flags; // Build flags (see ImFontAtlasFlags_)
|
||||
ImTextureFormat TexDesiredFormat; // Desired texture format (default to ImTextureFormat_RGBA32 but may be changed to ImTextureFormat_Alpha8).
|
||||
int TexGlyphPadding; // FIXME: Should be called "TexPackPadding". Padding between glyphs within texture in pixels. Defaults to 1. If your rendering method doesn't rely on bilinear filtering you may set this to 0 (will also need to set AntiAliasedLinesUseTex = false).
|
||||
int TexGlyphPadding; // FIXME: Should be called "TexPackPadding". Padding between glyphs within texture in pixels. Defaults to 1. If your rendering method never relies on bilinear filtering you may set this to 0.
|
||||
int TexMinWidth; // Minimum desired texture width. Must be a power of two. Default to 512.
|
||||
int TexMinHeight; // Minimum desired texture height. Must be a power of two. Default to 128.
|
||||
int TexMaxWidth; // Maximum desired texture width. Must be a power of two. Default to 8192.
|
||||
@ -4004,7 +4072,6 @@ struct ImFontAtlas
|
||||
ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel. May change as new texture gets created.
|
||||
ImVector<ImFont*> Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font.
|
||||
ImVector<ImFontConfig> Sources; // Source/configuration data
|
||||
ImVec4 TexUvLines[IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1]; // UVs for baked anti-aliased lines
|
||||
int TexNextUniqueID; // Next value to be stored in TexData->UniqueID
|
||||
int FontNextUniqueID; // Next value to be stored in ImFont->FontID
|
||||
ImVector<ImDrawListSharedData*> DrawListSharedDatas; // List of users for this atlas. Typically one per Dear ImGui context.
|
||||
@ -4523,6 +4590,18 @@ namespace ImGui
|
||||
|
||||
#define ImDrawCallback_ResetRenderState (ImDrawCallback)(-8) // OBSOLETED in 1.92.8: Use ImGui::GetPlatformIO().DrawCallback_ResetRenderState
|
||||
|
||||
// -- RENAMED in 1.93.0: Merged ImDrawListFlags into ImDrawFlags.
|
||||
typedef ImDrawFlags ImDrawListFlags;
|
||||
enum ImDrawListFlags_
|
||||
{
|
||||
ImDrawListFlags_None = ImDrawFlags_None,
|
||||
ImDrawListFlags_AntiAliasedFill = ImDrawFlags_AAFill,
|
||||
ImDrawListFlags_AntiAliasedLines = ImDrawFlags_AALines,
|
||||
ImDrawListFlags_AntiAliasedLinesUseTex = ImDrawFlags_AALines, // No effect, anti-aliased rendering always uses textures from 1.93+
|
||||
ImDrawListFlags_AllowVtxOffset = ImDrawFlags_UseVtxOffset,
|
||||
ImDrawListFlags_TextNoPixelSnap = ImDrawFlags_TextNoPixelSnap,
|
||||
};
|
||||
|
||||
//-- OBSOLETED in 1.92.0: ImFontAtlasCustomRect becomes ImTextureRect
|
||||
// - ImFontAtlasCustomRect::X,Y --> ImTextureRect::x,y
|
||||
// - ImFontAtlasCustomRect::Width,Height --> ImTextureRect::w,h
|
||||
@ -4546,16 +4625,16 @@ typedef ImFontAtlasRect ImFontAtlasCustomRect;
|
||||
//typedef ImDrawFlags ImDrawCornerFlags;
|
||||
//enum ImDrawCornerFlags_
|
||||
//{
|
||||
// ImDrawCornerFlags_None = ImDrawFlags_RoundCornersNone, // Was == 0 prior to 1.82, this is now == ImDrawFlags_RoundCornersNone which is != 0 and not implicit
|
||||
// ImDrawCornerFlags_TopLeft = ImDrawFlags_RoundCornersTopLeft, // Was == 0x01 (1 << 0) prior to 1.82. Order matches ImDrawFlags_NoRoundCorner* flag (we exploit this internally).
|
||||
// ImDrawCornerFlags_TopRight = ImDrawFlags_RoundCornersTopRight, // Was == 0x02 (1 << 1) prior to 1.82.
|
||||
// ImDrawCornerFlags_BotLeft = ImDrawFlags_RoundCornersBottomLeft, // Was == 0x04 (1 << 2) prior to 1.82.
|
||||
// ImDrawCornerFlags_BotRight = ImDrawFlags_RoundCornersBottomRight, // Was == 0x08 (1 << 3) prior to 1.82.
|
||||
// ImDrawCornerFlags_All = ImDrawFlags_RoundCornersAll, // Was == 0x0F prior to 1.82
|
||||
// ImDrawCornerFlags_Top = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_TopRight,
|
||||
// ImDrawCornerFlags_Bot = ImDrawCornerFlags_BotLeft | ImDrawCornerFlags_BotRight,
|
||||
// ImDrawCornerFlags_Left = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotLeft,
|
||||
// ImDrawCornerFlags_Right = ImDrawCornerFlags_TopRight | ImDrawCornerFlags_BotRight,
|
||||
// ImDrawCornerFlags_None = ImDrawFlags_RoundNone, // Was == 0 prior to 1.82, this is now == ImDrawFlags_RoundNone which is != 0 and not implicit
|
||||
// ImDrawCornerFlags_TopLeft = ImDrawFlags_RoundTopLeft, // Was == 0x01 (1 << 0) prior to 1.82. Order matches ImDrawFlags_NoRoundCorner* flag (we exploit this internally).
|
||||
// ImDrawCornerFlags_TopRight = ImDrawFlags_RoundTopRight, // Was == 0x02 (1 << 1) prior to 1.82.
|
||||
// ImDrawCornerFlags_BotLeft = ImDrawFlags_RoundBottomLeft, // Was == 0x04 (1 << 2) prior to 1.82.
|
||||
// ImDrawCornerFlags_BotRight = ImDrawFlags_RoundBottomRight, // Was == 0x08 (1 << 3) prior to 1.82.
|
||||
// ImDrawCornerFlags_All = ImDrawFlags_RoundAll, // Was == 0x0F prior to 1.82
|
||||
// ImDrawCornerFlags_Top = ImDrawFlags_RoundTopLeft | ImDrawFlags_RoundTopRight,
|
||||
// ImDrawCornerFlags_Bot = ImDrawFlags_RoundBottomLeft | ImDrawFlags_RoundBottomRight,
|
||||
// ImDrawCornerFlags_Left = ImDrawFlags_RoundTopLeft | ImDrawFlags_RoundBottomLeft,
|
||||
// ImDrawCornerFlags_Right = ImDrawFlags_RoundTopRight | ImDrawFlags_RoundBottomRight,
|
||||
//};
|
||||
|
||||
// RENAMED and MERGED both ImGuiKey_ModXXX and ImGuiModFlags_XXX into ImGuiMod_XXX (from September 2022)
|
||||
|
||||
340
imgui_demo.cpp
340
imgui_demo.cpp
@ -640,6 +640,8 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
ImGui::SameLine(); HelpMarker("Some calls to Begin()/BeginChild() will return false.\n\nWill cycle through window depths then repeat. Windows should be flickering while running.");
|
||||
ImGui::Checkbox("io.ConfigDebugIgnoreFocusLoss", &io.ConfigDebugIgnoreFocusLoss);
|
||||
ImGui::SameLine(); HelpMarker("Option to deactivate io.AddFocusEvent(false) handling. May facilitate interactions with a debugger when focus loss leads to clearing inputs data.");
|
||||
ImGui::Checkbox("io.ConfigDebugDrawListDefaultsToStrokeLegacy", &io.ConfigDebugDrawListDefaultsToStrokeLegacy);
|
||||
ImGui::SameLine(); HelpMarker("Option to default all ImDrawList to ImDrawFlags_StrokeLegacy mode, mimicking pre-1.93.0 rendering.");
|
||||
ImGui::Checkbox("io.ConfigDebugIniSettings", &io.ConfigDebugIniSettings);
|
||||
ImGui::SameLine(); HelpMarker("Option to save .ini data with extra comments (particularly helpful for Docking, but makes saving slower).");
|
||||
|
||||
@ -9025,12 +9027,21 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
Checkbox("Anti-aliased lines", &style.AntiAliasedLines);
|
||||
SameLine();
|
||||
HelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well.");
|
||||
BeginDisabled(style.AntiAliasedLines == false);
|
||||
Checkbox("Anti-aliased line ends", &style.AntiAliasedLineEnds);
|
||||
EndDisabled();
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
BeginDisabled();
|
||||
Checkbox("Anti-aliased lines use texture", &style.AntiAliasedLinesUseTex);
|
||||
SameLine();
|
||||
HelpMarker("Faster lines using texture data. Require backend to render with bilinear filtering (not point/nearest filtering).");
|
||||
EndDisabled();
|
||||
#endif
|
||||
|
||||
Checkbox("Anti-aliased fill", &style.AntiAliasedFill);
|
||||
Checkbox("Debug: DrawList Defaults to _StrokeLegacy", &ImGui::GetIO().ConfigDebugDrawListDefaultsToStrokeLegacy);
|
||||
|
||||
PushItemWidth(GetFontSize() * 8);
|
||||
DragFloat("Curve Tessellation Max Error", &style.CurveTessellationMaxError, 0.02f, 0.10f, 10.0f, "%.2f");
|
||||
if (style.CurveTessellationMaxError < 0.10f)
|
||||
@ -10448,13 +10459,10 @@ static void ShowExampleAppWindowTitles(bool*)
|
||||
// [SECTION] Example App: Custom Rendering using ImDrawList API / ShowExampleAppCustomRendering()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Add a |_| looking shape
|
||||
static void PathConcaveShape(ImDrawList* draw_list, float x, float y, float sz)
|
||||
{
|
||||
const ImVec2 pos_norms[] = { { 0.0f, 0.0f }, { 0.3f, 0.0f }, { 0.3f, 0.7f }, { 0.7f, 0.7f }, { 0.7f, 0.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f }, { 0.0f, 1.0f } };
|
||||
for (const ImVec2& p : pos_norms)
|
||||
draw_list->PathLineTo(ImVec2(x + 0.5f + (int)(sz * p.x), y + 0.5f + (int)(sz * p.y)));
|
||||
}
|
||||
// See our Wiki guides:
|
||||
// - 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
|
||||
|
||||
// Demonstrate using the low-level ImDrawList to draw custom shapes.
|
||||
static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
@ -10486,118 +10494,250 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
ImGui::Text("Gradients");
|
||||
ImVec2 gradient_size = ImVec2(ImGui::CalcItemWidth(), ImGui::GetFrameHeight());
|
||||
{
|
||||
ImVec2 p0 = ImGui::GetCursorScreenPos();
|
||||
ImVec2 p1 = ImVec2(p0.x + gradient_size.x, p0.y + gradient_size.y);
|
||||
ImGui::InvisibleButton("##gradient1", gradient_size);
|
||||
ImU32 col_a = ImGui::GetColorU32(IM_COL32(0, 0, 0, 255));
|
||||
ImU32 col_b = ImGui::GetColorU32(IM_COL32(255, 255, 255, 255));
|
||||
draw_list->AddRectFilledMultiColor(p0, p1, col_a, col_b, col_b, col_a);
|
||||
ImGui::InvisibleButton("##gradient1", gradient_size);
|
||||
draw_list->AddRectFilledMultiColor(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), col_a, col_b, col_b, col_a);
|
||||
}
|
||||
{
|
||||
ImVec2 p0 = ImGui::GetCursorScreenPos();
|
||||
ImVec2 p1 = ImVec2(p0.x + gradient_size.x, p0.y + gradient_size.y);
|
||||
ImGui::InvisibleButton("##gradient2", gradient_size);
|
||||
ImU32 col_a = ImGui::GetColorU32(IM_COL32(0, 255, 0, 255));
|
||||
ImU32 col_b = ImGui::GetColorU32(IM_COL32(255, 0, 0, 255));
|
||||
draw_list->AddRectFilledMultiColor(p0, p1, col_a, col_b, col_b, col_a);
|
||||
ImGui::InvisibleButton("##gradient2", gradient_size);
|
||||
draw_list->AddRectFilledMultiColor(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), col_a, col_b, col_b, col_a);
|
||||
}
|
||||
|
||||
// Draw a bunch of primitives
|
||||
ImGui::Text("All primitives");
|
||||
static float sz = 42.0f;
|
||||
static float thickness = 3.0f;
|
||||
static int ngon_sides = 6;
|
||||
static float base_rounding = 8.0f;
|
||||
static float base_thickness = 3.0f;
|
||||
static bool animate_rounding = false;
|
||||
static bool animate_thickness = false;
|
||||
static int ngon_segments = 6;
|
||||
static bool circle_segments_override = false;
|
||||
static int circle_segments_override_v = 12;
|
||||
static bool curve_segments_override = false;
|
||||
static int curve_segments_override_v = 8;
|
||||
static ImVec4 colf = ImVec4(1.0f, 1.0f, 0.4f, 1.0f);
|
||||
ImGui::DragFloat("Size", &sz, 0.2f, 2.0f, 100.0f, "%.0f");
|
||||
ImGui::DragFloat("Thickness", &thickness, 0.05f, 1.0f, 8.0f, "%.02f");
|
||||
ImGui::SliderInt("N-gon sides", &ngon_sides, 3, 12);
|
||||
ImGui::Checkbox("##circlesegmentoverride", &circle_segments_override);
|
||||
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
||||
circle_segments_override |= ImGui::SliderInt("Circle segments override", &circle_segments_override_v, 3, 40);
|
||||
ImGui::Checkbox("##curvessegmentoverride", &curve_segments_override);
|
||||
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
||||
curve_segments_override |= ImGui::SliderInt("Curves segments override", &curve_segments_override_v, 3, 40);
|
||||
ImGui::ColorEdit4("Color", &colf.x);
|
||||
static ImVec4 colf_stroke = ImVec4(1.000f, 0.384f, 0.169f, 1.000f);
|
||||
static ImVec4 colf_fill = ImVec4(0.416f, 0.378f, 0.420f, 1.000f);
|
||||
|
||||
const ImVec2 p = ImGui::GetCursorScreenPos();
|
||||
const ImU32 col = ImColor(colf);
|
||||
const float spacing = 10.0f;
|
||||
const ImDrawFlags corners_tl_br = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersBottomRight;
|
||||
const float rounding = sz / 5.0f;
|
||||
ImGui::DragFloat("Size", &sz, 0.2f, 0.2f, 100.0f, "%.0f");
|
||||
|
||||
const float rounding_anim_period = 3.0f;
|
||||
const float rounding_wave = 1.0f - fabsf(fmodf((float)ImGui::GetTime(), rounding_anim_period) * (2.0f / rounding_anim_period) - 1.0f);
|
||||
const float rounding = animate_rounding ? (float)(int)(rounding_wave * base_rounding * 10.0f) / 10.0f : base_rounding; // Sub-integer rounding works but has discontinuities in small values, so best disable we
|
||||
ImGui::DragFloat("Rounding", &base_rounding, 0.02f, 0.0f, 32.0f, "%.1f"); ImGui::SameLine();
|
||||
ImGui::Checkbox("Animate##rounding", &animate_rounding); ImGui::SameLine();
|
||||
ImGui::Text("%.2f", rounding);
|
||||
|
||||
const float thickness_anim_period = 5.0f;
|
||||
const float thickness_wave = 1.0f - fabsf(fmodf((float)ImGui::GetTime(), thickness_anim_period) * (2.0f / thickness_anim_period) - 1.0f);
|
||||
const float thickness = animate_thickness ? thickness_wave * base_thickness : base_thickness;
|
||||
ImGui::DragFloat("Thickness", &base_thickness, 0.02f, 0.0f, 32.0f, "%.02f"); ImGui::SameLine();
|
||||
ImGui::Checkbox("Animate##thickness", &animate_thickness); ImGui::SameLine();
|
||||
ImGui::Text("%.2f", thickness);
|
||||
|
||||
ImGui::SliderInt("N-gon sides", &ngon_segments, 3, 12);
|
||||
ImGui::Checkbox("##CircleSegmentOverride", &circle_segments_override);
|
||||
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
||||
circle_segments_override |= ImGui::SliderInt("Circle segments override", &circle_segments_override_v, 3, 30);
|
||||
ImGui::Checkbox("##CurvesSegmentOverride", &curve_segments_override);
|
||||
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
||||
curve_segments_override |= ImGui::SliderInt("Curves segments override", &curve_segments_override_v, 3, 30);
|
||||
ImGui::ColorEdit4("Stroke Color", &colf_stroke.x);
|
||||
ImGui::ColorEdit4("Fill Color", &colf_fill.x);
|
||||
|
||||
static ImDrawFlags prim_stroke_flags = ImDrawFlags_None;
|
||||
static ImDrawFlags prim_other_flags = ImDrawFlags_AALineEnds;
|
||||
ImGui::SeparatorText("Per primitive flags (AddXXX functions)");
|
||||
ImGui::RadioButton("Default", &prim_stroke_flags, ImDrawFlags_None); ImGui::SameLine();
|
||||
ImGui::RadioButton("Inside", &prim_stroke_flags, ImDrawFlags_StrokeInside); ImGui::SameLine();
|
||||
ImGui::RadioButton("Center", &prim_stroke_flags, ImDrawFlags_StrokeCenter); ImGui::SameLine();
|
||||
ImGui::RadioButton("CenterBiased", &prim_stroke_flags, ImDrawFlags_StrokeCenterBiased); ImGui::SameLine();
|
||||
ImGui::RadioButton("Outside", &prim_stroke_flags, ImDrawFlags_StrokeOutside); ImGui::SameLine();
|
||||
ImGui::RadioButton("Legacy", &prim_stroke_flags, ImDrawFlags_StrokeLegacy);
|
||||
ImGui::CheckboxFlags("AAFill", &prim_other_flags, ImDrawFlags_AAFill); ImGui::SameLine(); // Note: Only for functions taking flags.
|
||||
ImGui::CheckboxFlags("AALines", &prim_other_flags, ImDrawFlags_AALines); ImGui::SameLine(); // Note: Only for functions taking flags.
|
||||
ImGui::CheckboxFlags("AALineEnds", &prim_other_flags, ImDrawFlags_AALineEnds); ImGui::SameLine();
|
||||
ImGui::CheckboxFlags("JoinMiter", &prim_other_flags, ImDrawFlags_JoinMiter); ImGui::SameLine();
|
||||
ImGui::CheckboxFlags("CapSquare", &prim_other_flags, ImDrawFlags_CapSquare);
|
||||
//ImGui::CheckboxFlags("UseTexForRoundCorners", &prim_other_flags, ImDrawFlags_UseTexForRoundCorners);
|
||||
|
||||
static ImDrawFlags scope_flags = draw_list->Flags & ImDrawFlags_AllowInPushScope_; // First init copy current state.
|
||||
ImGui::SeparatorText("Current ImDrawList flags (e.g. PushDrawFlag function)");
|
||||
ImGui::PushID("ScopeFlags");
|
||||
ImGui::CheckboxFlags("AAFill", &scope_flags, ImDrawFlags_AAFill); ImGui::SameLine();
|
||||
ImGui::CheckboxFlags("AALines", &scope_flags, ImDrawFlags_AALines); ImGui::SameLine();
|
||||
ImGui::CheckboxFlags("AALineEnds", &scope_flags, ImDrawFlags_AALineEnds); ImGui::SameLine();
|
||||
ImGui::CheckboxFlags("StrokeLegacy", &scope_flags, ImDrawFlags_StrokeLegacy);
|
||||
//ImGui::CheckboxFlags("UseTexForRoundCorners", &scope_flags, ImDrawFlags_UseTexForRoundCorners);
|
||||
ImGui::PopID();
|
||||
ImGui::Spacing();
|
||||
|
||||
draw_list->PushDrawFlag(ImDrawFlags_AllowInPushScope_, false); // Reset all existing (very unusual: done for this demo)
|
||||
draw_list->PushDrawFlag(scope_flags, true);
|
||||
const ImDrawFlags flags = prim_stroke_flags | prim_other_flags;
|
||||
|
||||
const ImVec2 start_pos = ImGui::GetCursorScreenPos();
|
||||
const float pi = 3.141592f;
|
||||
const float step = sz + 10.0f;
|
||||
const ImDrawFlags corners_tl_br = ImDrawFlags_RoundTopLeft | ImDrawFlags_RoundBottomRight;
|
||||
const float half_sz = sz * 0.5f;
|
||||
const int circle_segments = circle_segments_override ? circle_segments_override_v : 0;
|
||||
const int curve_segments = curve_segments_override ? curve_segments_override_v : 0;
|
||||
const ImVec2 cp3[3] = { ImVec2(0.0f, sz * 0.6f), ImVec2(sz * 0.5f, -sz * 0.4f), ImVec2(sz, sz) }; // Control points for curves
|
||||
const ImVec2 cp4[4] = { ImVec2(0.0f, 0.0f), ImVec2(sz * 1.3f, sz * 0.3f), ImVec2(sz - sz * 1.3f, sz - sz * 0.3f), ImVec2(sz, sz) };
|
||||
|
||||
float x = p.x + 4.0f;
|
||||
float y = p.y + 4.0f;
|
||||
for (int n = 0; n < 2; n++)
|
||||
const ImVec2 cp3[3] = { { 0.0f, sz * 0.6f }, { sz * 0.5f, -sz * 0.4f }, { sz, sz } }; // Control points for curves
|
||||
const ImVec2 cp4[4] = { { 0.0f, 0.0f }, { sz * 1.3f, sz * 0.3f }, { sz - sz * 1.3f, sz - sz * 0.3f }, { sz, sz } };
|
||||
const ImVec2 concave_shape[] = { { 0.0f, 0.0f }, { 0.3f, 0.0f }, { 0.3f, 0.7f }, { 0.7f, 0.7f }, { 0.7f, 0.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f }, { 0.0f, 1.0f } }; // |_| looking shape. Normalized.
|
||||
const ImVec2 zigzag_shape[] = { { 0.0f, 0.0f }, { 0.9f, 0.0f }, { 1.0f, 0.1f }, { 1.0f, 0.9f }, { 0.9f, 1.0f }, { 0.3f, 1.0f }, { 0.3f, 0.4f }, { 0.9f, 0.4f } };
|
||||
ImVec2 rotating_square[4];
|
||||
for (int side = 0; side < 4; side++)
|
||||
{
|
||||
// First line uses a thickness of 1.0f, second line uses the configurable thickness
|
||||
float th = (n == 0) ? 1.0f : thickness;
|
||||
draw_list->AddNgon(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, ngon_sides, th); x += sz + spacing; // N-gon
|
||||
draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments, th); x += sz + spacing; // Circle
|
||||
draw_list->AddEllipse(ImVec2(x + sz*0.5f, y + sz*0.5f), ImVec2(sz*0.5f, sz*0.3f), col, -0.3f, circle_segments, th); x += sz + spacing; // Ellipse
|
||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 0.0f, th); x += sz + spacing; // Square
|
||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, th); x += sz + spacing; // Square with all rounded corners
|
||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, th, corners_tl_br); x += sz + spacing; // Square with two rounded corners
|
||||
draw_list->AddTriangle(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col, th);x += sz + spacing; // Triangle
|
||||
//draw_list->AddTriangle(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col, th);x+= sz*0.4f + spacing; // Thin triangle
|
||||
PathConcaveShape(draw_list, x, y, sz); draw_list->PathStroke(col, th, ImDrawFlags_Closed); x += sz + spacing; // Concave Shape
|
||||
//draw_list->AddPolyline(concave_shape, IM_COUNTOF(concave_shape), col, ImDrawFlags_Closed, th);
|
||||
draw_list->AddLineH(x, x + sz, y, col, th); x += sz + spacing; // Horizontal line (note: drawing a filled rectangle will be faster!)
|
||||
draw_list->AddLineV(x, y, y + sz, col, th); x += spacing; // Vertical line (note: drawing a filled rectangle will be faster!)
|
||||
draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y + sz), col, th); x += sz + spacing; // Diagonal line
|
||||
|
||||
// Path
|
||||
draw_list->PathArcTo(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, 3.141592f, 3.141592f * -0.5f);
|
||||
draw_list->PathStroke(col, th);
|
||||
x += sz + spacing;
|
||||
|
||||
// Quadratic Bezier Curve (3 control points)
|
||||
draw_list->AddBezierQuadratic(ImVec2(x + cp3[0].x, y + cp3[0].y), ImVec2(x + cp3[1].x, y + cp3[1].y), ImVec2(x + cp3[2].x, y + cp3[2].y), col, th, curve_segments);
|
||||
x += sz + spacing;
|
||||
|
||||
// Cubic Bezier Curve (4 control points)
|
||||
draw_list->AddBezierCubic(ImVec2(x + cp4[0].x, y + cp4[0].y), ImVec2(x + cp4[1].x, y + cp4[1].y), ImVec2(x + cp4[2].x, y + cp4[2].y), ImVec2(x + cp4[3].x, y + cp4[3].y), col, th, curve_segments);
|
||||
|
||||
x = p.x + 4;
|
||||
y += sz + spacing;
|
||||
float t = (float)ImGui::GetTime() * 0.1f + side * pi * 0.5f;
|
||||
rotating_square[side] = { (float)cosf(t) * half_sz, (float)sinf(t) * half_sz };
|
||||
}
|
||||
|
||||
// Filled shapes
|
||||
draw_list->AddNgonFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz * 0.5f, col, ngon_sides); x += sz + spacing; // N-gon
|
||||
draw_list->AddCircleFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz * 0.5f, col, circle_segments); x += sz + spacing; // Circle
|
||||
draw_list->AddEllipseFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), ImVec2(sz * 0.5f, sz * 0.3f), col, -0.3f, circle_segments); x += sz + spacing;// Ellipse
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col); x += sz + spacing; // Square
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f); x += sz + spacing; // Square with all rounded corners
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br); x += sz + spacing; // Square with two rounded corners
|
||||
draw_list->AddTriangleFilled(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col); x += sz + spacing; // Triangle
|
||||
//draw_list->AddTriangleFilled(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col); x += sz*0.4f + spacing; // Thin triangle
|
||||
PathConcaveShape(draw_list, x, y, sz); draw_list->PathFillConcave(col); x += sz + spacing; // Concave shape
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + thickness), col); x += sz + spacing; // Horizontal line (faster than AddLine, but only handle integer thickness)
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + thickness, y + sz), col); x += spacing * 2.0f;// Vertical line (faster than AddLine, but only handle integer thickness)
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + 1, y + 1), col); x += sz; // Pixel (faster than AddLine)
|
||||
float x = start_pos.x;
|
||||
float y = start_pos.y;
|
||||
for (int row = 0; row < 4; row++)
|
||||
{
|
||||
x = start_pos.x;
|
||||
bool draw_fill = (row == 2 || row == 3);
|
||||
bool draw_strokes = (row == 0 || row == 1 || row == 3);
|
||||
if (draw_fill)
|
||||
{
|
||||
// FILLED SHAPES
|
||||
const ImU32 col = ImColor(colf_fill);
|
||||
draw_list->AddNgonFilled({ x + half_sz, y + half_sz }, half_sz, col, ngon_segments); x += step; // N-gon
|
||||
draw_list->AddCircleFilled({ x + half_sz, y + half_sz }, half_sz, col, circle_segments); x += step; // Circle
|
||||
draw_list->AddEllipseFilled({ x + half_sz, y + half_sz }, { half_sz, sz * 0.3f }, col, -0.3f, circle_segments); x += step;// Ellipse
|
||||
draw_list->AddRectFilled({ x, y }, { x + sz, y + sz }, col, 0.0f, flags); x += step; // Square
|
||||
draw_list->AddRectFilled({ x, y }, { x + sz, y + sz }, col, rounding, flags); x += step; // Square with all rounded corners
|
||||
draw_list->AddRectFilled({ x, y }, { x + sz, y + sz }, col, rounding, flags | corners_tl_br); x += step; // Square with two rounded corners
|
||||
draw_list->AddTriangleFilled({ x + sz * 0.5f, y }, { x + sz, y + sz }, { x, y + sz }, col); x += step; // Triangle
|
||||
draw_list->AddTriangleFilled({ x + sz * 0.2f, y }, { x + sz * 0.4f, y + sz }, { x, y + sz }, col); x += step - (float)(int)(sz * 0.6f); // Thin triangle
|
||||
|
||||
// Path
|
||||
draw_list->PathArcTo(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz * 0.5f, 3.141592f * -0.5f, 3.141592f);
|
||||
draw_list->PathFillConvex(col);
|
||||
x += sz + spacing;
|
||||
// Concave shape: U
|
||||
for (const ImVec2& p : concave_shape)
|
||||
draw_list->PathLineTo({ x + (int)(sz * p.x), y + (int)(sz * p.y) });
|
||||
draw_list->PathFillConcave(col);
|
||||
x += step;
|
||||
|
||||
// Quadratic Bezier Curve (3 control points)
|
||||
draw_list->PathLineTo(ImVec2(x + cp3[0].x, y + cp3[0].y));
|
||||
draw_list->PathBezierQuadraticCurveTo(ImVec2(x + cp3[1].x, y + cp3[1].y), ImVec2(x + cp3[2].x, y + cp3[2].y), curve_segments);
|
||||
draw_list->PathFillConvex(col);
|
||||
x += sz + spacing;
|
||||
// Concave shape: Zig-Zag with sharp angles (see difference with/without JoinMiter)
|
||||
for (const ImVec2& p : zigzag_shape)
|
||||
draw_list->PathLineTo({ x + (int)(sz * p.x), y + (int)(sz * p.y) });
|
||||
draw_list->PathFillConcave(col);
|
||||
x += step;
|
||||
|
||||
draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x + sz, y + sz), IM_COL32(0, 0, 0, 255), IM_COL32(255, 0, 0, 255), IM_COL32(255, 255, 0, 255), IM_COL32(0, 255, 0, 255));
|
||||
x += sz + spacing;
|
||||
// Horizontal/Vertical lines
|
||||
// (here for consistency with the strokes section. AddRectFilled() is roughly close to AddLineH(), AddLineV()
|
||||
draw_list->AddRectFilled({ x, y }, { x + sz, y + thickness }, col); x += step;
|
||||
draw_list->AddRectFilled({ x, y }, { x + thickness, y + sz }, col); x += step - (float)(int)half_sz;
|
||||
if (!(draw_fill && draw_strokes)) //-V560
|
||||
for (int block_sz = 1, off = 0; block_sz < 16 && off + block_sz <= sz; off += block_sz + 1, block_sz++)
|
||||
draw_list->AddRectFilled({ x, y + off }, { x + block_sz, y + off + block_sz }, col);
|
||||
x += step - (float)(int)half_sz;
|
||||
|
||||
// Rotating square
|
||||
for (int n = 0; n < 4; n++)
|
||||
draw_list->PathLineTo({ x + half_sz + rotating_square[n].x, y + half_sz + rotating_square[n].y });
|
||||
draw_list->PathFillConvex(col, flags);
|
||||
x += step;
|
||||
|
||||
// Path
|
||||
draw_list->PathArcTo({ x + half_sz, y + half_sz }, half_sz, pi * -0.5f, pi * 1.1f);
|
||||
draw_list->PathFillConvex(col);
|
||||
x += step;
|
||||
|
||||
// Quadratic Bezier Curve (3 control points)
|
||||
draw_list->PathLineTo({ x + cp3[0].x, y + cp3[0].y });
|
||||
draw_list->PathBezierQuadraticCurveTo({ x + cp3[1].x, y + cp3[1].y }, { x + cp3[2].x, y + cp3[2].y }, curve_segments);
|
||||
draw_list->PathFillConvex(col);
|
||||
x += step;
|
||||
|
||||
if (!(draw_fill && draw_strokes)) //-V560
|
||||
{
|
||||
draw_list->AddRectFilledMultiColor({ x, y }, { x + sz, y + sz }, IM_COL32(0, 0, 0, 255), IM_COL32(255, 0, 0, 255), IM_COL32(255, 255, 0, 255), IM_COL32(0, 255, 0, 255));
|
||||
x += step;
|
||||
}
|
||||
}
|
||||
if (draw_fill && draw_strokes)
|
||||
x = start_pos.x;
|
||||
if (draw_strokes)
|
||||
{
|
||||
// STROKES
|
||||
// First row uses a thickness of 1.0f, second row uses the configurable thickness
|
||||
const ImU32 col = ImColor(colf_stroke);
|
||||
float th = (row == 0) ? 1.0f : thickness;
|
||||
draw_list->AddNgon({ x + half_sz, y + half_sz }, half_sz, col, ngon_segments, th, flags); x += step; // N-gon
|
||||
draw_list->AddCircle({ x + half_sz, y + half_sz }, half_sz, col, circle_segments, th, flags); x += step; // Circle
|
||||
draw_list->AddEllipse({ x + half_sz, y + half_sz }, { half_sz, sz * 0.3f }, col, -0.3f, circle_segments, th, flags); x += step; // Ellipse
|
||||
draw_list->AddRect({ x, y }, { x + sz, y + sz }, col, 0.0f, th, flags); x += step; // Square
|
||||
draw_list->AddRect({ x, y }, { x + sz, y + sz }, col, rounding, th, flags); x += step; // Square with all rounded corners
|
||||
draw_list->AddRect({ x, y }, { x + sz, y + sz }, col, rounding, th, flags | corners_tl_br); x += step; // Square with two rounded corners
|
||||
draw_list->AddTriangle({ x + sz * 0.5f, y }, { x + sz, y + sz }, { x, y + sz }, col, th, flags); x += step; // Triangle
|
||||
draw_list->AddTriangle({ x + sz * 0.2f, y }, { x + sz * 0.4f, y + sz }, { x, y + sz }, col, th, flags); x += step - (float)(int)(sz * 0.6f); // Thin triangle
|
||||
|
||||
// Concave shape: U
|
||||
for (const ImVec2& p : concave_shape)
|
||||
draw_list->PathLineTo({ x + (int)(sz * p.x), y + (int)(sz * p.y) });
|
||||
draw_list->PathStroke(col, th, flags | ImDrawFlags_Closed);
|
||||
x += step;
|
||||
|
||||
// Concave shape: Zig-Zag with sharp angles (see difference with/without JoinMiter)
|
||||
for (const ImVec2& p : zigzag_shape)
|
||||
draw_list->PathLineTo({ x + (int)(sz * p.x), y + (int)(sz * p.y) });
|
||||
draw_list->PathStroke(col, th, flags | ImDrawFlags_Closed);
|
||||
x += step;
|
||||
|
||||
// Horizontal/Vertical/Diagonal lines
|
||||
const float off = (float)(int)(sz * 0.4f);
|
||||
draw_list->AddLineH(x, x + sz, y, col, th, flags);
|
||||
draw_list->AddLine({ x, y + off }, { x + sz, y + off }, col, th, flags);
|
||||
x += step;
|
||||
draw_list->AddLineV(x, y, y + sz, col, th, flags);
|
||||
draw_list->AddLine({ x + off, y + sz }, { x + off, y }, col, th, flags);
|
||||
x += step - (float)(int)half_sz;
|
||||
if (!(draw_fill && draw_strokes)) //-V560
|
||||
{
|
||||
draw_list->AddLine({ x, y }, { x + half_sz, y + sz }, col, th, flags);
|
||||
draw_list->AddLine({ x, y + sz }, { x + half_sz, y }, col, th, flags);
|
||||
}
|
||||
x += step - (float)(int)half_sz;
|
||||
|
||||
// Rotating square
|
||||
for (int n = 0; n < 4; n++)
|
||||
draw_list->PathLineTo({ x + half_sz + rotating_square[n].x, y + half_sz + rotating_square[n].y });
|
||||
draw_list->PathStroke(col, th, flags | ImDrawFlags_Closed);
|
||||
//for (int n = 0; n < 4; n++) // ...made of individual line
|
||||
// draw_list->AddLine({ x + half_sz + rotating_square[n].x, y + half_sz + rotating_square[n].y }, { x + half_sz + rotating_square[(n + 1) & 3].x, y + half_sz + rotating_square[(n + 1) & 3].y }, col, th, flags);
|
||||
x += step;
|
||||
|
||||
// Path
|
||||
draw_list->PathArcTo({ x + half_sz, y + half_sz }, half_sz, pi * -0.5f, pi * 1.1f);
|
||||
draw_list->PathStroke(col, th, flags);
|
||||
x += step;
|
||||
|
||||
// Quadratic Bezier Curve (3 control points)
|
||||
draw_list->AddBezierQuadratic({ x + cp3[0].x, y + cp3[0].y }, { x + cp3[1].x, y + cp3[1].y }, { x + cp3[2].x, y + cp3[2].y }, col, th, curve_segments, flags);
|
||||
x += step;
|
||||
|
||||
// Cubic Bezier Curve (4 control points)
|
||||
if (!(draw_fill && draw_strokes)) //-V560
|
||||
{
|
||||
draw_list->AddBezierCubic({ x + cp4[0].x, y + cp4[0].y }, { x + cp4[1].x, y + cp4[1].y }, { x + cp4[2].x, y + cp4[2].y }, { x + cp4[3].x, y + cp4[3].y }, col, th, curve_segments, flags);
|
||||
x += step;
|
||||
}
|
||||
}
|
||||
y += step;
|
||||
}
|
||||
|
||||
ImGui::Dummy(ImVec2(step * 15.5f, step * 4.0f));
|
||||
draw_list->PopDrawFlag();
|
||||
draw_list->PopDrawFlag();
|
||||
|
||||
ImGui::Text("ImDrawList Vector Rendering Reference:");
|
||||
ImGui::TextLinkOpenURL("https://github.com/ocornut/imgui/wiki/Draw-List");
|
||||
|
||||
ImGui::Dummy(ImVec2((sz + spacing) * 13.2f, (sz + spacing) * 3.0f));
|
||||
ImGui::PopItemFlag();
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::EndTabItem();
|
||||
@ -10731,9 +10871,9 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
ImGui::Text("Blue shape is drawn first: appears in back");
|
||||
ImGui::Text("Red shape is drawn after: appears in front");
|
||||
ImVec2 p0 = ImGui::GetCursorScreenPos();
|
||||
draw_list->AddRectFilled(ImVec2(p0.x, p0.y), ImVec2(p0.x + 50, p0.y + 50), IM_COL32(0, 0, 255, 255)); // Blue
|
||||
draw_list->AddRectFilled(ImVec2(p0.x + 25, p0.y + 25), ImVec2(p0.x + 75, p0.y + 75), IM_COL32(255, 0, 0, 255)); // Red
|
||||
ImGui::Dummy(ImVec2(75, 75));
|
||||
draw_list->AddRectFilled({ p0.x, p0.y }, { p0.x + 50, p0.y + 50 }, IM_COL32(0, 0, 255, 255)); // Blue
|
||||
draw_list->AddRectFilled({ p0.x + 25, p0.y + 25 }, { p0.x + 75, p0.y + 75 }, IM_COL32(255, 0, 0, 255)); // Red
|
||||
ImGui::Dummy({ 75, 75 });
|
||||
}
|
||||
ImGui::Separator();
|
||||
{
|
||||
@ -10745,14 +10885,14 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
// You can create any number of channels. Tables API use 1 channel per column in order to better batch draw calls.
|
||||
draw_list->ChannelsSplit(2);
|
||||
draw_list->ChannelsSetCurrent(1);
|
||||
draw_list->AddRectFilled(ImVec2(p1.x, p1.y), ImVec2(p1.x + 50, p1.y + 50), IM_COL32(0, 0, 255, 255)); // Blue
|
||||
draw_list->AddRectFilled({ p1.x, p1.y }, { p1.x + 50, p1.y + 50 }, IM_COL32(0, 0, 255, 255)); // Blue
|
||||
draw_list->ChannelsSetCurrent(0);
|
||||
draw_list->AddRectFilled(ImVec2(p1.x + 25, p1.y + 25), ImVec2(p1.x + 75, p1.y + 75), IM_COL32(255, 0, 0, 255)); // Red
|
||||
draw_list->AddRectFilled({ p1.x + 25, p1.y + 25 }, { p1.x + 75, p1.y + 75 }, IM_COL32(255, 0, 0, 255)); // Red
|
||||
|
||||
// Flatten/reorder channels. Red shape is in channel 0 and it appears below the Blue shape in channel 1.
|
||||
// This works by copying draw indices only (vertices are not copied).
|
||||
draw_list->ChannelsMerge();
|
||||
ImGui::Dummy(ImVec2(75, 75));
|
||||
ImGui::Dummy({ 75, 75 });
|
||||
ImGui::Text("After reordering, contents of channel 0 appears below channel 1.");
|
||||
}
|
||||
ImGui::EndTabItem();
|
||||
|
||||
2338
imgui_draw.cpp
2338
imgui_draw.cpp
File diff suppressed because it is too large
Load Diff
@ -517,13 +517,23 @@ inline float ImSign(float x) { return (x < 0.0f) ? -1.0f : (x > 0.0f
|
||||
inline double ImSign(double x) { return (x < 0.0) ? -1.0 : (x > 0.0) ? 1.0 : 0.0; }
|
||||
#ifdef IMGUI_ENABLE_SSE
|
||||
inline float ImRsqrt(float x) { return _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(x))); }
|
||||
// Converge to more precise solution using single step of Newton-Raphson method, repeating increases precision
|
||||
inline float ImRsqrtPrecise(float x) { const float r = _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(x))); return r * (1.5f - x * 0.5f * r * r); }
|
||||
#else
|
||||
inline float ImRsqrt(float x) { return 1.0f / sqrtf(x); }
|
||||
inline float ImRsqrtPrecise(float x) { return 1.0f / sqrtf(x); }
|
||||
#endif
|
||||
inline double ImRsqrt(double x) { return 1.0 / sqrt(x); }
|
||||
inline double ImRsqrt(double x) { return 1.0 / sqrt(x); }
|
||||
#endif
|
||||
|
||||
// - ImMin/ImMax/ImClamp/ImLerp/ImSwap are used by widgets which support variety of types: signed/unsigned int/long long float/double
|
||||
// (Exceptionally using templates here but we could also redefine them for those types)
|
||||
// (Specialized version ensure that runtime-check pragmas/macros are applied with caller settings. Template version are less reliable in this regards)
|
||||
inline int ImMin(int lhs, int rhs) { return lhs < rhs ? lhs : rhs; }
|
||||
inline int ImMax(int lhs, int rhs) { return lhs >= rhs ? lhs : rhs; }
|
||||
inline int ImClamp(int v, int mn, int mx) { return (v < mn) ? mn : (v > mx) ? mx : v; }
|
||||
inline float ImMin(float lhs, float rhs) { return lhs < rhs ? lhs : rhs; }
|
||||
inline float ImMax(float lhs, float rhs) { return lhs >= rhs ? lhs : rhs; }
|
||||
inline float ImClamp(float v, float mn, float mx) { return (v < mn) ? mn : (v > mx) ? mx : v; }
|
||||
template<typename T> T ImMin(T lhs, T rhs) { return lhs < rhs ? lhs : rhs; }
|
||||
template<typename T> T ImMax(T lhs, T rhs) { return lhs >= rhs ? lhs : rhs; }
|
||||
template<typename T> T ImClamp(T v, T mn, T mx) { return (v < mn) ? mn : (v > mx) ? mx : v; }
|
||||
@ -559,6 +569,23 @@ inline float ImLinearRemapClamp(float s0, float s1, float d0, float d1, float x
|
||||
inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
|
||||
inline bool ImIsFloatAboveGuaranteedIntegerPrecision(float f) { return f <= -16777216 || f >= 16777216; }
|
||||
inline float ImExponentialMovingAverage(float avg, float sample, int n){ avg -= avg / (float)n; avg += sample / (float)n; return avg; }
|
||||
|
||||
inline bool ImIsTruncated(float x) { return (float)(int)x == x; }
|
||||
#ifdef IMGUI_ENABLE_SSE
|
||||
// Returns true if all parameters are whole numbers.
|
||||
inline bool ImIsTruncated4(float x, float y, float z, float w)
|
||||
{
|
||||
__m128 v = _mm_set_ps(x, y, z, w);
|
||||
__m128i i = _mm_cvttps_epi32(v);
|
||||
return _mm_movemask_ps(_mm_cmpeq_ps(v, _mm_cvtepi32_ps(i))) == 0xF;
|
||||
}
|
||||
#else
|
||||
inline bool ImIsTruncated4(float x, float y, float z, float w)
|
||||
{
|
||||
return (float)(int)x == x && (float)(int)y == y && (float)(int)z == z && (float)(int)w == w;
|
||||
}
|
||||
#endif
|
||||
|
||||
IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||
|
||||
// Helpers: Geometry
|
||||
@ -901,11 +928,28 @@ IMGUI_API ImGuiStoragePair* ImLowerBound(ImGuiStoragePair* in_begin, ImGuiStorag
|
||||
#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC_R(_N,_MAXERROR) ((_MAXERROR) / (1 - ImCos(IM_PI / ImMax((float)(_N), IM_PI))))
|
||||
#define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC_ERROR(_N,_RAD) ((1 - ImCos(IM_PI / ImMax((float)(_N), IM_PI))) / (_RAD))
|
||||
|
||||
// ImDrawList: Lookup table size for adaptive arc drawing, cover full circle.
|
||||
// ImDrawList: Lookup tables
|
||||
#ifndef IM_DRAWLIST_ARCFAST_TABLE_SIZE
|
||||
#define IM_DRAWLIST_ARCFAST_TABLE_SIZE 48 // Number of samples in lookup table.
|
||||
#define IM_DRAWLIST_ARCFAST_TABLE_SIZE (48) // Number of samples in adaptive arc drawing lookup table.
|
||||
#endif
|
||||
#define IM_DRAWLIST_ARCFAST_SAMPLE_MAX IM_DRAWLIST_ARCFAST_TABLE_SIZE // Sample index _PathArcToFastEx() for 360 angle.
|
||||
#define IM_DRAWLIST_ARCFAST_SAMPLE_MAX IM_DRAWLIST_ARCFAST_TABLE_SIZE // Sample index _PathArcToFastEx() for 360 angle.
|
||||
|
||||
#ifndef IM_DRAWLIST_TEX_LINES_WIDTH_MAX
|
||||
#define IM_DRAWLIST_TEX_LINES_WIDTH_MAX (32) // The maximum line width to bake anti-aliased textures for.
|
||||
#endif
|
||||
#ifndef IM_DRAWLIST_TEX_LINES_DETAILED_WIDTH
|
||||
#define IM_DRAWLIST_TEX_LINES_DETAILED_WIDTH (4) // Calculate detailed textures for width [1..IM_DRAWLIST_TEX_LINES_DETAILED_WIDTH]
|
||||
#endif
|
||||
#ifndef IM_DRAWLIST_TEX_LINES_SAMPLE_COUNT
|
||||
#define IM_DRAWLIST_TEX_LINES_SAMPLE_COUNT (4) // How many samples per integer thickness level.
|
||||
#endif
|
||||
#ifndef IM_DRAWLIST_TEX_CORNERS_ROUNDING_MAX
|
||||
#define IM_DRAWLIST_TEX_CORNERS_ROUNDING_MAX (16)
|
||||
#endif
|
||||
#ifndef IM_DRAWLIST_TEX_CORNERS_THICKNESS_MAX
|
||||
#define IM_DRAWLIST_TEX_CORNERS_THICKNESS_MAX (4) // 0: fill, 1-3: strokes thickness
|
||||
#endif
|
||||
#define IM_DRAWLIST_TEX_LINES_DETAILED_WIDTH_COUNT ((IM_DRAWLIST_TEX_LINES_DETAILED_WIDTH - 1) * IM_DRAWLIST_TEX_LINES_SAMPLE_COUNT + 1)
|
||||
|
||||
// Data shared between all ImDrawList instances
|
||||
// Conceptually this could have been called e.g. ImDrawListSharedContext
|
||||
@ -914,14 +958,15 @@ IMGUI_API ImGuiStoragePair* ImLowerBound(ImGuiStoragePair* in_begin, ImGuiStorag
|
||||
struct IMGUI_API ImDrawListSharedData
|
||||
{
|
||||
ImVec2 TexUvWhitePixel; // UV of white pixel in the atlas (== FontAtlas->TexUvWhitePixel)
|
||||
const ImVec4* TexUvLines; // UV of anti-aliased lines in the atlas (== FontAtlas->TexUvLines)
|
||||
const ImVec4* TexUvLines; // UV of anti-aliased lines in the atlas (== FontAtlas->Builder->TexUvLines)
|
||||
const ImVec4* TexUvCorners; // UV of rounded corner (== FontAtlas->Builder->TexUvCorners)
|
||||
ImFontAtlas* FontAtlas; // Current font atlas
|
||||
ImFont* Font; // Current font (used for simplified AddText overload)
|
||||
float FontSize; // Current font size (used for simplified AddText overload)
|
||||
float FontScale; // Current font scale (== FontSize / Font->FontSize)
|
||||
float CurveTessellationMaxError; // Tessellation tolerance when using PathBezierCurveTo()
|
||||
float CircleTessellationMaxError; // Number of circle segments to use per pixel of radius for AddCircle() etc
|
||||
ImDrawListFlags InitialFlags; // Initial flags at the beginning of the frame (it is possible to alter flags on a per-drawlist basis afterwards)
|
||||
ImDrawFlags InitialDrawFlags; // Initial flags at the beginning of the frame (it is possible to alter flags on a per-drawlist basis afterwards)
|
||||
ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen()
|
||||
ImVector<ImVec2> TempBuffer; // Temporary write buffer
|
||||
ImVector<ImDrawList*> DrawLists; // All draw lists associated to this ImDrawListSharedData
|
||||
@ -4335,8 +4380,14 @@ struct ImFontAtlasBuilder
|
||||
// Custom rectangle identifiers
|
||||
ImFontAtlasRectId PackIdMouseCursors; // White pixel + mouse cursors. Also happen to be fallback in case of packing failure.
|
||||
ImFontAtlasRectId PackIdLinesTexData;
|
||||
ImFontAtlasRectId PackIdLineFractTexData;
|
||||
ImFontAtlasRectId PackIdCornersTexData;
|
||||
|
||||
ImFontAtlasBuilder() { memset((void*)this, 0, sizeof(*this)); FrameCount = -1; RectsIndexFreeListStart = -1; PackIdMouseCursors = PackIdLinesTexData = -1; }
|
||||
// Cached UV coordinates
|
||||
ImVec4 TexUvLines[IM_DRAWLIST_TEX_LINES_WIDTH_MAX + 1 + IM_DRAWLIST_TEX_LINES_DETAILED_WIDTH_COUNT]; // UVs for baked anti-aliased lines (u0, u1, v, 1/thickness)
|
||||
ImVec4 TexUvCorners[IM_DRAWLIST_TEX_CORNERS_ROUNDING_MAX * IM_DRAWLIST_TEX_CORNERS_THICKNESS_MAX]; // UVs for baked anti-aliased corners (0= fill, 1> stroke thickness)
|
||||
|
||||
ImFontAtlasBuilder() { memset((void*)this, 0, sizeof(*this)); FrameCount = -1; RectsIndexFreeListStart = -1; PackIdMouseCursors = PackIdLinesTexData = PackIdLineFractTexData = PackIdCornersTexData = -1; }
|
||||
};
|
||||
|
||||
IMGUI_API void ImFontAtlasBuildInit(ImFontAtlas* atlas);
|
||||
|
||||
@ -2961,7 +2961,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
|
||||
// Draw inner border and resizing feedback
|
||||
ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent);
|
||||
const float border_size = TABLE_BORDER_SIZE;
|
||||
const float draw_y1 = ImMax(table->InnerRect.Min.y, (table->FreezeRowsCount >= 1 ? table->InnerRect.Min.y : table->WorkRect.Min.y) + table->AngledHeadersHeight) + ((table->Flags & ImGuiTableFlags_BordersOuterH) ? 1.0f : 0.0f);
|
||||
const float draw_y1 = ImMax(table->InnerRect.Min.y, (table->FreezeRowsCount >= 1 ? table->InnerRect.Min.y : table->WorkRect.Min.y) + table->AngledHeadersHeight) + ((table->Flags & ImGuiTableFlags_BordersOuterH) ? border_size : 0.0f);
|
||||
const float draw_y2_body = table->InnerRect.Max.y;
|
||||
const float draw_y2_head = table->IsUsingHeaders ? ImMin(table->InnerRect.Max.y, (table->FreezeRowsCount >= 1 ? table->InnerRect.Min.y : table->WorkRect.Min.y) + table_instance->LastTopHeadersRowHeight) : draw_y1;
|
||||
if (table->Flags & ImGuiTableFlags_BordersInnerV)
|
||||
@ -3018,7 +3018,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
|
||||
else if (table->Flags & ImGuiTableFlags_BordersOuterV)
|
||||
{
|
||||
inner_drawlist->AddLineV(outer_border.Min.x, outer_border.Min.y, outer_border.Max.y, outer_col, border_size);
|
||||
inner_drawlist->AddLineV(outer_border.Max.x, outer_border.Min.y, outer_border.Max.y, outer_col, border_size);
|
||||
inner_drawlist->AddLineV(outer_border.Max.x - border_size, outer_border.Min.y, outer_border.Max.y, outer_col, border_size);
|
||||
}
|
||||
else if (table->Flags & ImGuiTableFlags_BordersOuterH)
|
||||
{
|
||||
@ -3029,9 +3029,10 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
|
||||
if ((table->Flags & ImGuiTableFlags_BordersInnerH) && table->RowPosY2 < table->OuterRect.Max.y)
|
||||
{
|
||||
// Draw bottom-most row border between it is above outer border.
|
||||
const float h_inset = (table->Flags & ImGuiTableFlags_BordersOuterV) ? border_size : 0.0f;
|
||||
const float border_y = table->RowPosY2;
|
||||
if (border_y >= table->BgClipRect.Min.y && border_y < table->BgClipRect.Max.y)
|
||||
inner_drawlist->AddLineH(table->BorderX1, table->BorderX2, border_y, table->BorderColorLight, border_size);
|
||||
inner_drawlist->AddLineH(table->BorderX1 + h_inset, table->BorderX2 - h_inset, border_y, table->BorderColorLight, border_size);
|
||||
}
|
||||
|
||||
inner_drawlist->PopClipRect();
|
||||
@ -3624,7 +3625,8 @@ void ImGui::TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label
|
||||
if (pass == 1)
|
||||
{
|
||||
// Draw border
|
||||
draw_list->AddLine(bg_shape[0] - ImVec2(TABLE_BORDER_SIZE * 0.5f, 0.0f), bg_shape[3] - ImVec2(TABLE_BORDER_SIZE * 0.5f, 0.0f), TableGetColumnBorderCol(table, order_n, column_n), TABLE_BORDER_SIZE);
|
||||
const float border_size = TABLE_BORDER_SIZE;
|
||||
draw_list->AddLine(bg_shape[0] + ImVec2(border_size * 0.5f, 0.0f), bg_shape[3] + ImVec2(border_size * 0.5f, 0.0f), TableGetColumnBorderCol(table, order_n, column_n), border_size);
|
||||
}
|
||||
}
|
||||
PopClipRect();
|
||||
|
||||
@ -932,7 +932,7 @@ bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos)
|
||||
window->DrawList->AddRectFilled(bb.Min, bb.Max, bg_col);
|
||||
RenderNavCursor(bb, id, ImGuiNavRenderCursorFlags_Compact);
|
||||
const ImU32 cross_col = GetColorU32(ImGuiCol_Text);
|
||||
const ImVec2 cross_center = bb.GetCenter() - ImVec2(0.5f, 0.5f);
|
||||
const ImVec2 cross_center = bb.GetCenter();
|
||||
const float cross_extent = g.FontSize * 0.5f * 0.7071f - 1.0f;
|
||||
const float cross_thickness = 1.0f * (float)(int)g.Style._MainScale; // FIXME-DPI
|
||||
window->DrawList->AddLine(cross_center + ImVec2(+cross_extent, +cross_extent), cross_center + ImVec2(-cross_extent, -cross_extent), cross_col, cross_thickness);
|
||||
@ -1764,7 +1764,7 @@ void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end
|
||||
|
||||
const float sep1_x1 = pos.x;
|
||||
const float sep2_x2 = bb.Max.x;
|
||||
const float seps_y = ImTrunc((bb.Min.y + bb.Max.y) * 0.5f + 0.999f);
|
||||
float seps_y = ImTrunc((bb.Min.y + bb.Max.y) * 0.5f) + 1.0f;
|
||||
|
||||
const float label_avail_w = ImMax(0.0f, sep2_x2 - sep1_x1 - padding.x * 2.0f);
|
||||
const ImVec2 label_pos(pos.x + padding.x + ImMax(0.0f, (label_avail_w - label_size.x - extra_w) * style.SeparatorTextAlign.x), pos.y + text_baseline_y); // FIXME-ALIGN
|
||||
@ -1778,9 +1778,9 @@ void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end
|
||||
const float sep1_x2 = label_pos.x - style.ItemSpacing.x;
|
||||
const float sep2_x1 = label_pos.x + label_size.x + extra_w + style.ItemSpacing.x;
|
||||
if (sep1_x2 > sep1_x1 && separator_thickness > 0.0f)
|
||||
window->DrawList->AddLineH(sep1_x1, sep1_x2, seps_y, separator_col, separator_thickness);
|
||||
window->DrawList->AddLineH(sep1_x1, sep1_x2, seps_y, separator_col, separator_thickness, ImDrawFlags_StrokeCenterBiased);
|
||||
if (sep2_x2 > sep2_x1 && separator_thickness > 0.0f)
|
||||
window->DrawList->AddLineH(sep2_x1, sep2_x2, seps_y, separator_col, separator_thickness);
|
||||
window->DrawList->AddLineH(sep2_x1, sep2_x2, seps_y, separator_col, separator_thickness, ImDrawFlags_StrokeCenterBiased);
|
||||
if (g.LogEnabled)
|
||||
LogSetNextTextDecoration("---", NULL);
|
||||
RenderTextEllipsis(window->DrawList, label_pos, ImVec2(bb.Max.x, bb.Max.y + style.ItemSpacing.y), bb.Max.x, label, label_end, &label_size);
|
||||
@ -1790,7 +1790,7 @@ void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end
|
||||
if (g.LogEnabled)
|
||||
LogText("---");
|
||||
if (separator_thickness > 0.0f)
|
||||
window->DrawList->AddLineH(sep1_x1, sep2_x2, seps_y, separator_col, separator_thickness);
|
||||
window->DrawList->AddLineH(sep1_x1, sep2_x2, seps_y, separator_col, separator_thickness, ImDrawFlags_StrokeCenterBiased);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1987,12 +1987,12 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
|
||||
const float value_x2 = ImMax(bb.Min.x, bb.Max.x - arrow_size);
|
||||
RenderNavCursor(bb, id);
|
||||
if (!(flags & ImGuiComboFlags_NoPreview))
|
||||
window->DrawList->AddRectFilled(bb.Min, ImVec2(value_x2, bb.Max.y), frame_col, style.FrameRounding, (flags & ImGuiComboFlags_NoArrowButton) ? ImDrawFlags_RoundCornersAll : ImDrawFlags_RoundCornersLeft);
|
||||
window->DrawList->AddRectFilled(bb.Min, ImVec2(value_x2, bb.Max.y), frame_col, style.FrameRounding, (flags & ImGuiComboFlags_NoArrowButton) ? ImDrawFlags_RoundAll : ImDrawFlags_RoundLeft);
|
||||
if (!(flags & ImGuiComboFlags_NoArrowButton))
|
||||
{
|
||||
ImU32 bg_col = GetColorU32((popup_open || hovered) ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
|
||||
ImU32 text_col = GetColorU32(ImGuiCol_Text);
|
||||
window->DrawList->AddRectFilled(ImVec2(value_x2, bb.Min.y), bb.Max, bg_col, style.FrameRounding, (w <= arrow_size) ? ImDrawFlags_RoundCornersAll : ImDrawFlags_RoundCornersRight);
|
||||
window->DrawList->AddRectFilled(ImVec2(value_x2, bb.Min.y), bb.Max, bg_col, style.FrameRounding, (w <= arrow_size) ? ImDrawFlags_RoundAll : ImDrawFlags_RoundRight);
|
||||
if (value_x2 + arrow_size - style.FramePadding.x <= bb.Max.x)
|
||||
RenderArrow(window->DrawList, ImVec2(value_x2 + style.FramePadding.y, bb.Min.y + style.FramePadding.y), text_col, ImGuiDir_Down, 1.0f);
|
||||
}
|
||||
@ -5766,9 +5766,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
state->CursorAnim += io.DeltaTime;
|
||||
bool cursor_is_visible = (!g.IO.ConfigInputTextCursorBlink) || (state->CursorAnim <= 0.0f) || ImFmod(state->CursorAnim, 1.20f) <= 0.80f;
|
||||
ImVec2 cursor_screen_pos = ImTrunc(draw_pos + cursor_offset - draw_scroll);
|
||||
ImRect cursor_screen_rect(cursor_screen_pos.x, cursor_screen_pos.y - g.FontSize + 0.5f, cursor_screen_pos.x + 1.0f, cursor_screen_pos.y - 1.5f);
|
||||
ImRect cursor_screen_rect = ImRect(cursor_screen_pos.x, cursor_screen_pos.y - g.FontSize + 1.0f, cursor_screen_pos.x + 1.0f, cursor_screen_pos.y - 1.0f);
|
||||
if (cursor_is_visible && cursor_screen_rect.Overlaps(clip_rect))
|
||||
draw_window->DrawList->AddLineV(cursor_screen_rect.Min.x, cursor_screen_rect.Min.y, cursor_screen_rect.Max.y, GetColorU32(ImGuiCol_InputTextCursor), style.InputTextCursorSize);
|
||||
draw_window->DrawList->AddLineV(cursor_screen_rect.Min.x, cursor_screen_rect.Min.y, cursor_screen_rect.Max.y, GetColorU32(ImGuiCol_InputTextCursor), style.InputTextCursorSize, ImDrawFlags_StrokeInside);
|
||||
|
||||
// Notify OS of text input position for advanced IME (-1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety.)
|
||||
// This is required for some backends (SDL3) to start emitting character/text inputs.
|
||||
@ -6630,10 +6630,10 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
|
||||
{
|
||||
float mid_x = IM_ROUND((bb.Min.x + bb.Max.x) * 0.5f);
|
||||
if ((flags & ImGuiColorEditFlags_AlphaNoBg) == 0)
|
||||
RenderColorRectWithAlphaCheckerboard(window->DrawList, ImVec2(bb.Min.x + grid_step, bb.Min.y), bb.Max, ColorConvertFloat4ToU32(col_rgb), g.Style.Alpha, grid_step, ImVec2(-grid_step, 0.0f), rounding, ImDrawFlags_RoundCornersRight);
|
||||
RenderColorRectWithAlphaCheckerboard(window->DrawList, ImVec2(bb.Min.x + grid_step, bb.Min.y), bb.Max, ColorConvertFloat4ToU32(col_rgb), g.Style.Alpha, grid_step, ImVec2(-grid_step, 0.0f), rounding, ImDrawFlags_RoundRight);
|
||||
else
|
||||
window->DrawList->AddRectFilled(ImVec2(bb.Min.x + grid_step, bb.Min.y), bb.Max, GetColorU32(col_rgb), rounding, ImDrawFlags_RoundCornersRight);
|
||||
window->DrawList->AddRectFilled(bb.Min, ImVec2(mid_x, bb.Max.y), GetColorU32(col_rgb_without_alpha), rounding, ImDrawFlags_RoundCornersLeft);
|
||||
window->DrawList->AddRectFilled(ImVec2(bb.Min.x + grid_step, bb.Min.y), bb.Max, GetColorU32(col_rgb), rounding, ImDrawFlags_RoundRight);
|
||||
window->DrawList->AddRectFilled(bb.Min, ImVec2(mid_x, bb.Max.y), GetColorU32(col_rgb_without_alpha), rounding, ImDrawFlags_RoundLeft);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -7315,17 +7315,19 @@ void ImGui::TreeNodeDrawLineToChildNode(const ImVec2& target_pos)
|
||||
if ((window->DC.TreeHasStackDataDepthMask & TREE_NODE_GET_DEPTH_MASK(window->DC.TreeDepth - 1)) == 0)
|
||||
return;
|
||||
|
||||
// FIXME: Could this be simplified using new stroke flags?
|
||||
ImGuiTreeNodeStackData* parent_data = &g.TreeNodeStack.Data[g.TreeNodeStack.Size - 1];
|
||||
float x1 = ImTrunc(parent_data->DrawLinesX1);
|
||||
const float half_size = g.Style.TreeLinesSize * 0.5f;
|
||||
float x1 = ImTrunc(parent_data->DrawLinesX1 - half_size) + half_size; // Draw line centered at X1, but snap to pixels boundary.
|
||||
float x2 = ImTrunc(target_pos.x - g.Style.ItemInnerSpacing.x);
|
||||
float y = ImTrunc(target_pos.y);
|
||||
float y = ImTrunc(target_pos.y - half_size) + half_size;
|
||||
float rounding = (g.Style.TreeLinesRounding > 0.0f) ? ImMin(x2 - x1, g.Style.TreeLinesRounding) : 0.0f;
|
||||
parent_data->DrawLinesToNodesY2 = ImMax(parent_data->DrawLinesToNodesY2, y - rounding);
|
||||
if (x1 >= x2)
|
||||
return;
|
||||
if (rounding > 0.0f)
|
||||
if (rounding > 0.0f && rounding > half_size)
|
||||
{
|
||||
x1 += 0.5f + rounding;
|
||||
x1 += rounding;
|
||||
window->DrawList->PathArcToFast(ImVec2(x1, y - rounding), rounding, 6, 3);
|
||||
if (x1 < x2)
|
||||
window->DrawList->PathLineTo(ImVec2(x2, y));
|
||||
@ -7333,7 +7335,10 @@ void ImGui::TreeNodeDrawLineToChildNode(const ImVec2& target_pos)
|
||||
}
|
||||
else
|
||||
{
|
||||
window->DrawList->AddLineH(x1, x2, y, GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize);
|
||||
// We use AddLine() instead of AddLineH() as we provide coordinates for line center,
|
||||
// in order to make the code use same coordinates for both rounded and non-rounded version. (FIXME-OPT)
|
||||
x1 += half_size; // Avoid overdraw
|
||||
window->DrawList->AddLine(ImVec2(x1, y), ImVec2(x2, y), GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7356,10 +7361,12 @@ void ImGui::TreeNodeDrawLineToTreePop(const ImGuiTreeNodeStackData* data)
|
||||
y2 = ImMin(y2, window->ClipRect.Max.y);
|
||||
if (y2 <= y1)
|
||||
return;
|
||||
float x = ImTrunc(data->DrawLinesX1);
|
||||
float x = ImTrunc(data->DrawLinesX1 - g.Style.TreeLinesSize * 0.5f) + g.Style.TreeLinesSize * 0.5f; // Draw line centered at X1, but snap to pixels boundary.
|
||||
if (data->DrawLinesTableColumn != -1)
|
||||
TablePushColumnChannel(data->DrawLinesTableColumn);
|
||||
window->DrawList->AddLineV(x, y1, y2, GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize);
|
||||
|
||||
// We use AddLine() instead of AddLineV() as we provide coordinates for line center (FIXME-OPT)
|
||||
window->DrawList->AddLine(ImVec2(x, y1), ImVec2(x, y2), GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize);
|
||||
if (data->DrawLinesTableColumn != -1)
|
||||
TablePopColumnChannel();
|
||||
}
|
||||
@ -11055,8 +11062,8 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
if (tab_contents_visible && (tab_bar->Flags & ImGuiTabBarFlags_DrawSelectedOverline) && style.TabBarOverlineSize > 0.0f)
|
||||
{
|
||||
// Might be moved to TabItemBackground() ?
|
||||
ImVec2 tl = bb.GetTL() + ImVec2(0, 1.0f * g.CurrentDpiScale);
|
||||
ImVec2 tr = bb.GetTR() + ImVec2(0, 1.0f * g.CurrentDpiScale);
|
||||
ImVec2 tl = bb.GetTL() + ImVec2(0, style.TabBarOverlineSize * 0.5f);
|
||||
ImVec2 tr = bb.GetTR() + ImVec2(0, style.TabBarOverlineSize * 0.5f);
|
||||
ImU32 overline_col = GetColorU32(tab_bar_focused ? ImGuiCol_TabSelectedOverline : ImGuiCol_TabDimmedSelectedOverline);
|
||||
if (style.TabRounding > 0.0f)
|
||||
{
|
||||
@ -11067,7 +11074,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
}
|
||||
else
|
||||
{
|
||||
display_draw_list->AddLine(tl - ImVec2(0.5f, 0.5f), tr - ImVec2(0.5f, 0.5f), overline_col, style.TabBarOverlineSize);
|
||||
display_draw_list->AddLine(tl, tr, overline_col, style.TabBarOverlineSize);
|
||||
}
|
||||
}
|
||||
RenderNavCursor(bb, id);
|
||||
@ -11170,14 +11177,14 @@ void ImGui::TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabI
|
||||
const float rounding = ImMax(0.0f, ImMin((flags & ImGuiTabItemFlags_Button) ? g.Style.FrameRounding : g.Style.TabRounding, width * 0.5f - 1.0f));
|
||||
const float y1 = bb.Min.y + 1.0f; // Leave a bit of room in title bars.
|
||||
const float y2 = bb.Max.y - g.Style.TabBarBorderSize;
|
||||
draw_list->AddRectFilled(bb.Min, ImVec2(bb.Max.x, y2), col, rounding, ImDrawFlags_RoundCornersTop);
|
||||
draw_list->AddRectFilled(ImVec2(bb.Min.x, y1), ImVec2(bb.Max.x, y2), col, rounding, ImDrawFlags_RoundTop);
|
||||
if (g.Style.TabBorderSize > 0.0f)
|
||||
{
|
||||
draw_list->PathLineTo(ImVec2(bb.Min.x + 0.5f, y2));
|
||||
draw_list->PathArcToFast(ImVec2(bb.Min.x + rounding + 0.5f, y1 + rounding + 0.5f), rounding, 6, 9);
|
||||
draw_list->PathArcToFast(ImVec2(bb.Max.x - rounding - 0.5f, y1 + rounding + 0.5f), rounding, 9, 12);
|
||||
draw_list->PathLineTo(ImVec2(bb.Max.x - 0.5f, y2));
|
||||
draw_list->PathStroke(GetColorU32(ImGuiCol_Border), g.Style.TabBorderSize);
|
||||
draw_list->PathLineTo(ImVec2(bb.Min.x, y2));
|
||||
draw_list->PathArcToFast(ImVec2(bb.Min.x + rounding, y1 + rounding), rounding, 6, 9);
|
||||
draw_list->PathArcToFast(ImVec2(bb.Max.x - rounding, y1 + rounding), rounding, 9, 12);
|
||||
draw_list->PathLineTo(ImVec2(bb.Max.x, y2));
|
||||
draw_list->PathStroke(GetColorU32(ImGuiCol_Border), g.Style.TabBorderSize, ImDrawFlags_StrokeCenterBiased); // Use _StrokeInside?
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user